1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/plugins/modules/hwc_vpc_private_ip.py
Felix Fontein 3e0d84bdda
Use semantic markup (modules h-j) (#6677)
* Use semantic markup.

* Use 'ignore:' until a new version of antsibull-docs is released.

* 'ignore:' is no longer needed.

* E() now works better.
2023-06-15 15:47:00 +02:00

360 lines
9.6 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Huawei
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
###############################################################################
# Documentation
###############################################################################
DOCUMENTATION = '''
---
module: hwc_vpc_private_ip
description:
- vpc private ip management.
short_description: Creates a resource of Vpc/PrivateIP in Huawei Cloud
notes:
- If O(id) option is provided, it takes precedence over O(subnet_id), O(ip_address) for private ip selection.
- O(subnet_id), O(ip_address) are used for private ip selection. If more than one private ip with this options exists, execution is aborted.
- No parameter support updating. If one of option is changed, the module will create a new resource.
version_added: '0.2.0'
author: Huawei Inc. (@huaweicloud)
requirements:
- keystoneauth1 >= 3.6.0
attributes:
check_mode:
support: full
diff_mode:
support: none
options:
state:
description:
- Whether the given object should exist in Huawei Cloud.
type: str
choices: ['present', 'absent']
default: 'present'
subnet_id:
description:
- Specifies the ID of the subnet from which IP addresses are
assigned. Cannot be changed after creating the private ip.
type: str
required: true
ip_address:
description:
- Specifies the target IP address. The value can be an available IP
address in the subnet. If it is not specified, the system
automatically assigns an IP address. Cannot be changed after
creating the private ip.
type: str
required: false
extends_documentation_fragment:
- community.general.hwc
- community.general.attributes
'''
EXAMPLES = '''
# create a private ip
- name: Create vpc
hwc_network_vpc:
cidr: "192.168.100.0/24"
name: "ansible_network_vpc_test"
register: vpc
- name: Create subnet
hwc_vpc_subnet:
gateway_ip: "192.168.100.32"
name: "ansible_network_subnet_test"
dhcp_enable: true
vpc_id: "{{ vpc.id }}"
cidr: "192.168.100.0/26"
register: subnet
- name: Create a private ip
community.general.hwc_vpc_private_ip:
subnet_id: "{{ subnet.id }}"
ip_address: "192.168.100.33"
'''
RETURN = '''
subnet_id:
description:
- Specifies the ID of the subnet from which IP addresses are
assigned.
type: str
returned: success
ip_address:
description:
- Specifies the target IP address. The value can be an available IP
address in the subnet. If it is not specified, the system
automatically assigns an IP address.
type: str
returned: success
'''
from ansible_collections.community.general.plugins.module_utils.hwc_utils import (
Config, HwcClientException, HwcModule, are_different_dicts, build_path,
get_region, is_empty_value, navigate_value)
def build_module():
return HwcModule(
argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'],
type='str'),
subnet_id=dict(type='str', required=True),
ip_address=dict(type='str')
),
supports_check_mode=True,
)
def main():
"""Main function"""
module = build_module()
config = Config(module, "vpc")
try:
resource = None
if module.params['id']:
resource = True
else:
v = search_resource(config)
if len(v) > 1:
raise Exception("Found more than one resource(%s)" % ", ".join([
navigate_value(i, ["id"]) for i in v]))
if len(v) == 1:
resource = v[0]
module.params['id'] = navigate_value(resource, ["id"])
result = {}
changed = False
if module.params['state'] == 'present':
if resource is None:
if not module.check_mode:
create(config)
changed = True
current = read_resource(config, exclude_output=True)
expect = user_input_parameters(module)
if are_different_dicts(expect, current):
raise Exception(
"Cannot change option from (%s) to (%s)of an"
" existing resource.(%s)" % (current, expect, module.params.get('id')))
result = read_resource(config)
result['id'] = module.params.get('id')
else:
if resource:
if not module.check_mode:
delete(config)
changed = True
except Exception as ex:
module.fail_json(msg=str(ex))
else:
result['changed'] = changed
module.exit_json(**result)
def user_input_parameters(module):
return {
"ip_address": module.params.get("ip_address"),
"subnet_id": module.params.get("subnet_id"),
}
def create(config):
module = config.module
client = config.client(get_region(module), "vpc", "project")
opts = user_input_parameters(module)
params = build_create_parameters(opts)
r = send_create_request(module, params, client)
module.params['id'] = navigate_value(r, ["privateips", "id"],
{"privateips": 0})
def delete(config):
module = config.module
client = config.client(get_region(module), "vpc", "project")
send_delete_request(module, None, client)
def read_resource(config, exclude_output=False):
module = config.module
client = config.client(get_region(module), "vpc", "project")
res = {}
r = send_read_request(module, client)
res["read"] = fill_read_resp_body(r)
return update_properties(module, res, None, exclude_output)
def _build_query_link(opts):
query_link = "?marker={marker}&limit=10"
return query_link
def search_resource(config):
module = config.module
client = config.client(get_region(module), "vpc", "project")
opts = user_input_parameters(module)
identity_obj = _build_identity_object(opts)
query_link = _build_query_link(opts)
link = build_path(module, "subnets/{subnet_id}/privateips") + query_link
result = []
p = {'marker': ''}
while True:
url = link.format(**p)
r = send_list_request(module, client, url)
if not r:
break
for item in r:
item = fill_list_resp_body(item)
if not are_different_dicts(identity_obj, item):
result.append(item)
if len(result) > 1:
break
p['marker'] = r[-1].get('id')
return result
def build_create_parameters(opts):
params = dict()
v = navigate_value(opts, ["ip_address"], None)
if not is_empty_value(v):
params["ip_address"] = v
v = navigate_value(opts, ["subnet_id"], None)
if not is_empty_value(v):
params["subnet_id"] = v
if not params:
return params
params = {"privateips": [params]}
return params
def send_create_request(module, params, client):
url = "privateips"
try:
r = client.post(url, params)
except HwcClientException as ex:
msg = ("module(hwc_vpc_private_ip): error running "
"api(create), error: %s" % str(ex))
module.fail_json(msg=msg)
return r
def send_delete_request(module, params, client):
url = build_path(module, "privateips/{id}")
try:
r = client.delete(url, params)
except HwcClientException as ex:
msg = ("module(hwc_vpc_private_ip): error running "
"api(delete), error: %s" % str(ex))
module.fail_json(msg=msg)
return r
def send_read_request(module, client):
url = build_path(module, "privateips/{id}")
r = None
try:
r = client.get(url)
except HwcClientException as ex:
msg = ("module(hwc_vpc_private_ip): error running "
"api(read), error: %s" % str(ex))
module.fail_json(msg=msg)
return navigate_value(r, ["privateip"], None)
def fill_read_resp_body(body):
result = dict()
result["id"] = body.get("id")
result["ip_address"] = body.get("ip_address")
result["subnet_id"] = body.get("subnet_id")
return result
def update_properties(module, response, array_index, exclude_output=False):
r = user_input_parameters(module)
v = navigate_value(response, ["read", "ip_address"], array_index)
r["ip_address"] = v
v = navigate_value(response, ["read", "subnet_id"], array_index)
r["subnet_id"] = v
return r
def send_list_request(module, client, url):
r = None
try:
r = client.get(url)
except HwcClientException as ex:
msg = ("module(hwc_vpc_private_ip): error running "
"api(list), error: %s" % str(ex))
module.fail_json(msg=msg)
return navigate_value(r, ["privateips"], None)
def _build_identity_object(all_opts):
result = dict()
result["id"] = None
v = navigate_value(all_opts, ["ip_address"], None)
result["ip_address"] = v
v = navigate_value(all_opts, ["subnet_id"], None)
result["subnet_id"] = v
return result
def fill_list_resp_body(body):
result = dict()
result["id"] = body.get("id")
result["ip_address"] = body.get("ip_address")
result["subnet_id"] = body.get("subnet_id")
return result
if __name__ == '__main__':
main()