Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Commit

Permalink
This commit updates vcd_gateway_services modules to
Browse files Browse the repository at this point in the history
create/update/delete list of firewall rules through
a single ansible-play

Work towards: #147, #150, #157, #158

Signed-off-by: mukultaneja <[email protected]>
  • Loading branch information
mukultaneja committed Dec 17, 2020
1 parent c274254 commit 0153d9c
Showing 1 changed file with 145 additions and 120 deletions.
265 changes: 145 additions & 120 deletions modules/vcd_gateway_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@
type: str
service_params:
description:
- A dict type respective service parameters
- A list type respective service parameters
required: false
type: dict
type: list
state:
description:
- State of the edge gateway service
Expand Down Expand Up @@ -90,11 +90,11 @@
gateway: edge-gateway
service: firewall
service_params:
name: test_firewall
action: accept
type: User
enabled: True
logging_enabled: False
- name: test_firewall
action: accept
type: User
enabled: True
logging_enabled: False
state: present
'''
Expand All @@ -104,13 +104,13 @@
msg: success/failure message corresponding to edge gateway state
changed: true if resource has been changed else false
'''

import traceback
from pyvcloud.vcd.org import Org
from pyvcloud.vcd.vdc import VDC
from pyvcloud.vcd.gateway import Gateway
from pyvcloud.vcd.firewall_rule import FirewallRule
from ansible.module_utils.vcd import VcdAnsibleModule
from pyvcloud.vcd.exceptions import EntityNotFoundException
from pyvcloud.vcd.exceptions import EntityNotFoundException, BadRequestException


EDGE_SERVICES = ["firewall"]
Expand All @@ -122,7 +122,7 @@ def vcd_gateway_services_argument_spec():
return dict(
vdc=dict(type='str', required=True),
gateway=dict(type='str', required=True),
service_params=dict(type='dict', required=False),
service_params=dict(type='list', required=False),
service=dict(choices=EDGE_SERVICES, required=True),
state=dict(choices=EDGE_SERVICES_STATES, required=False),
operation=dict(choices=EDGE_SERVICES_OPERATIONS, required=False)
Expand All @@ -149,9 +149,11 @@ def manage_states(self):

def manage_operations(self):
operation = self.params.get("operation")

return self.apply_operation_on_service(operation)

def get_gateway(self, gateway_name):
def get_gateway(self):
gateway_name = self.params.get("gateway")
gateway = self.vdc.get_gateway(gateway_name)
if gateway is None:
msg = "Gateway {0} not found".format(gateway_name)
Expand All @@ -162,40 +164,32 @@ def get_gateway(self, gateway_name):

def add_service(self):
service = self.params.get("service")
gateway_name = self.params.get("gateway")
service_params = self.params.get("service_params")
gateway = self.get_gateway(gateway_name)
if service == "firewall":
service = FirewallService(gateway, service_params)
service = FirewallService(self.get_gateway(), service_params)

return service.manage_states(state="present")

def delete_service(self):
service = self.params.get("service")
gateway_name = self.params.get("gateway")
service_params = self.params.get("service_params")
gateway = self.get_gateway(gateway_name)
if service == "firewall":
service = FirewallService(gateway, service_params)
service = FirewallService(self.get_gateway(), service_params)

return service.manage_states(state="absent")

def update_service(self):
service = self.params.get("service")
gateway_name = self.params.get("gateway")
service_params = self.params.get("service_params")
gateway = self.get_gateway(gateway_name)
if service == "firewall":
service = FirewallService(gateway, service_params)
service = FirewallService(self.get_gateway(), service_params)

return service.manage_states(state="update")

def apply_operation_on_service(self, operation):
service = self.params.get("service")
gateway_name = self.params.get("gateway")
gateway = self.get_gateway(gateway_name)
if service == "firewall":
service = FirewallService(gateway)
service = FirewallService(self.get_gateway())

return service.manage_operations(operation=operation)

Expand All @@ -205,145 +199,176 @@ def __init__(self, gateway, service_params=None):
self.gateway = gateway
self.service_params = service_params

def _get_firewall_rules(self):
return self.gateway.get_firewall_rules_list()
def get_firewall_rules(self):
response = dict()
response['changed'] = False
response['msg'] = list()

fw_rules = self.gateway.get_firewall_rules_list()
for fw_rule in fw_rules:
response['msg'].append({
"name": str(fw_rule["name"]),
"id": int(fw_rule["ID"]),
"type": str(fw_rule["ruleType"])
})

return response

def _get_firewall_rule(self, firewall_rule_name):
firewall_rules = self._get_firewall_rules()
for firewall_rule in firewall_rules:
if firewall_rule["name"] == firewall_rule_name:
firewall_rule = FirewallRule(client=self.gateway.client,
gateway_name=self.gateway.name,
resource_id=firewall_rule["ID"])
return firewall_rule
def get_firewall_rule(self, fw_rule_name):
fw_rules = self.get_firewall_rules()['msg']
for fw_rule in fw_rules:
if fw_rule["name"] == fw_rule_name:
return FirewallRule(client=self.gateway.client,
gateway_name=self.gateway.name,
resource_id=fw_rule["id"])

msg = "Firewall rule {0} does not exists"
raise EntityNotFoundException(msg.format(firewall_rule_name))
raise EntityNotFoundException(msg.format(fw_rule_name))

def manage_states(self, state=None):
if state == "present":
return self._add()
return self.add()

if state == "update":
return self._update()
return self.update()

if state == "absent":
return self._delete()
return self.delete()

raise Exception("Please provide a valid state for the service")

def manage_operations(self, operation=None):
if operation == "list":
return self._list_firewall_rules()
return self.get_firewall_rules()

raise Exception("Please provide a valid operation for the service")

def _add(self):
name = self.service_params.get("name")
action = self.service_params.get("action", 'accept')
firewall_type = self.service_params.get("type", 'User')
enabled = self.service_params.get("enabled", True)
logging_enabled = self.service_params.get("logging_enabled", False)
response = dict()
response['changed'] = False

try:
self._get_firewall_rule(name)
except EntityNotFoundException:
self.gateway.add_firewall_rule(name=name, action=action,
type=firewall_type, enabled=enabled,
logging_enabled=logging_enabled)
msg = "A new firewall rule {0} has been added"
response['msg'] = msg.format(name)
response['changed'] = True
else:
msg = "A firewall rule {0} is already present"
response['warnings'] = msg.format(name)

return response

def _delete(self):
name = self.service_params.get("name")
response = dict()
response['changed'] = False

try:
firewall_rule = self._get_firewall_rule(name)
except EntityNotFoundException:
msg = "firewall rule {0} does not exists"
response['warnings'] = msg.format(name)
else:
firewall_rule.delete()
msg = "firewall rule {0} has been deleted"
response['msg'] = msg.format(name)
response['changed'] = True

return response

def _list_firewall_rules(self):
response = dict()
response['changed'] = False
response['msg'] = list()
for firewall_rule in self._get_firewall_rules():
res = {
"name": str(firewall_rule["name"]),
"id": int(firewall_rule["ID"]),
"type": str(firewall_rule["ruleType"])
}
response['msg'].append(res)
def _update_response(self, response, msg, warnings):
if response['msg']:
response['msg'] = msg.format(response['msg'])
if response['warnings']:
response['warnings'] = warnings.format(response['warnings'])

return response

def _prepare_service_values(self, services):
if services is not None:
for service in services:
for name, value in service.items():
value[value["source_port"]] = value["destination_port"]
del value["destination_port"], value["source_port"]
for name, value in service.copy().items():
service[name] = {
value["source_port"]: value["destination_port"]
}

return services

def _prepare_route_values(self, route_values):
response = list()
if route_values is not None:
for route, values in route_values.items():
response.append("{0}:{1}".format(values, route))
for route_value in route_values:
for route, value in route_value.items():
response.append("{0}:{1}".format(value[0], route))

return response

def _update(self):
name = self.service_params.get("name")
new_name = self.service_params.get("new_name", name)
services = self.service_params.get("services", None)
source_values = self.service_params.get("source_values", None)
destination_values = self.service_params.get(
"destination_values", None)
def add(self):
response = dict()
response['changed'] = False
response['warnings'] = list()
response['msg'] = list()
msg = 'Firewall rule(s) {0} have been created'
warnings = 'Firewall rule(s) {0} are already present'

for service_param in self.service_params:
name = service_param.get("name")
action = service_param.get("action") or 'accept'
firewall_type = service_param.get("type") or 'User'
enabled = service_param.get("enabled") or True
logging_enabled = service_param.get("logging_enabled") or False

try:
self.get_firewall_rule(name)
except EntityNotFoundException:
self.gateway.add_firewall_rule(name=name, action=action,
type=firewall_type,
enabled=enabled,
logging_enabled=logging_enabled)
try:
self.update([service_param])
except Exception:
self.delete([service_param])
raise Exception(traceback.format_exc())
else:
response['msg'].append(name)
response['changed'] = True
else:
response['warnings'].append(name)

return self._update_response(response, msg, warnings)

def update(self, service_params=None):
response = dict()
response['changed'] = False
response['msg'] = list()
response['warnings'] = list()
msg = 'Firewall rule(s) {0} have been updated'
warnings = 'Firewall rule(s) {0} are not present'

service_params = service_params or self.service_params
for service_param in service_params:
name = service_param.get("name")
new_name = service_param.get("new_name") or name
services = service_param.get("services") or None
source_values = service_param.get("source_values") or None
destination_values = service_param.get(
"destination_values") or None

try:
firewall_rule = self.get_firewall_rule(name)
services = self._prepare_service_values(services)
source_values = self._prepare_route_values(source_values)
destination_values = self._prepare_route_values(
destination_values)
firewall_rule.edit(source_values=source_values,
services=services,
destination_values=destination_values,
new_name=new_name)
response['msg'].append(name)
response['changed'] = True
except EntityNotFoundException:
response['warnings'].append(name)
except BadRequestException as ex:
raise Exception(ex)

return self._update_response(response, msg, warnings)

def delete(self, service_params=None):
response = dict()
response['changed'] = False
response['msg'] = list()
response['warnings'] = list()
msg = 'Firewall rule(s) {0} have been deleted'
warnings = 'Firewall rule(s) {0} are not present'

try:
firewall_rule = self._get_firewall_rule(name)
except EntityNotFoundException:
msg = "firewall rule {0} does not exists"
response['warnings'] = msg.format(name)
else:
services = self._prepare_service_values(services)
source_values = self._prepare_route_values(source_values)
destination_values = self._prepare_route_values(destination_values)
firewall_rule.edit(source_values=source_values, services=services,
destination_values=destination_values,
new_name=new_name)
msg = "A firewall rule {0} has been updated with {1}"
response['msg'] = msg.format(name, new_name)
response['changed'] = True
service_params = service_params or self.service_params
for service_param in service_params:
try:
name = service_param.get("name")
firewall_rule = self.get_firewall_rule(name)
except EntityNotFoundException:
response['warnings'].append(name)
else:
firewall_rule.delete()
response['msg'].append(name)
response['changed'] = True

return response
return self._update_response(response, msg, warnings)


def main():
argument_spec = vcd_gateway_services_argument_spec()
response = dict(msg=dict(type='str'))
module = EdgeServices(argument_spec=argument_spec, supports_check_mode=True)
module = EdgeServices(
argument_spec=argument_spec, supports_check_mode=True)

try:
if module.check_mode:
Expand Down

0 comments on commit 0153d9c

Please sign in to comment.