mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
389 lines
11 KiB
Python
389 lines
11 KiB
Python
|
#!/usr/bin/python
|
||
|
# -*- coding: utf-8 -*-
|
||
|
#
|
||
|
# Copyright (c) 2018, David Passante <@dpassante>
|
||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||
|
|
||
|
from __future__ import absolute_import, division, print_function
|
||
|
__metaclass__ = type
|
||
|
|
||
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||
|
'status': ['preview'],
|
||
|
'supported_by': 'community'}
|
||
|
|
||
|
|
||
|
DOCUMENTATION = '''
|
||
|
---
|
||
|
module: cs_vlan_ip_range
|
||
|
short_description: Manages VLAN IP ranges on Apache CloudStack based clouds.
|
||
|
description:
|
||
|
- Create and delete VLAN IP range.
|
||
|
author: David Passante (@dpassante)
|
||
|
options:
|
||
|
network:
|
||
|
description:
|
||
|
- The network name or id.
|
||
|
- Required if I(for_virtual_network) and I(physical_network) are not set.
|
||
|
type: str
|
||
|
physical_network:
|
||
|
description:
|
||
|
- The physical network name or id.
|
||
|
type: str
|
||
|
start_ip:
|
||
|
description:
|
||
|
- The beginning IPv4 address in the VLAN IP range.
|
||
|
- Only considered on create.
|
||
|
type: str
|
||
|
required: true
|
||
|
end_ip:
|
||
|
description:
|
||
|
- The ending IPv4 address in the VLAN IP range.
|
||
|
- If not specified, value of I(start_ip) is used.
|
||
|
- Only considered on create.
|
||
|
type: str
|
||
|
gateway:
|
||
|
description:
|
||
|
- The gateway of the VLAN IP range.
|
||
|
- Required if I(state=present).
|
||
|
type: str
|
||
|
netmask:
|
||
|
description:
|
||
|
- The netmask of the VLAN IP range.
|
||
|
- Required if I(state=present).
|
||
|
type: str
|
||
|
start_ipv6:
|
||
|
description:
|
||
|
- The beginning IPv6 address in the IPv6 network range.
|
||
|
- Only considered on create.
|
||
|
type: str
|
||
|
end_ipv6:
|
||
|
description:
|
||
|
- The ending IPv6 address in the IPv6 network range.
|
||
|
- If not specified, value of I(start_ipv6) is used.
|
||
|
- Only considered on create.
|
||
|
type: str
|
||
|
gateway_ipv6:
|
||
|
description:
|
||
|
- The gateway of the IPv6 network.
|
||
|
- Only considered on create.
|
||
|
type: str
|
||
|
cidr_ipv6:
|
||
|
description:
|
||
|
- The CIDR of IPv6 network, must be at least /64.
|
||
|
type: str
|
||
|
vlan:
|
||
|
description:
|
||
|
- The ID or VID of the network.
|
||
|
- If not specified, will be defaulted to the vlan of the network.
|
||
|
type: str
|
||
|
state:
|
||
|
description:
|
||
|
- State of the network ip range.
|
||
|
type: str
|
||
|
default: present
|
||
|
choices: [ present, absent ]
|
||
|
zone:
|
||
|
description:
|
||
|
- The Zone ID of the VLAN IP range.
|
||
|
- If not set, default zone is used.
|
||
|
type: str
|
||
|
domain:
|
||
|
description:
|
||
|
- Domain of the account owning the VLAN.
|
||
|
type: str
|
||
|
account:
|
||
|
description:
|
||
|
- Account who owns the VLAN.
|
||
|
- Mutually exclusive with I(project).
|
||
|
type: str
|
||
|
project:
|
||
|
description:
|
||
|
- Project who owns the VLAN.
|
||
|
- Mutually exclusive with I(account).
|
||
|
type: str
|
||
|
for_virtual_network:
|
||
|
description:
|
||
|
- C(yes) if VLAN is of Virtual type, C(no) if Direct.
|
||
|
- If set to C(yes) but neither I(physical_network) or I(network) is set CloudStack will try to add the
|
||
|
VLAN range to the Physical Network with a Public traffic type.
|
||
|
type: bool
|
||
|
default: no
|
||
|
extends_documentation_fragment:
|
||
|
- community.general.cloudstack
|
||
|
|
||
|
'''
|
||
|
|
||
|
EXAMPLES = '''
|
||
|
- name: create a VLAN IP range for network test
|
||
|
cs_vlan_ip_range:
|
||
|
network: test
|
||
|
vlan: 98
|
||
|
start_ip: 10.2.4.10
|
||
|
end_ip: 10.2.4.100
|
||
|
gateway: 10.2.4.1
|
||
|
netmask: 255.255.255.0
|
||
|
zone: zone-02
|
||
|
delegate_to: localhost
|
||
|
|
||
|
- name: remove a VLAN IP range for network test
|
||
|
cs_vlan_ip_range:
|
||
|
state: absent
|
||
|
network: test
|
||
|
start_ip: 10.2.4.10
|
||
|
end_ip: 10.2.4.100
|
||
|
zone: zone-02
|
||
|
delegate_to: localhost
|
||
|
'''
|
||
|
|
||
|
RETURN = '''
|
||
|
---
|
||
|
id:
|
||
|
description: UUID of the VLAN IP range.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
|
||
|
network:
|
||
|
description: The network of vlan range
|
||
|
returned: if available
|
||
|
type: str
|
||
|
sample: test
|
||
|
vlan:
|
||
|
description: The ID or VID of the VLAN.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: vlan://98
|
||
|
gateway:
|
||
|
description: IPv4 gateway.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: 10.2.4.1
|
||
|
netmask:
|
||
|
description: IPv4 netmask.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: 255.255.255.0
|
||
|
gateway_ipv6:
|
||
|
description: IPv6 gateway.
|
||
|
returned: if available
|
||
|
type: str
|
||
|
sample: 2001:db8::1
|
||
|
cidr_ipv6:
|
||
|
description: The CIDR of IPv6 network.
|
||
|
returned: if available
|
||
|
type: str
|
||
|
sample: 2001:db8::/64
|
||
|
zone:
|
||
|
description: Name of zone.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: zone-02
|
||
|
domain:
|
||
|
description: Domain name of the VLAN IP range.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: ROOT
|
||
|
account:
|
||
|
description: Account who owns the network.
|
||
|
returned: if available
|
||
|
type: str
|
||
|
sample: example account
|
||
|
project:
|
||
|
description: Project who owns the network.
|
||
|
returned: if available
|
||
|
type: str
|
||
|
sample: example project
|
||
|
for_systemvms:
|
||
|
description: Whether VLAN IP range is dedicated to system vms or not.
|
||
|
returned: success
|
||
|
type: bool
|
||
|
sample: false
|
||
|
for_virtual_network:
|
||
|
description: Whether VLAN IP range is of Virtual type or not.
|
||
|
returned: success
|
||
|
type: bool
|
||
|
sample: false
|
||
|
physical_network:
|
||
|
description: The physical network VLAN IP range belongs to.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
|
||
|
start_ip:
|
||
|
description: The start ip of the VLAN IP range.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: 10.2.4.10
|
||
|
end_ip:
|
||
|
description: The end ip of the VLAN IP range.
|
||
|
returned: success
|
||
|
type: str
|
||
|
sample: 10.2.4.100
|
||
|
start_ipv6:
|
||
|
description: The start ipv6 of the VLAN IP range.
|
||
|
returned: if available
|
||
|
type: str
|
||
|
sample: 2001:db8::10
|
||
|
end_ipv6:
|
||
|
description: The end ipv6 of the VLAN IP range.
|
||
|
returned: if available
|
||
|
type: str
|
||
|
sample: 2001:db8::50
|
||
|
'''
|
||
|
|
||
|
from ansible.module_utils.basic import AnsibleModule
|
||
|
from ansible_collections.community.general.plugins.module_utils.cloudstack import (
|
||
|
AnsibleCloudStack,
|
||
|
cs_argument_spec,
|
||
|
cs_required_together,
|
||
|
)
|
||
|
|
||
|
|
||
|
class AnsibleCloudStackVlanIpRange(AnsibleCloudStack):
|
||
|
|
||
|
def __init__(self, module):
|
||
|
super(AnsibleCloudStackVlanIpRange, self).__init__(module)
|
||
|
self.returns = {
|
||
|
'startip': 'start_ip',
|
||
|
'endip': 'end_ip',
|
||
|
'physicalnetworkid': 'physical_network',
|
||
|
'vlan': 'vlan',
|
||
|
'forsystemvms': 'for_systemvms',
|
||
|
'forvirtualnetwork': 'for_virtual_network',
|
||
|
'gateway': 'gateway',
|
||
|
'netmask': 'netmask',
|
||
|
'ip6gateway': 'gateway_ipv6',
|
||
|
'ip6cidr': 'cidr_ipv6',
|
||
|
'startipv6': 'start_ipv6',
|
||
|
'endipv6': 'end_ipv6',
|
||
|
}
|
||
|
self.ip_range = None
|
||
|
|
||
|
def get_vlan_ip_range(self):
|
||
|
if not self.ip_range:
|
||
|
args = {
|
||
|
'zoneid': self.get_zone(key='id'),
|
||
|
'projectid': self.get_project(key='id'),
|
||
|
'account': self.get_account(key='name'),
|
||
|
'domainid': self.get_domain(key='id'),
|
||
|
'networkid': self.get_network(key='id'),
|
||
|
}
|
||
|
|
||
|
res = self.query_api('listVlanIpRanges', **args)
|
||
|
if res:
|
||
|
ip_range_list = res['vlaniprange']
|
||
|
|
||
|
params = {
|
||
|
'startip': self.module.params.get('start_ip'),
|
||
|
'endip': self.get_or_fallback('end_ip', 'start_ip'),
|
||
|
}
|
||
|
|
||
|
for ipr in ip_range_list:
|
||
|
if params['startip'] == ipr['startip'] and params['endip'] == ipr['endip']:
|
||
|
self.ip_range = ipr
|
||
|
break
|
||
|
|
||
|
return self.ip_range
|
||
|
|
||
|
def present_vlan_ip_range(self):
|
||
|
ip_range = self.get_vlan_ip_range()
|
||
|
|
||
|
if not ip_range:
|
||
|
ip_range = self.create_vlan_ip_range()
|
||
|
|
||
|
return ip_range
|
||
|
|
||
|
def create_vlan_ip_range(self):
|
||
|
self.result['changed'] = True
|
||
|
|
||
|
vlan = self.module.params.get('vlan')
|
||
|
|
||
|
args = {
|
||
|
'zoneid': self.get_zone(key='id'),
|
||
|
'projectid': self.get_project(key='id'),
|
||
|
'account': self.get_account(key='name'),
|
||
|
'domainid': self.get_domain(key='id'),
|
||
|
'startip': self.module.params.get('start_ip'),
|
||
|
'endip': self.get_or_fallback('end_ip', 'start_ip'),
|
||
|
'netmask': self.module.params.get('netmask'),
|
||
|
'gateway': self.module.params.get('gateway'),
|
||
|
'startipv6': self.module.params.get('start_ipv6'),
|
||
|
'endipv6': self.get_or_fallback('end_ipv6', 'start_ipv6'),
|
||
|
'ip6gateway': self.module.params.get('gateway_ipv6'),
|
||
|
'ip6cidr': self.module.params.get('cidr_ipv6'),
|
||
|
'vlan': self.get_network(key='vlan') if not vlan else vlan,
|
||
|
'networkid': self.get_network(key='id'),
|
||
|
'forvirtualnetwork': self.module.params.get('for_virtual_network'),
|
||
|
}
|
||
|
if self.module.params.get('physical_network'):
|
||
|
args['physicalnetworkid'] = self.get_physical_network(key='id')
|
||
|
|
||
|
if not self.module.check_mode:
|
||
|
res = self.query_api('createVlanIpRange', **args)
|
||
|
|
||
|
self.ip_range = res['vlan']
|
||
|
|
||
|
return self.ip_range
|
||
|
|
||
|
def absent_vlan_ip_range(self):
|
||
|
ip_range = self.get_vlan_ip_range()
|
||
|
|
||
|
if ip_range:
|
||
|
self.result['changed'] = True
|
||
|
|
||
|
args = {
|
||
|
'id': ip_range['id'],
|
||
|
}
|
||
|
|
||
|
if not self.module.check_mode:
|
||
|
self.query_api('deleteVlanIpRange', **args)
|
||
|
|
||
|
return ip_range
|
||
|
|
||
|
|
||
|
def main():
|
||
|
argument_spec = cs_argument_spec()
|
||
|
argument_spec.update(dict(
|
||
|
network=dict(type='str'),
|
||
|
physical_network=dict(type='str'),
|
||
|
zone=dict(type='str'),
|
||
|
start_ip=dict(type='str', required=True),
|
||
|
end_ip=dict(type='str'),
|
||
|
gateway=dict(type='str'),
|
||
|
netmask=dict(type='str'),
|
||
|
start_ipv6=dict(type='str'),
|
||
|
end_ipv6=dict(type='str'),
|
||
|
gateway_ipv6=dict(type='str'),
|
||
|
cidr_ipv6=dict(type='str'),
|
||
|
vlan=dict(type='str'),
|
||
|
state=dict(choices=['present', 'absent'], default='present'),
|
||
|
domain=dict(type='str'),
|
||
|
account=dict(type='str'),
|
||
|
project=dict(type='str'),
|
||
|
for_virtual_network=dict(type='bool', default=False),
|
||
|
))
|
||
|
|
||
|
module = AnsibleModule(
|
||
|
argument_spec=argument_spec,
|
||
|
required_together=cs_required_together(),
|
||
|
mutually_exclusive=(
|
||
|
['account', 'project'],
|
||
|
),
|
||
|
required_if=(("state", "present", ("gateway", "netmask")),),
|
||
|
supports_check_mode=True,
|
||
|
)
|
||
|
|
||
|
acs_vlan_ip_range = AnsibleCloudStackVlanIpRange(module)
|
||
|
|
||
|
state = module.params.get('state')
|
||
|
if state == 'absent':
|
||
|
ipr = acs_vlan_ip_range.absent_vlan_ip_range()
|
||
|
|
||
|
else:
|
||
|
ipr = acs_vlan_ip_range.present_vlan_ip_range()
|
||
|
|
||
|
result = acs_vlan_ip_range.get_result(ipr)
|
||
|
module.exit_json(**result)
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|