Reverting recent commits back to initial PR and will move the new profitbricks_firewall_rule module and other recent changes to a new branch.

Revert "Added support for firewall rules, consolidated resource UUID retrieval methods for server and NIC modules, and set LAN type to int."

This reverts commit 464cbb89f2.
This commit is contained in:
Ethan Devenport 2016-08-29 19:45:57 +00:00 committed by Matt Clay
parent e1960d2488
commit f9e0830b44
3 changed files with 96 additions and 473 deletions

View file

@ -98,11 +98,6 @@ options:
- This will assign the machine to the public LAN. If no LAN exists with public Internet access it is created.
required: false
default: false
nic_name:
description:
- The name of the default NIC.
required: false
version_added: '2.2'
lan:
description:
- The ID of the LAN you wish to add the servers to.
@ -115,7 +110,7 @@ options:
default: null
subscription_password:
description:
- The ProfitBricks password. Overrides the PB_PASSWORD environement variable.
- THe ProfitBricks password. Overrides the PB_PASSWORD environement variable.
required: false
default: null
wait:
@ -200,15 +195,14 @@ EXAMPLES = '''
'''
import re
import uuid
import time
HAS_PB_SDK = True
try:
from profitbricks.client import (
ProfitBricksService, Volume, Server, Datacenter, NIC, LAN
)
from profitbricks.client import ProfitBricksService, Volume, Server, Datacenter, NIC, LAN
except ImportError:
HAS_PB_SDK = False
@ -216,6 +210,9 @@ LOCATIONS = ['us/las',
'de/fra',
'de/fkb']
uuid_match = re.compile(
'[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}', re.I)
def _wait_for_completion(profitbricks, promise, wait_timeout, msg):
if not promise: return
@ -226,9 +223,9 @@ def _wait_for_completion(profitbricks, promise, wait_timeout, msg):
request_id=promise['requestId'],
status=True)
if operation_result['metadata']['status'] == 'DONE':
if operation_result['metadata']['status'] == "DONE":
return
elif operation_result['metadata']['status'] == 'FAILED':
elif operation_result['metadata']['status'] == "FAILED":
raise Exception(
'Request failed to complete ' + msg + ' "' + str(
promise['requestId']) + '" to complete.')
@ -248,7 +245,6 @@ def _create_machine(module, profitbricks, datacenter, name):
image_password = module.params.get('image_password')
ssh_keys = module.params.get('ssh_keys')
bus = module.params.get('bus')
nic_name = module.params.get('nic_name')
lan = module.params.get('lan')
assign_public_ip = module.params.get('assign_public_ip')
subscription_user = module.params.get('subscription_user')
@ -288,7 +284,6 @@ def _create_machine(module, profitbricks, datacenter, name):
bus=bus)
n = NIC(
name=nic_name,
lan=int(lan)
)
@ -316,7 +311,6 @@ def _create_machine(module, profitbricks, datacenter, name):
except Exception as e:
module.fail_json(msg="failed to create the new server: %s" % str(e))
else:
server_response['nic'] = server_response['entities']['nics']['items'][0]
return server_response
@ -379,7 +373,7 @@ def create_virtual_machine(module, profitbricks):
# Locate UUID for datacenter if referenced by name.
datacenter_list = profitbricks.list_datacenters()
datacenter_id = _get_resource_id(datacenter_list, datacenter)
datacenter_id = _get_datacenter_id(datacenter_list, datacenter)
if datacenter_id:
datacenter_found = True
@ -415,13 +409,14 @@ def create_virtual_machine(module, profitbricks):
server_list = profitbricks.list_servers(datacenter_id)
for name in names:
# Skip server creation if the server already exists.
if _get_resource_id(server_list, name):
if _get_server_id(server_list, name):
continue
create_response = _create_machine(module, profitbricks, str(datacenter_id), name)
for nic in create_response['entities']['nics']['items']:
if lan == nic['properties']['lan']:
create_response.update({'public_ip': nic['properties']['ips'][0]})
nics = profitbricks.list_nics(datacenter_id, create_response['id'])
for n in nics['items']:
if lan == n['properties']['lan']:
create_response.update({'public_ip': n['properties']['ips'][0]})
virtual_machines.append(create_response)
@ -463,7 +458,7 @@ def remove_virtual_machine(module, profitbricks):
# Locate UUID for datacenter if referenced by name.
datacenter_list = profitbricks.list_datacenters()
datacenter_id = _get_resource_id(datacenter_list, datacenter)
datacenter_id = _get_datacenter_id(datacenter_list, datacenter)
if not datacenter_id:
module.fail_json(msg='Virtual data center \'%s\' not found.' % str(datacenter))
@ -471,7 +466,7 @@ def remove_virtual_machine(module, profitbricks):
server_list = profitbricks.list_servers(datacenter_id)
for instance in instance_ids:
# Locate UUID for server if referenced by name.
server_id = _get_resource_id(server_list, instance)
server_id = _get_server_id(server_list, instance)
if server_id:
# Remove the server's boot volume
if remove_boot_volume:
@ -522,7 +517,7 @@ def startstop_machine(module, profitbricks, state):
# Locate UUID for datacenter if referenced by name.
datacenter_list = profitbricks.list_datacenters()
datacenter_id = _get_resource_id(datacenter_list, datacenter)
datacenter_id = _get_datacenter_id(datacenter_list, datacenter)
if not datacenter_id:
module.fail_json(msg='Virtual data center \'%s\' not found.' % str(datacenter))
@ -530,7 +525,7 @@ def startstop_machine(module, profitbricks, state):
server_list = profitbricks.list_servers(datacenter_id)
for instance in instance_ids:
# Locate UUID of server if referenced by name.
server_id = _get_resource_id(server_list, instance)
server_id = _get_server_id(server_list, instance)
if server_id:
_startstop_machine(module, profitbricks, datacenter_id, server_id)
changed = True
@ -559,14 +554,23 @@ def startstop_machine(module, profitbricks, state):
return (changed)
def _get_resource_id(resources, identity):
def _get_datacenter_id(datacenters, identity):
"""
Fetch and return the UUID of a resource regardless of whether the name or
UUID is passed.
Fetch and return datacenter UUID by datacenter name if found.
"""
for resource in resources['items']:
if identity in (resource['properties']['name'], resource['id']):
return resource['id']
for datacenter in datacenters['items']:
if identity in (datacenter['properties']['name'], datacenter['id']):
return datacenter['id']
return None
def _get_server_id(servers, identity):
"""
Fetch and return server UUID by server name if found.
"""
for server in servers['items']:
if identity in (server['properties']['name'], server['id']):
return server['id']
return None
@ -584,8 +588,7 @@ def main():
image_password=dict(default=None),
ssh_keys=dict(type='list', default=[]),
bus=dict(default='VIRTIO'),
nic_name=dict(default=str(uuid.uuid4()).replace('-', '')[:10]),
lan=dict(type='int', default=1),
lan=dict(default=1),
count=dict(type='int', default=1),
auto_increment=dict(type='bool', default=True),
instance_ids=dict(type='list', default=[]),

View file

@ -1,399 +0,0 @@
#!/usr/bin/python
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
DOCUMENTATION = '''
---
module: profitbricks_firewall_rule
short_description: Create or remove a firewall rule.
description:
- This module allows you to create or remove a firewlal rule. This module has a dependency on profitbricks >= 1.0.0
version_added: "2.2"
options:
datacenter:
description:
- The datacenter name or UUID in which to operate.
required: true
server:
description:
- The server name or UUID.
required: true
nic:
description:
- The NIC name or UUID.
required: true
name:
description:
- The name or UUID of the firewall rule.
required: false
protocol:
description:
- The protocol for the firewall rule.
choices: [ "TCP", "UDP", "ICMP" ]
required: true
source_mac:
description:
- Only traffic originating from the respective MAC address is allowed. No value allows all source MAC addresses.
required: false
source_ip:
description:
- Only traffic originating from the respective IPv4 address is allowed. No value allows all source IPs.
required: false
target_ip:
description:
- In case the target NIC has multiple IP addresses, only traffic directed to the respective IP address of the NIC is allowed. No value allows all target IPs.
required: false
port_range_start:
description:
- Defines the start range of the allowed port (from 1 to 65534) if protocol TCP or UDP is chosen. Leave value empty to allow all ports.
required: false
port_range_end:
description:
- Defines the end range of the allowed port (from 1 to 65534) if the protocol TCP or UDP is chosen. Leave value empty to allow all ports.
required: false
icmp_type:
description:
- Defines the allowed type (from 0 to 254) if the protocol ICMP is chosen. No value allows all types.
required: false
icmp_code:
description:
- Defines the allowed code (from 0 to 254) if protocol ICMP is chosen. No value allows all codes.
required: false
subscription_user:
description:
- The ProfitBricks username. Overrides the PB_SUBSCRIPTION_ID environement variable.
required: false
subscription_password:
description:
- THe ProfitBricks password. Overrides the PB_PASSWORD environement variable.
required: false
wait:
description:
- wait for the operation to complete before returning
required: false
default: "yes"
choices: [ "yes", "no" ]
wait_timeout:
description:
- how long before wait gives up, in seconds
default: 600
state:
description:
- Indicate desired state of the resource
required: false
default: 'present'
choices: ["present", "absent"]
requirements: [ "profitbricks" ]
author: Ethan Devenport (ethand@stackpointcloud.com)
'''
EXAMPLES = '''
# Create a firewall rule
- name: Create SSH firewall rule
profitbricks_firewall_rule:
datacenter: Virtual Datacenter
server: node001
nic: 7341c2454f
name: Allow SSH
protocol: TCP
source_ip: 0.0.0.0
port_range_start: 22
port_range_end: 22
state: present
- name: Create ping firewall rule
profitbricks_firewall_rule:
datacenter: Virtual Datacenter
server: node001
nic: 7341c2454f
name: Allow Ping
protocol: ICMP
source_ip: 0.0.0.0
icmp_type: 8
icmp_code: 0
state: present
# Remove a firewall rule
- name: Remove public ping firewall rule
profitbricks_firewall_rule:
datacenter: Virtual Datacenter
server: node001
nic: aa6c261b9c
name: Allow Ping
state: absent
'''
RETURN = '''
---
id:
description: UUID of the firewall rule.
returned: success
type: string
sample: be60aa97-d9c7-4c22-bebe-f5df7d6b675d
name:
description: Name of the firwall rule.
returned: success
type: string
sample: Allow SSH
protocol:
description: Protocol of the firewall rule.
returned: success
type: string
sample: TCP
source_mac:
description: MAC address of the firewall rule.
returned: success
type: string
sample: 02:01:97:d7:ed:49
source_ip:
description: Source IP of the firewall rule.
returned: success
type: string
sample: tcp
target_ip:
description: Target IP of the firewal rule.
returned: success
type: string
sample: 10.0.0.1
port_range_start:
description: Start port of the firewall rule.
returned: success
type: int
sample: 80
port_range_end:
description: End port of the firewall rule.
returned: success
type: int
sample: 80
icmp_type:
description: ICMP type of the firewall rule.
returned: success
type: int
sample: 8
icmp_code:
description: ICMP code of the firewall rule.
returned: success
type: int
sample: 0
'''
# import uuid
import time
HAS_PB_SDK = True
try:
from profitbricks.client import ProfitBricksService, FirewallRule
except ImportError:
HAS_PB_SDK = False
def _wait_for_completion(profitbricks, promise, wait_timeout, msg):
if not promise: return
wait_timeout = time.time() + wait_timeout
while wait_timeout > time.time():
time.sleep(5)
operation_result = profitbricks.get_request(
request_id=promise['requestId'],
status=True)
if operation_result['metadata']['status'] == 'DONE':
return
elif operation_result['metadata']['status'] == 'FAILED':
raise Exception(
'Request failed to complete ' + msg + ' "' + str(
promise['requestId']) + '" to complete.')
raise Exception(
'Timed out waiting for async operation ' + msg + ' "' + str(
promise['requestId']
) + '" to complete.')
def create_firewall_rule(module, profitbricks):
"""
Creates a firewall rule.
module : AnsibleModule object
profitbricks: authenticated profitbricks object.
Returns:
True if the firewal rule creates, false otherwise
"""
datacenter = module.params.get('datacenter')
server = module.params.get('server')
nic = module.params.get('nic')
name = module.params.get('name')
protocol = module.params.get('protocol')
source_mac = module.params.get('source_mac')
source_ip = module.params.get('source_ip')
target_ip = module.params.get('target_ip')
port_range_start = module.params.get('port_range_start')
port_range_end = module.params.get('port_range_end')
icmp_type = module.params.get('icmp_type')
icmp_code = module.params.get('icmp_code')
wait = module.params.get('wait')
wait_timeout = module.params.get('wait_timeout')
# Locate UUID for virtual datacenter
datacenter_list = profitbricks.list_datacenters()
datacenter_id = _get_resource_id(datacenter_list, datacenter)
if not datacenter_id:
module.fail_json(msg='Virtual data center \'%s\' not found.' % str(datacenter))
# Locate UUID for server
server_list = profitbricks.list_servers(datacenter_id)
server_id = _get_resource_id(server_list, server)
# Locate UUID for NIC
nic_list = profitbricks.list_nics(datacenter_id, server_id)
nic_id = _get_resource_id(nic_list, nic)
try:
profitbricks.update_nic(datacenter_id, server_id, nic_id,
firewall_active=True)
except Exception as e:
module.fail_json(msg='Unable to activate the NIC firewall.' % str(e))
f = FirewallRule(
name=name,
protocol=protocol,
source_mac=source_mac,
source_ip=source_ip,
target_ip=target_ip,
port_range_start=port_range_start,
port_range_end=port_range_end,
icmp_type=icmp_type,
icmp_code=icmp_code
)
try:
firewall_rule_response = profitbricks.create_firewall_rule(
datacenter_id, server_id, nic_id, f
)
if wait:
_wait_for_completion(profitbricks, firewall_rule_response,
wait_timeout, "create_firewall_rule")
return firewall_rule_response
except Exception as e:
module.fail_json(msg="failed to create the firewall rule: %s" % str(e))
def delete_firewall_rule(module, profitbricks):
"""
Removes a firewall rule
module : AnsibleModule object
profitbricks: authenticated profitbricks object.
Returns:
True if the firewall rule was removed, false otherwise
"""
datacenter = module.params.get('datacenter')
server = module.params.get('server')
nic = module.params.get('nic')
name = module.params.get('name')
# Locate UUID for virtual datacenter
datacenter_list = profitbricks.list_datacenters()
datacenter_id = _get_resource_id(datacenter_list, datacenter)
# Locate UUID for server
server_list = profitbricks.list_servers(datacenter_id)
server_id = _get_resource_id(server_list, server)
# Locate UUID for NIC
nic_list = profitbricks.list_nics(datacenter_id, server_id)
nic_id = _get_resource_id(nic_list, nic)
# Locate UUID for firewall rule
firewall_rule_list = profitbricks.get_firewall_rules(datacenter_id, server_id, nic_id)
firewall_rule_id = _get_resource_id(firewall_rule_list, name)
try:
firewall_rule_response = profitbricks.delete_firewall_rule(
datacenter_id, server_id, nic_id, firewall_rule_id
)
return firewall_rule_response
except Exception as e:
module.fail_json(msg="failed to remove the firewall rule: %s" % str(e))
def _get_resource_id(resource_list, identity):
"""
Fetch and return the UUID of a resource regardless of whether the name or
UUID is passed.
"""
for resource in resource_list['items']:
if identity in (resource['properties']['name'], resource['id']):
return resource['id']
return None
def main():
module = AnsibleModule(
argument_spec=dict(
datacenter=dict(type='str', required=True),
server=dict(type='str', required=True),
nic=dict(type='str', required=True),
name=dict(type='str', required=True),
protocol=dict(type='str', required=False),
source_mac=dict(type='str', default=None),
source_ip=dict(type='str', default=None),
target_ip=dict(type='str', default=None),
port_range_start=dict(type='int', default=None),
port_range_end=dict(type='int', default=None),
icmp_type=dict(type='int', default=None),
icmp_code=dict(type='int', default=None),
subscription_user=dict(type='str', required=True),
subscription_password=dict(type='str', required=True),
wait=dict(type='bool', default=True),
wait_timeout=dict(type='int', default=600),
state=dict(default='present'),
)
)
if not HAS_PB_SDK:
module.fail_json(msg='profitbricks required for this module')
subscription_user = module.params.get('subscription_user')
subscription_password = module.params.get('subscription_password')
profitbricks = ProfitBricksService(
username=subscription_user,
password=subscription_password)
state = module.params.get('state')
if state == 'absent':
try:
(changed) = delete_firewall_rule(module, profitbricks)
module.exit_json(changed=changed)
except Exception as e:
module.fail_json(msg='failed to set firewall rule state: %s' % str(e))
elif state == 'present':
try:
(firewall_rule_dict) = create_firewall_rule(module, profitbricks)
module.exit_json(firewall_rules=firewall_rule_dict)
except Exception as e:
module.fail_json(msg='failed to set firewall rules state: %s' % str(e))
from ansible.module_utils.basic import *
main()

View file

@ -84,18 +84,23 @@ EXAMPLES = '''
name: 7341c2454f
wait_timeout: 500
state: absent
'''
import re
import uuid
import time
HAS_PB_SDK = True
try:
from profitbricks.client import ProfitBricksService, NIC, FirewallRule
from profitbricks.client import ProfitBricksService, NIC
except ImportError:
HAS_PB_SDK = False
uuid_match = re.compile(
'[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}', re.I)
def _wait_for_completion(profitbricks, promise, wait_timeout, msg):
if not promise: return
@ -106,9 +111,9 @@ def _wait_for_completion(profitbricks, promise, wait_timeout, msg):
request_id=promise['requestId'],
status=True)
if operation_result['metadata']['status'] == 'DONE':
if operation_result['metadata']['status'] == "DONE":
return
elif operation_result['metadata']['status'] == 'FAILED':
elif operation_result['metadata']['status'] == "FAILED":
raise Exception(
'Request failed to complete ' + msg + ' "' + str(
promise['requestId']) + '" to complete.')
@ -118,7 +123,6 @@ def _wait_for_completion(profitbricks, promise, wait_timeout, msg):
promise['requestId']
) + '" to complete.')
def create_nic(module, profitbricks):
"""
Creates a NIC.
@ -137,22 +141,28 @@ def create_nic(module, profitbricks):
wait_timeout = module.params.get('wait_timeout')
# Locate UUID for Datacenter
datacenter_list = profitbricks.list_datacenters()
datacenter_id = _get_resource_id(datacenter_list, datacenter)
if not datacenter_id:
module.fail_json(msg='Virtual data center \'%s\' not found.' % str(datacenter))
if not (uuid_match.match(datacenter)):
datacenter_list = profitbricks.list_datacenters()
for d in datacenter_list['items']:
dc = profitbricks.get_datacenter(d['id'])
if datacenter == dc['properties']['name']:
datacenter = d['id']
break
# Locate UUID for Server
server_list = profitbricks.list_servers(datacenter_id)
server_id = _get_resource_id(server_list, server)
n = NIC(
name=name,
lan=lan
)
if not (uuid_match.match(server)):
server_list = profitbricks.list_servers(datacenter)
for s in server_list['items']:
if server == s['properties']['name']:
server = s['id']
break
try:
nic_response = profitbricks.create_nic(datacenter_id, server_id, n)
n = NIC(
name=name,
lan=lan
)
nic_response = profitbricks.create_nic(datacenter, server, n)
if wait:
_wait_for_completion(profitbricks, nic_response,
@ -163,7 +173,6 @@ def create_nic(module, profitbricks):
except Exception as e:
module.fail_json(msg="failed to create the NIC: %s" % str(e))
def delete_nic(module, profitbricks):
"""
Removes a NIC
@ -179,44 +188,53 @@ def delete_nic(module, profitbricks):
name = module.params.get('name')
# Locate UUID for Datacenter
datacenter_list = profitbricks.list_datacenters()
datacenter_id = _get_resource_id(datacenter_list, datacenter)
if not datacenter_id:
module.fail_json(msg='Virtual data center \'%s\' not found.' % str(datacenter))
if not (uuid_match.match(datacenter)):
datacenter_list = profitbricks.list_datacenters()
for d in datacenter_list['items']:
dc = profitbricks.get_datacenter(d['id'])
if datacenter == dc['properties']['name']:
datacenter = d['id']
break
# Locate UUID for Server
server_list = profitbricks.list_servers(datacenter_id)
server_id = _get_resource_id(server_list, server)
server_found = False
if not (uuid_match.match(server)):
server_list = profitbricks.list_servers(datacenter)
for s in server_list['items']:
if server == s['properties']['name']:
server_found = True
server = s['id']
break
if not server_found:
return False
# Locate UUID for NIC
nic_list = profitbricks.list_nics(datacenter_id, server_id)
nic_id = _get_resource_id(nic_list, name)
nic_found = False
if not (uuid_match.match(name)):
nic_list = profitbricks.list_nics(datacenter, server)
for n in nic_list['items']:
if name == n['properties']['name']:
nic_found = True
name = n['id']
break
if not nic_found:
return False
try:
nic_response = profitbricks.delete_nic(datacenter_id, server_id, nic_id)
nic_response = profitbricks.delete_nic(datacenter, server, name)
return nic_response
except Exception as e:
module.fail_json(msg="failed to remove the NIC: %s" % str(e))
def _get_resource_id(resource_list, identity):
"""
Fetch and return the UUID of a resource regardless of whether the name or
UUID is passed.
"""
for resource in resource_list['items']:
if identity in (resource['properties']['name'], resource['id']):
return resource['id']
return None
def main():
module = AnsibleModule(
argument_spec=dict(
datacenter=dict(),
server=dict(),
name=dict(default=str(uuid.uuid4()).replace('-', '')[:10]),
lan=dict(type='int'),
name=dict(default=str(uuid.uuid4()).replace('-','')[:10]),
lan=dict(),
subscription_user=dict(),
subscription_password=dict(),
wait=dict(type='bool', default=True),
@ -237,6 +255,7 @@ def main():
if not module.params.get('server'):
module.fail_json(msg='server parameter is required')
subscription_user = module.params.get('subscription_user')
subscription_password = module.params.get('subscription_password')
@ -262,10 +281,10 @@ def main():
try:
(nic_dict) = create_nic(module, profitbricks)
module.exit_json(nic=nic_dict)
module.exit_json(nics=nic_dict)
except Exception as e:
module.fail_json(msg='failed to set nic state: %s' % str(e))
from ansible.module_utils.basic import *
main()
main()