community.general/plugins/modules/oneandone_private_network.py
Felix Fontein 5589bcb659
[stable-6] Add attributes to oneandone, ovh, and rackspace modules ()
Add attributes to oneandone, ovh, and rackspace modules ()

Add attributes to oneandone, ovh, and rackspace modules.

(cherry picked from commit 6bd131f2fb)
2023-02-24 11:03:19 +01:00

455 lines
14 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) Ansible Project
# 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 = '''
---
module: oneandone_private_network
short_description: Configure 1&1 private networking
description:
- Create, remove, reconfigure, update a private network.
This module has a dependency on 1and1 >= 1.0.
extends_documentation_fragment:
- community.general.attributes
attributes:
check_mode:
support: full
diff_mode:
support: none
options:
state:
description:
- Define a network's state to create, remove, or update.
type: str
required: false
default: 'present'
choices: [ "present", "absent", "update" ]
auth_token:
description:
- Authenticating API token provided by 1&1.
type: str
private_network:
description:
- The identifier (id or name) of the network used with update state.
type: str
api_url:
description:
- Custom API URL. Overrides the
ONEANDONE_API_URL environment variable.
type: str
required: false
name:
description:
- Private network name used with present state. Used as identifier (id or name) when used with absent state.
type: str
description:
description:
- Set a description for the network.
type: str
datacenter:
description:
- The identifier of the datacenter where the private network will be created
type: str
choices: [US, ES, DE, GB]
network_address:
description:
- Set a private network space, i.e. 192.168.1.0
type: str
subnet_mask:
description:
- Set the netmask for the private network, i.e. 255.255.255.0
type: str
add_members:
description:
- List of server identifiers (name or id) to be added to the private network.
type: list
elements: str
default: []
remove_members:
description:
- List of server identifiers (name or id) to be removed from the private network.
type: list
elements: str
default: []
wait:
description:
- wait for the instance to be in state 'running' before returning
required: false
default: true
type: bool
wait_timeout:
description:
- how long before wait gives up, in seconds
type: int
default: 600
wait_interval:
description:
- Defines the number of seconds to wait when using the _wait_for methods
type: int
default: 5
requirements:
- "1and1"
- "python >= 2.6"
author:
- Amel Ajdinovic (@aajdinov)
- Ethan Devenport (@edevenport)
'''
EXAMPLES = '''
- name: Create a private network
community.general.oneandone_private_network:
auth_token: oneandone_private_api_key
name: backup_network
description: Testing creation of a private network with ansible
network_address: 70.35.193.100
subnet_mask: 255.0.0.0
datacenter: US
- name: Destroy a private network
community.general.oneandone_private_network:
auth_token: oneandone_private_api_key
state: absent
name: backup_network
- name: Modify the private network
community.general.oneandone_private_network:
auth_token: oneandone_private_api_key
state: update
private_network: backup_network
network_address: 192.168.2.0
subnet_mask: 255.255.255.0
- name: Add members to the private network
community.general.oneandone_private_network:
auth_token: oneandone_private_api_key
state: update
private_network: backup_network
add_members:
- server identifier (id or name)
- name: Remove members from the private network
community.general.oneandone_private_network:
auth_token: oneandone_private_api_key
state: update
private_network: backup_network
remove_members:
- server identifier (id or name)
'''
RETURN = '''
private_network:
description: Information about the private network.
type: dict
sample: '{"name": "backup_network", "id": "55726DEDA20C99CF6F2AF8F18CAC9963"}'
returned: always
'''
import os
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.oneandone import (
get_private_network,
get_server,
get_datacenter,
OneAndOneResources,
wait_for_resource_creation_completion,
wait_for_resource_deletion_completion
)
HAS_ONEANDONE_SDK = True
try:
import oneandone.client
except ImportError:
HAS_ONEANDONE_SDK = False
DATACENTERS = ['US', 'ES', 'DE', 'GB']
def _check_mode(module, result):
if module.check_mode:
module.exit_json(
changed=result
)
def _add_servers(module, oneandone_conn, name, members):
try:
private_network_id = get_private_network(oneandone_conn, name)
if module.check_mode:
if private_network_id and members:
return True
return False
network = oneandone_conn.attach_private_network_servers(
private_network_id=private_network_id,
server_ids=members)
return network
except Exception as e:
module.fail_json(msg=str(e))
def _remove_member(module, oneandone_conn, name, member_id):
try:
private_network_id = get_private_network(oneandone_conn, name)
if module.check_mode:
if private_network_id:
network_member = oneandone_conn.get_private_network_server(
private_network_id=private_network_id,
server_id=member_id)
if network_member:
return True
return False
network = oneandone_conn.remove_private_network_server(
private_network_id=name,
server_id=member_id)
return network
except Exception as ex:
module.fail_json(msg=str(ex))
def create_network(module, oneandone_conn):
"""
Create new private network
module : AnsibleModule object
oneandone_conn: authenticated oneandone object
Returns a dictionary containing a 'changed' attribute indicating whether
any network was added.
"""
name = module.params.get('name')
description = module.params.get('description')
network_address = module.params.get('network_address')
subnet_mask = module.params.get('subnet_mask')
datacenter = module.params.get('datacenter')
wait = module.params.get('wait')
wait_timeout = module.params.get('wait_timeout')
wait_interval = module.params.get('wait_interval')
if datacenter is not None:
datacenter_id = get_datacenter(oneandone_conn, datacenter)
if datacenter_id is None:
module.fail_json(
msg='datacenter %s not found.' % datacenter)
try:
_check_mode(module, True)
network = oneandone_conn.create_private_network(
private_network=oneandone.client.PrivateNetwork(
name=name,
description=description,
network_address=network_address,
subnet_mask=subnet_mask,
datacenter_id=datacenter_id
))
if wait:
wait_for_resource_creation_completion(
oneandone_conn,
OneAndOneResources.private_network,
network['id'],
wait_timeout,
wait_interval)
network = get_private_network(oneandone_conn,
network['id'],
True)
changed = True if network else False
_check_mode(module, False)
return (changed, network)
except Exception as e:
module.fail_json(msg=str(e))
def update_network(module, oneandone_conn):
"""
Modifies a private network.
module : AnsibleModule object
oneandone_conn: authenticated oneandone object
"""
try:
_private_network_id = module.params.get('private_network')
_name = module.params.get('name')
_description = module.params.get('description')
_network_address = module.params.get('network_address')
_subnet_mask = module.params.get('subnet_mask')
_add_members = module.params.get('add_members')
_remove_members = module.params.get('remove_members')
changed = False
private_network = get_private_network(oneandone_conn,
_private_network_id,
True)
if private_network is None:
_check_mode(module, False)
if _name or _description or _network_address or _subnet_mask:
_check_mode(module, True)
private_network = oneandone_conn.modify_private_network(
private_network_id=private_network['id'],
name=_name,
description=_description,
network_address=_network_address,
subnet_mask=_subnet_mask)
changed = True
if _add_members:
instances = []
for member in _add_members:
instance_id = get_server(oneandone_conn, member)
instance_obj = oneandone.client.AttachServer(server_id=instance_id)
instances.extend([instance_obj])
private_network = _add_servers(module, oneandone_conn, private_network['id'], instances)
_check_mode(module, private_network)
changed = True
if _remove_members:
chk_changed = False
for member in _remove_members:
instance = get_server(oneandone_conn, member, True)
if module.check_mode:
chk_changed |= _remove_member(module,
oneandone_conn,
private_network['id'],
instance['id'])
_check_mode(module, instance and chk_changed)
_remove_member(module,
oneandone_conn,
private_network['id'],
instance['id'])
private_network = get_private_network(oneandone_conn,
private_network['id'],
True)
changed = True
return (changed, private_network)
except Exception as ex:
module.fail_json(msg=str(ex))
def remove_network(module, oneandone_conn):
"""
Removes a private network.
module : AnsibleModule object
oneandone_conn: authenticated oneandone object.
"""
try:
pn_id = module.params.get('name')
wait_timeout = module.params.get('wait_timeout')
wait_interval = module.params.get('wait_interval')
private_network_id = get_private_network(oneandone_conn, pn_id)
if module.check_mode:
if private_network_id is None:
_check_mode(module, False)
_check_mode(module, True)
private_network = oneandone_conn.delete_private_network(private_network_id)
wait_for_resource_deletion_completion(oneandone_conn,
OneAndOneResources.private_network,
private_network['id'],
wait_timeout,
wait_interval)
changed = True if private_network else False
return (changed, {
'id': private_network['id'],
'name': private_network['name']
})
except Exception as e:
module.fail_json(msg=str(e))
def main():
module = AnsibleModule(
argument_spec=dict(
auth_token=dict(
type='str', no_log=True,
default=os.environ.get('ONEANDONE_AUTH_TOKEN')),
api_url=dict(
type='str',
default=os.environ.get('ONEANDONE_API_URL')),
private_network=dict(type='str'),
name=dict(type='str'),
description=dict(type='str'),
network_address=dict(type='str'),
subnet_mask=dict(type='str'),
add_members=dict(type='list', elements="str", default=[]),
remove_members=dict(type='list', elements="str", default=[]),
datacenter=dict(
choices=DATACENTERS),
wait=dict(type='bool', default=True),
wait_timeout=dict(type='int', default=600),
wait_interval=dict(type='int', default=5),
state=dict(type='str', default='present', choices=['present', 'absent', 'update']),
),
supports_check_mode=True
)
if not HAS_ONEANDONE_SDK:
module.fail_json(msg='1and1 required for this module')
if not module.params.get('auth_token'):
module.fail_json(
msg='auth_token parameter is required.')
if not module.params.get('api_url'):
oneandone_conn = oneandone.client.OneAndOneService(
api_token=module.params.get('auth_token'))
else:
oneandone_conn = oneandone.client.OneAndOneService(
api_token=module.params.get('auth_token'), api_url=module.params.get('api_url'))
state = module.params.get('state')
if state == 'absent':
if not module.params.get('name'):
module.fail_json(
msg="'name' parameter is required for deleting a network.")
try:
(changed, private_network) = remove_network(module, oneandone_conn)
except Exception as e:
module.fail_json(msg=str(e))
elif state == 'update':
if not module.params.get('private_network'):
module.fail_json(
msg="'private_network' parameter is required for updating a network.")
try:
(changed, private_network) = update_network(module, oneandone_conn)
except Exception as e:
module.fail_json(msg=str(e))
elif state == 'present':
if not module.params.get('name'):
module.fail_json(
msg="'name' parameter is required for new networks.")
try:
(changed, private_network) = create_network(module, oneandone_conn)
except Exception as e:
module.fail_json(msg=str(e))
module.exit_json(changed=changed, private_network=private_network)
if __name__ == '__main__':
main()