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

Commit

Permalink
Updating vcd_gateway_services module to manage NAT Rules
Browse files Browse the repository at this point in the history
This commit has following changes,
1. Updates `vcd_gateway_services` module to manage NAT rules
2. Updates `vcd_gateway_services` playbook to have plays to
manage NAT Rules and Firewall gateway services

Work towards: #147, #150

Signed-off-by: mukultaneja <[email protected]>
  • Loading branch information
mukultaneja committed Dec 22, 2020
1 parent 0153d9c commit e0e6269
Show file tree
Hide file tree
Showing 4 changed files with 486 additions and 197 deletions.
175 changes: 175 additions & 0 deletions module_utils/gateway_firewall_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@

import traceback
from pyvcloud.vcd.firewall_rule import FirewallRule
from pyvcloud.vcd.exceptions import BadRequestException
from pyvcloud.vcd.exceptions import EntityNotFoundException


class FirewallService():
def __init__(self, gateway, service_params=None):
self.gateway = gateway
self.service_params = service_params

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, 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(fw_rule_name))

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

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

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

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

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

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

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.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_value in route_values:
for route, value in route_value.items():
response.append("{0}:{1}".format(value[0], route))

return response

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'

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 self._update_response(response, msg, warnings)
138 changes: 138 additions & 0 deletions module_utils/gateway_nat_rule_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@

from pyvcloud.vcd.nat_rule import NatRule
from pyvcloud.vcd.utils import build_network_url_from_gateway_url
from pyvcloud.vcd.network_url_constants import NAT_RULE_URL_TEMPLATE


class NatRuleService():
def __init__(self, gateway, service_params=None):
self.gateway = gateway
self.service_params = service_params

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

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

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

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

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

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

def get_nat_rule_href(self, nat_rule_id):
network_url = build_network_url_from_gateway_url(self.gateway.href)
nat_href = network_url + NAT_RULE_URL_TEMPLATE

return nat_href.format(nat_rule_id)

def get_nat_rules(self):
response = dict()
response['changed'] = False
response['msg'] = list()

nat_rules_resource = self.gateway.get_nat_rules()
if (hasattr(nat_rules_resource.natRules, 'natRule')):
for nat_rule in nat_rules_resource.natRules.natRule:
nat_rule_info = {}
nat_rule_info['ID'] = int(nat_rule.ruleId)
nat_rule_info['Action'] = str(nat_rule.action)
nat_rule_info['Enabled'] = str(nat_rule.enabled)
nat_rule_info['href'] = self.get_nat_rule_href(
nat_rule_info['ID'])
response['msg'].append(nat_rule_info)

return response

def add(self):
response = dict()
response['changed'] = False

for service_param in self.service_params:
action = service_param.get("action")
original_address = service_param.get("original_address")
translated_address = service_param.get("translated_address")
description = service_param.get("description", '')
protocol = service_param.get("protocol", 'any')
original_port = service_param.get("original_port", 'any')
translated_port = service_param.get("translated_port", 'any')
access_type = service_param.get("access_type", 'User')
icmp_type = service_param.get("icmp_type", 'any')
enabled = service_param.get("enabled", True)
logging_enabled = service_param.get("logging_enabled", False)
vnic = service_param.get("vnic", 0)

self.gateway.add_nat_rule(action, original_address,
translated_address, description,
protocol, original_port,
translated_port, access_type,
icmp_type, logging_enabled,
enabled, vnic)
response['msg'] = 'Nat rule(s) are added'
response['changed'] = True

return response

def update(self):
response = dict()
response['changed'] = False
response['msg'] = list()

for service_param in self.service_params:
nat_rule_id = service_param.get("nat_rule_id")
original_address = service_param.get("original_address")
translated_address = service_param.get("translated_address")
description = service_param.get("description", '')
protocol = service_param.get("protocol", 'any')
original_port = service_param.get("original_port", 'any')
translated_port = service_param.get("translated_port", 'any')
icmp_type = service_param.get("icmp_type", 'any')
enabled = service_param.get("enabled", True)
logging_enabled = service_param.get("logging_enabled", False)
vnic = service_param.get("vnic", 0)
nat_rule_obj = NatRule(client=self.gateway.client,
gateway_name=self.gateway.name,
rule_id=nat_rule_id)
nat_rule_obj.href = self.get_nat_rule_href(nat_rule_id)
nat_rule_obj.update_nat_rule(
original_address,
translated_address,
description,
protocol,
original_port,
translated_port,
icmp_type,
logging_enabled,
enabled,
vnic
)
response['msg'].append(nat_rule_id)
response['msg'] = 'Nat rule(s) {0} are updated'.format(response['msg'])
response['changed'] = True

return response

def delete(self):
response = dict()
response['changed'] = False
response['msg'] = list()

for service_param in self.service_params:
nat_rule_id = service_param.get("nat_rule_id")
nat_rule_obj = NatRule(client=self.gateway.client,
gateway_name=self.gateway.name,
rule_id=nat_rule_id)
nat_rule_obj.href = self.get_nat_rule_href(nat_rule_id)
nat_rule_obj.delete_nat_rule()
response['msg'].append(nat_rule_id)
response['msg'] = 'Nat rule(s) {0} are deleted'.format(response['msg'])
response['changed'] = True

return response
Loading

0 comments on commit e0e6269

Please sign in to comment.