|
|
|
@ -95,6 +95,22 @@ options:
|
|
|
|
|
- Default tags such as C(VirtualNetwork), C(AzureLoadBalancer) and C(Internet) can also be used.
|
|
|
|
|
- It can accept string type or a list of string type.
|
|
|
|
|
default: "*"
|
|
|
|
|
source_application_security_groups:
|
|
|
|
|
description:
|
|
|
|
|
- List of the source application security groups.
|
|
|
|
|
- It could be list of resource id.
|
|
|
|
|
- It could be list of names in same resource group.
|
|
|
|
|
- It could be list of dict containing resource_group and name.
|
|
|
|
|
- It is mutually exclusive with C(source_address_prefix) and C(source_address_prefixes).
|
|
|
|
|
type: list
|
|
|
|
|
destination_application_security_groups:
|
|
|
|
|
description:
|
|
|
|
|
- List of the destination application security groups.
|
|
|
|
|
- It could be list of resource id.
|
|
|
|
|
- It could be list of names in same resource group.
|
|
|
|
|
- It could be list of dict containing resource_group and name.
|
|
|
|
|
- It is mutually exclusive with C(destination_address_prefix) and C(destination_address_prefixes).
|
|
|
|
|
type: list
|
|
|
|
|
access:
|
|
|
|
|
description:
|
|
|
|
|
- Whether or not to allow the traffic flow.
|
|
|
|
@ -341,6 +357,7 @@ state:
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
from msrestazure.azure_exceptions import CloudError
|
|
|
|
|
from msrestazure.tools import is_valid_resource_id
|
|
|
|
|
from azure.mgmt.network import NetworkManagementClient
|
|
|
|
|
except ImportError:
|
|
|
|
|
# This is handled in azure_rm_common
|
|
|
|
@ -373,6 +390,12 @@ def validate_rule(self, rule, rule_type=None):
|
|
|
|
|
check_plural('source_port_range', 'source_port_ranges')
|
|
|
|
|
check_plural('destination_port_range', 'destination_port_ranges')
|
|
|
|
|
|
|
|
|
|
# when source(destination)_application_security_groups set, remove the default value * of source(destination)_address_prefix
|
|
|
|
|
if rule.get('source_application_security_groups') and rule.get('source_address_prefix') == '*':
|
|
|
|
|
rule['source_address_prefix'] = None
|
|
|
|
|
if rule.get('destination_application_security_groups') and rule.get('destination_address_prefix') == '*':
|
|
|
|
|
rule['destination_address_prefix'] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compare_rules_change(old_list, new_list, purge_list):
|
|
|
|
|
old_list = old_list or []
|
|
|
|
@ -425,6 +448,10 @@ def compare_rules(old_rule, rule):
|
|
|
|
|
changed = True
|
|
|
|
|
if set(rule.get('destination_port_ranges') or []) != set(old_rule.get('destination_port_ranges') or []):
|
|
|
|
|
changed = True
|
|
|
|
|
if set(rule.get('source_application_security_groups') or []) != set(old_rule.get('source_application_security_groups') or []):
|
|
|
|
|
changed = True
|
|
|
|
|
if set(rule.get('destination_application_security_groups') or []) != set(old_rule.get('destination_application_security_groups') or []):
|
|
|
|
|
changed = True
|
|
|
|
|
return changed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -446,6 +473,12 @@ def create_rule_instance(self, rule):
|
|
|
|
|
destination_address_prefixes=rule.get('destination_address_prefixes', None),
|
|
|
|
|
source_port_ranges=rule.get('source_port_ranges', None),
|
|
|
|
|
destination_port_ranges=rule.get('destination_port_ranges', None),
|
|
|
|
|
source_application_security_groups=[
|
|
|
|
|
self.nsg_models.ApplicationSecurityGroup(id=p)
|
|
|
|
|
for p in rule.get('source_application_security_groups')] if rule.get('source_application_security_groups') else None,
|
|
|
|
|
destination_application_security_groups=[
|
|
|
|
|
self.nsg_models.ApplicationSecurityGroup(id=p)
|
|
|
|
|
for p in rule.get('destination_application_security_groups')] if rule.get('destination_application_security_groups') else None,
|
|
|
|
|
access=rule.get('access', None),
|
|
|
|
|
priority=rule.get('priority', None),
|
|
|
|
|
direction=rule.get('direction', None),
|
|
|
|
@ -475,6 +508,9 @@ def create_rule_dict_from_obj(rule):
|
|
|
|
|
destination_port_ranges=rule.destination_port_ranges,
|
|
|
|
|
source_address_prefixes=rule.source_address_prefixes,
|
|
|
|
|
destination_address_prefixes=rule.destination_address_prefixes,
|
|
|
|
|
source_application_security_groups=[p.id for p in rule.source_application_security_groups] if rule.source_application_security_groups else None,
|
|
|
|
|
destination_application_security_groups=[
|
|
|
|
|
p.id for p in rule.destination_application_security_groups] if rule.destination_application_security_groups else None,
|
|
|
|
|
access=rule.access,
|
|
|
|
|
priority=rule.priority,
|
|
|
|
|
direction=rule.direction,
|
|
|
|
@ -522,6 +558,8 @@ rule_spec = dict(
|
|
|
|
|
destination_port_range=dict(type='raw', default='*'),
|
|
|
|
|
source_address_prefix=dict(type='raw', default='*'),
|
|
|
|
|
destination_address_prefix=dict(type='raw', default='*'),
|
|
|
|
|
source_application_security_groups=dict(type='list', elements='raw'),
|
|
|
|
|
destination_application_security_groups=dict(type='list', elements='raw'),
|
|
|
|
|
access=dict(type='str', choices=['Allow', 'Deny'], default='Allow'),
|
|
|
|
|
priority=dict(type='int', required=True),
|
|
|
|
|
direction=dict(type='str', choices=['Inbound', 'Outbound'], default='Inbound')
|
|
|
|
@ -559,8 +597,14 @@ class AzureRMSecurityGroup(AzureRMModuleBase):
|
|
|
|
|
state=dict()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
mutually_exclusive = [["source_application_security_group", "source_address_prefix"],
|
|
|
|
|
["source_application_security_group", "source_address_prefixes"],
|
|
|
|
|
["destination_application_security_group", "destination_address_prefix"],
|
|
|
|
|
["destination_application_security_group", "destination_address_prefixes"]]
|
|
|
|
|
|
|
|
|
|
super(AzureRMSecurityGroup, self).__init__(self.module_arg_spec,
|
|
|
|
|
supports_check_mode=True)
|
|
|
|
|
supports_check_mode=True,
|
|
|
|
|
mutually_exclusive=mutually_exclusive)
|
|
|
|
|
|
|
|
|
|
def exec_module(self, **kwargs):
|
|
|
|
|
# tighten up poll interval for security groups; default 30s is an eternity
|
|
|
|
@ -585,6 +629,7 @@ class AzureRMSecurityGroup(AzureRMModuleBase):
|
|
|
|
|
validate_rule(self, rule)
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
self.fail("Error validating rule {0} - {1}".format(rule, str(exc)))
|
|
|
|
|
self.convert_asg_to_id(rule)
|
|
|
|
|
|
|
|
|
|
if self.default_rules:
|
|
|
|
|
for rule in self.default_rules:
|
|
|
|
@ -592,6 +637,7 @@ class AzureRMSecurityGroup(AzureRMModuleBase):
|
|
|
|
|
validate_rule(self, rule, 'default')
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
self.fail("Error validating default rule {0} - {1}".format(rule, str(exc)))
|
|
|
|
|
self.convert_asg_to_id(rule)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
nsg = self.network_client.network_security_groups.get(self.resource_group, self.name)
|
|
|
|
@ -698,6 +744,24 @@ class AzureRMSecurityGroup(AzureRMModuleBase):
|
|
|
|
|
raise Exception("Error deleting security group {0} - {1}".format(self.name, str(exc)))
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
def convert_asg_to_id(self, rule):
|
|
|
|
|
def convert_to_id(rule, key):
|
|
|
|
|
if rule.get(key):
|
|
|
|
|
ids = []
|
|
|
|
|
for p in rule.get(key):
|
|
|
|
|
if isinstance(p, dict):
|
|
|
|
|
ids.append("/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Network/applicationSecurityGroups/{2}".format(
|
|
|
|
|
self.subscription_id, p.get('resource_group'), p.get('name')))
|
|
|
|
|
elif isinstance(p, str):
|
|
|
|
|
if is_valid_resource_id(p):
|
|
|
|
|
ids.append(p)
|
|
|
|
|
else:
|
|
|
|
|
ids.append("/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Network/applicationSecurityGroups/{2}".format(
|
|
|
|
|
self.subscription_id, self.resource_group, p))
|
|
|
|
|
rule[key] = ids
|
|
|
|
|
convert_to_id(rule, 'source_application_security_groups')
|
|
|
|
|
convert_to_id(rule, 'destination_application_security_groups')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
AzureRMSecurityGroup()
|
|
|
|
|