def create_netsec_group_port_allow(self, secgroup_name, protocol, source_address_prefix, destination_address_prefix, access, direction, resource_group=None, **kwargs): resource_group = resource_group or self.resource_group self.logger.info( "Attempting to Create New Azure Security Group " "Rule '%s'.", secgroup_name) parameters = NetworkSecurityGroup(location=self.region) parameters.security_rules = [ SecurityRule(protocol, source_address_prefix, destination_address_prefix, access, direction, **kwargs) ] nsg = self.network_client.network_security_groups operation = nsg.create_or_update(resource_group, secgroup_name, parameters) operation.wait() self.logger.info("Network Security Group Rule is created.") return operation.status()
def test_delete_security_rules(self): # Arrange self.network_security_group = MagicMock() network_client = MagicMock() private_ip_address = Mock() resource_group_name = "group_name" vm_name = "vm_name" security_group = NetworkSecurityGroup() security_group.name = "security_group_name" security_rule = Mock() security_rule.name = "rule_name" security_rule.destination_address_prefix = private_ip_address security_rules = [security_rule] security_group.security_rules = security_rules self.security_group_service.get_network_security_group = MagicMock() self.security_group_service.get_network_security_group.return_value = security_group self.network_service.get_private_ip = Mock( return_value=private_ip_address) contex_enter_mock = Mock() locker = Mock() locker.__enter__ = contex_enter_mock locker.__exit__ = Mock() # Act self.security_group_service.delete_security_rules( network_client, resource_group_name, vm_name, locker, Mock()) # Verify network_client.security_rules.delete.assert_called_once_with( resource_group_name=resource_group_name, network_security_group_name=security_group.name, security_rule_name=security_rule.name) contex_enter_mock.assert_called_once()
def _ensure_network_security_group(cli_ctx, resource_group_name, ase_name, location, subnet_id, force): subnet_id_parts = parse_resource_id(subnet_id) vnet_resource_group = subnet_id_parts['resource_group'] vnet_name = subnet_id_parts['name'] subnet_name = subnet_id_parts['resource_name'] ase_nsg_name = ase_name + '-NSG' network_client = _get_network_client_factory(cli_ctx) subnet_obj = network_client.subnets.get(vnet_resource_group, vnet_name, subnet_name) subnet_address_prefix = subnet_obj.address_prefix if subnet_obj.network_security_group is None or force: nsg_list = network_client.network_security_groups.list( resource_group_name) nsg_found = False for nsg in list(nsg_list): if nsg.name.lower() == ase_nsg_name.lower(): nsg_found = True break if not nsg_found: logger.info('Ensure Network Security Group...') ase_nsg = NetworkSecurityGroup(location=location) poller = network_client.network_security_groups.begin_create_or_update( resource_group_name, ase_nsg_name, ase_nsg) LongRunningOperation(cli_ctx)(poller) _create_asev2_nsg_rules(cli_ctx, resource_group_name, ase_nsg_name, subnet_address_prefix) nsg = network_client.network_security_groups.get( resource_group_name, ase_nsg_name) if not subnet_obj.network_security_group or subnet_obj.network_security_group.id != nsg.id: logger.info('Associate Network Security Group with Subnet...') subnet_obj.network_security_group = NetworkSecurityGroup(id=nsg.id) poller = network_client.subnets.begin_create_or_update( vnet_resource_group, vnet_name, subnet_name, subnet_parameters=subnet_obj) LongRunningOperation(cli_ctx)(poller) else: nsg_id_parts = parse_resource_id(subnet_obj.network_security_group.id) nsg_name = nsg_id_parts['name'] if nsg_name.lower() != ase_nsg_name.lower(): err_msg = 'Network Security Group already exists.' rec_msg = 'Use --ignore-network-security-group to use existing NSG ' \ 'or --force-network-security-group to replace existing NSG' validation_error = ValidationError(err_msg, rec_msg) raise validation_error
def create_nsg(self): print("Creating NSG") params_create = NetworkSecurityGroup( location=self.location, security_rules=[ SecurityRule( name='Port_29876-29877', access=SecurityRuleAccess.allow, description='Batch Node Management', destination_address_prefix="*", destination_port_range='29876-29877', direction=SecurityRuleDirection.inbound, priority=1040, protocol=SecurityRuleProtocol.tcp, source_address_prefix='BatchNodeManagement', source_port_range="*", ), ], ) result_create_NSG = self.network_client.network_security_groups.create_or_update( self.rg_name, self.nsg_name, params_create, ) return result_create_NSG.result()
def create_ssh_security_group(self, location, resource_group_name, network_security_group_name): ssh_rule = SecurityRule( name='default-allow-ssh', protocol='Tcp', source_port_range='*', destination_port_range=22, direction='Inbound', source_address_prefix='*', destination_address_prefix='*', access='Allow', priority=1000, ) security_group = NetworkSecurityGroup(location=location, security_rules=[ssh_rule]) try: return self.network_client.network_security_groups.create_or_update( resource_group_name, network_security_group_name, security_group, ) except ClientException as exc: raise AzureBackendError(exc)
def get(self, resource_group_name: str, network_security_group_name: str) -> NetworkSecurityGroup: try: with open(self.path / resource_group_name / f"nsg-{network_security_group_name}.json", "r", encoding="utf-8") as file: return NetworkSecurityGroup.deserialize(json.load(file)) except FileNotFoundError: raise ResourceNotFoundError("Network security group not found") from None
def update_subnet(resource_group_name, virtual_network_name, subnet_name, address_prefix=None, network_security_group=None): '''update existing virtual sub network :param str address_prefix: New address prefix in CIDR format, for example 10.0.0.0/24. :param str network_security_group: attach with existing network security group, both name or id are accepted. Use empty string "" to detach it. ''' ncf = _network_client_factory() subnet = ncf.subnets.get(resource_group_name, virtual_network_name, subnet_name) #pylint: disable=redefined-variable-type if address_prefix: subnet.address_prefix = address_prefix if network_security_group: subnet.network_security_group = NetworkSecurityGroup( network_security_group) elif network_security_group == '': #clear it subnet.network_security_group = None return ncf.subnets.create_or_update(resource_group_name, virtual_network_name, subnet_name, subnet)
def set_nic(resource_group_name, network_interface_name, network_security_group=None, enable_ip_forwarding=None, internal_dns_name_label=None): ncf = _network_client_factory() nic = ncf.network_interfaces.get(resource_group_name, network_interface_name) if enable_ip_forwarding is not None: nic.enable_ip_forwarding = enable_ip_forwarding == 'true' if network_security_group == '': nic.network_security_group = None elif network_security_group is not None: nic.network_security_group = NetworkSecurityGroup( network_security_group) if internal_dns_name_label == '': nic.dns_settings.internal_dns_name_label = None elif internal_dns_name_label is not None: nic.dns_settings.internal_dns_name_label = internal_dns_name_label return ncf.network_interfaces.create_or_update(resource_group_name, network_interface_name, nic)
def add_vm_firewall(self, fw): ''' :param fw: :return: None This method adds the security group to VM instance. In Azure, security group added to Network interface. Azure supports to add only one security group to network interface, we are adding the provided security group if not associated any security group to NIC else replacing the existing security group. ''' fw = (self._provider.security.vm_firewalls.get(fw) if isinstance( fw, str) else fw) nic = next(self._nics) if not nic.network_security_group: nic.network_security_group = NetworkSecurityGroup() nic.network_security_group.id = fw.resource_id else: existing_fw = self._provider.security.\ vm_firewalls.get(nic.network_security_group.id) new_fw = self._provider.security.vm_firewalls.\ create('{0}-{1}'.format(fw.name, existing_fw.name), 'Merged security groups {0} and {1}'. format(fw.name, existing_fw.name)) new_fw.add_rule(src_dest_fw=fw) new_fw.add_rule(src_dest_fw=existing_fw) nic.network_security_group.id = new_fw.resource_id self._provider.azure_client.update_nic(nic.id, nic)
def update_or_create(rules): """A local function to create and return a NetworkSecurityGroup instance.""" if rules is None: rules = [] rules = ['Allow:Inbound:Tcp:22:SSH'] + rules # We always open SSH port priority = { 'Inbound': 300, 'Outbond': 300, } security_rules = [] for rule in rules: direction = rule.split(':')[1] rule = f'{priority[direction]}:{rule}' security_rules.append(create_security_rule(rule)) priority[direction] += 10 params = NetworkSecurityGroup( location=location, security_rules=security_rules, ) return ncli.network_security_groups.create_or_update( resource_group_name=rg_name, network_security_group_name=nsg_name, parameters=params, ).result()
def list(self, resource_group_name: str) -> List[NetworkSecurityGroup]: try: files = [file for file in os.listdir(self.path / resource_group_name) if file.startswith("nsg-")] except FileNotFoundError: raise ResourceNotFoundError("No resource group") from None elements = [] for file in files: with open(self.path / resource_group_name / file, "r", encoding="utf-8") as file: elements.append(NetworkSecurityGroup.deserialize(json.load(file))) return elements
def create_netsec_group(self, group_name, resource_group=None): security_groups = self.network_client.network_security_groups self.logger.info("Attempting to Create New Azure Security Group {}".format(group_name)) nsg = NetworkSecurityGroup(location=self.region) operation = security_groups.create_or_update(resource_group_name=resource_group or self.resource_group, network_security_group_name=group_name, parameters=nsg) operation.wait() self.logger.info("Network Security Group {} is created".format(group_name)) return operation.status()
def create_or_update(self, results): parameters = NetworkSecurityGroup() if results.get('rules'): parameters.security_rules = [] for rule in results.get('rules'): parameters.security_rules.append(create_rule_instance(rule)) if results.get('default_rules'): parameters.default_security_rules = [] for rule in results.get('default_rules'): parameters.default_security_rules.append(create_rule_instance(rule)) parameters.tags = results.get('tags') parameters.location = results.get('location') try: poller = self.network_client.network_security_groups.create_or_update(self.resource_group, self.name, parameters) result = self.get_poller_result(poller) except AzureHttpError as exc: self.fail("Error creating/upating security group {0} - {1}".format(self.name, str(exc))) return create_network_security_group_dict(result)
def test_remediate_success(self): client = Mock() client.network_security_groups.get.return_value = NetworkSecurityGroup( id="nsg", security_rules=[ SecurityRule( protocol="All", access="Allow", direction="Inbound", source_address_prefix="*", destination_port_ranges=["22-30", "3380-3390"], ), SecurityRule( protocol="All", access="Allow", direction="Inbound", source_address_prefix="*", destination_port_range="3380-3395", ), SecurityRule( protocol="All", access="Allow", direction="Inbound", source_address_prefix="*", destination_port_range="3389", ), SecurityRule( protocol="All", access="Allow", direction="Inbound", source_address_prefix="*", destination_port_range="35", ), ], ) action = NetworkSecurityGroupClosePort3389() assert action.remediate(client, "security_group_name", "resource_group") == 0 assert client.network_security_groups.create_or_update.call_count == 1 call_args = client.network_security_groups.create_or_update.call_args updated_sg = call_args.args[2] security_rules = updated_sg.security_rules assert len(security_rules) == 3 assert security_rules[0].destination_port_ranges == [ "22-30", "3380-3388", "3390" ] assert security_rules[1].destination_port_ranges == [ "3380-3388", "3390-3395" ] assert security_rules[1].destination_port_range is None assert security_rules[2].destination_port_range == "35"
def create_security_group(self): """ Creates firewall rules :return: """ with open(f'WebApp/DeploymentLogs/{self.protocol_name}.log', 'a+') as output_file: print('Creating security groups', file=output_file) parameters = NetworkSecurityGroup() parameters.location = 'useast1' parameters.security_rules = [ SecurityRule(description='AllIn', protocol='Tcp', source_port_range='*', destination_port_range='*', access='Allow', direction='Inbound', priority=100, name='AllIn'), SecurityRule(description='AllIn', protocol='Tcp', source_port_range='*', destination_port_range='*', access='Allow', direction='Outbound', priority=100, name='AllIn') ] self.network_client.network_security_groups.create_or_update( self.resource_group, "test-nsg", parameters) with open(f'WebApp/DeploymentLogs/{self.protocol_name}.log', 'a+') as output_file: print( 'Done creating security groups, you will redirect to the deployment in few seconds..', file=output_file)
def create_security_group(call=None, kwargs=None): # pylint: disable=unused-argument ''' Create a security group ''' global netconn # pylint: disable=global-statement,invalid-name if not netconn: netconn = get_conn(NetworkManagementClient, NetworkManagementClientConfiguration) if kwargs is None: kwargs = {} if kwargs.get('location') is None: kwargs['location'] = get_location() if kwargs.get('resource_group') is None: kwargs['resource_group'] = config.get_cloud_config_value( 'resource_group', {}, __opts__, search_global=True) if kwargs.get('name') is None: kwargs['name'] = config.get_cloud_config_value('name', {}, __opts__, search_global=True) group_params = NetworkSecurityGroup(location=kwargs['location'], ) netconn.network_security_group.create_or_update( # pylint: disable=no-member rource_group_name=kwargs['resource_group'], network_security_group_name=kwargs['name'], parameters=group_params, ) count = 0 while True: try: return show_security_group(kwargs=kwargs) except CloudError: count += 1 if count > 120: raise ValueError( 'Timed out waiting for operation to complete.') time.sleep(5)
def create_subnet(resource_group_name, virtual_network_name, subnet_name, address_prefix='10.0.0.0/24', network_security_group=None): '''Create a virtual network (VNet) subnet :param str address_prefix: address prefix in CIDR format. :param str network_security_group: attach with existing network security group, both name or id are accepted. ''' ncf = _network_client_factory() subnet = Subnet(name=subnet_name, address_prefix=address_prefix) subnet.address_prefix = address_prefix if network_security_group: subnet.network_security_group = NetworkSecurityGroup( network_security_group) return ncf.subnets.create_or_update(resource_group_name, virtual_network_name, subnet_name, subnet)
def test_remediate_success(self): client = Mock() action = RestrictUdpAccessFromInternet() security_rule1 = SecurityRule( id="/subscriptions/d687b1a3-9b78-43b1-a17b-7de297fd1fce/resourceGroups/accelerators-team-resources/providers/Microsoft.Network/networkSecurityGroups/port_rules_testing_2/securityRules/Port_23", name="Port_23", protocol="TCP", source_port_range="*", destination_port_range="23", source_address_prefix="*", source_address_prefixes=[], access="Allow", priority=110, direction="Inbound", ) security_rule2 = SecurityRule( id="/subscriptions/d687b1a3-9b78-43b1-a17b-7de297fd1fce/resourceGroups/accelerators-team-resources/providers/Microsoft.Network/networkSecurityGroups/port_rules_testing_2/securityRules/Port_23", name="Port_21", protocol="UDP", source_port_range="*", destination_port_range="21", source_address_prefix="*", source_address_prefixes=[], access="Allow", priority=100, direction="Inbound", ) client.network_security_groups.get.return_value = NetworkSecurityGroup( id="/subscriptions/d687b1a3-9b78-43b1-a17b-7de297fd1fce/resourceGroups/accelerators-team-resources/providers/Microsoft.Network/networkSecurityGroups/port_rules_testing_2", location="eastus", security_rules=[security_rule1, security_rule2], ) assert ( action.remediate(client, "resource_group", "network_security_group_name") == 0 ) assert client.security_rules.begin_delete.call_count == 1 assert client.network_security_groups.get.call_count == 1
def create_network_security_group(self, network_client, group_name, security_group_name, region, tags=None): """Create NSG on the Azure :param network_client: azure.mgmt.network.NetworkManagementClient instance :param group_name: resource group name (reservation id) :param security_group_name: name for NSG on Azure :param region: Azure location :param tags: tags :return: azure.mgmt.network.models.NetworkSecurityGroup instance """ nsg_model = NetworkSecurityGroup(location=region, tags=tags) operation_poler = network_client.network_security_groups.create_or_update( resource_group_name=group_name, network_security_group_name=security_group_name, parameters=nsg_model) return operation_poler.result()
def create_or_update(self, results): parameters = NetworkSecurityGroup() if results.get('rules'): parameters.security_rules = [] for rule in results.get('rules'): parameters.security_rules.append(create_rule_instance(rule)) if results.get('default_rules'): parameters.default_security_rules = [] for rule in results.get('default_rules'): parameters.default_security_rules.append(create_rule_instance(rule)) parameters.tags = results.get('tags') parameters.location = results.get('location') try: poller = self.network_client.network_security_groups.create_or_update(self.resource_group, self.name, parameters) result = self.get_poller_result(poller) except CloudError as exc: self.fail("Error creating/updating security group {0} - {1}".format(self.name, str(exc))) return create_network_security_group_dict(result)
def _ensure_network_security_group(cli_ctx, resource_group_name, ase_name, location, subnet_id, force): subnet_id_parts = parse_resource_id(subnet_id) vnet_resource_group = subnet_id_parts['resource_group'] vnet_name = subnet_id_parts['name'] subnet_name = subnet_id_parts['resource_name'] ase_nsg_name = ase_name + '-NSG' network_client = _get_network_client_factory(cli_ctx) subnet_obj = network_client.subnets.get(vnet_resource_group, vnet_name, subnet_name) subnet_address_prefix = subnet_obj.address_prefix if subnet_obj.network_security_group is None or force: nsg_list = network_client.network_security_groups.list(resource_group_name) nsg_found = False for nsg in list(nsg_list): if nsg.name.lower() == ase_nsg_name.lower(): nsg_found = True break if not nsg_found: logger.info('Ensure Network Security Group...') ase_nsg = NetworkSecurityGroup(location=location) poller = network_client.network_security_groups.begin_create_or_update(resource_group_name, ase_nsg_name, ase_nsg) LongRunningOperation(cli_ctx)(poller) logger.info('Ensure Network Security Group Rules...') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-management', 100, 'Used to manage ASE from public VIP', '*', 'Allow', 'Inbound', '*', 'AppServiceManagement', '454-455', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-load-balancer-keep-alive', 105, 'Allow communication to ASE from Load Balancer', '*', 'Allow', 'Inbound', '*', 'AzureLoadBalancer', '16001', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'ASE-internal-inbound', 110, 'ASE-internal-inbound', '*', 'Allow', 'Inbound', '*', subnet_address_prefix, '*', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-HTTP', 120, 'Allow HTTP', '*', 'Allow', 'Inbound', '*', '*', '80', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-HTTPS', 130, 'Allow HTTPS', '*', 'Allow', 'Inbound', '*', '*', '443', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-FTP', 140, 'Allow FTP', '*', 'Allow', 'Inbound', '*', '*', '21', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-FTPS', 150, 'Allow FTPS', '*', 'Allow', 'Inbound', '*', '*', '990', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-FTP-Data', 160, 'Allow FTP Data', '*', 'Allow', 'Inbound', '*', '*', '10001-10020', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Inbound-Remote-Debugging', 170, 'Visual Studio remote debugging', '*', 'Allow', 'Inbound', '*', '*', '4016-4022', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-443', 100, 'Azure Storage blob', '*', 'Allow', 'Outbound', '*', '*', '443', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-DB', 110, 'Database', '*', 'Allow', 'Outbound', '*', '*', '1433', 'Sql') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-DNS', 120, 'DNS', '*', 'Allow', 'Outbound', '*', '*', '53', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'ASE-internal-outbound', 130, 'Azure Storage queue', '*', 'Allow', 'Outbound', '*', '*', '*', subnet_address_prefix) _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-80', 140, 'Outbound 80', '*', 'Allow', 'Outbound', '*', '*', '80', '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-monitor', 150, 'Azure Monitor', '*', 'Allow', 'Outbound', '*', '*', 12000, '*') _create_nsg_rule(cli_ctx, resource_group_name, ase_nsg_name, 'Outbound-NTP', 160, 'Clock', '*', 'Allow', 'Outbound', '*', '*', '123', '*') nsg = network_client.network_security_groups.get(resource_group_name, ase_nsg_name) if not subnet_obj.network_security_group or subnet_obj.network_security_group.id != nsg.id: logger.info('Associate Network Security Group with Subnet...') subnet_obj.network_security_group = NetworkSecurityGroup(id=nsg.id) poller = network_client.subnets.begin_create_or_update( vnet_resource_group, vnet_name, subnet_name, subnet_parameters=subnet_obj) LongRunningOperation(cli_ctx)(poller) else: nsg_id_parts = parse_resource_id(subnet_obj.network_security_group.id) nsg_name = nsg_id_parts['name'] if nsg_name.lower() != ase_nsg_name.lower(): raise CLIError('Network Security Group already exists. \ Use --ignore-network-security-group to use existing NSG. \ Use --force-network-security-group to replace existing NSG')
def create_default_securitygroup(self, resource_group, location, name, os_type, open_ports): ''' Create a default security group <name>01 to associate with a network interface. If a security group matching <name>01 exists, return it. Otherwise, create one. :param resource_group: Resource group name :param location: azure location name :param name: base name to use for the security group :param os_type: one of 'Windows' or 'Linux'. Determins any default rules added to the security group. :param ssh_port: for os_type 'Linux' port used in rule allowing SSH access. :param rdp_port: for os_type 'Windows' port used in rule allowing RDP access. :return: security_group object ''' security_group_name = name + '01' group = None self.log("Create security group {0}".format(security_group_name)) self.log("Check to see if security group {0} exists".format( security_group_name)) try: group = self.network_client.network_security_groups.get( resource_group, security_group_name) except CloudError: pass if group: self.log("Security group {0} found.".format(security_group_name)) self.check_provisioning_state(group) return group parameters = NetworkSecurityGroup() parameters.location = location if not open_ports: # Open default ports based on OS type if os_type == 'Linux': # add an inbound SSH rule parameters.security_rules = [ SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', description='Allow SSH Access', source_port_range='*', destination_port_range='22', priority=100, name='SSH') ] parameters.location = location else: # for windows add inbound RDP and WinRM rules parameters.security_rules = [ SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', description='Allow RDP port 3389', source_port_range='*', destination_port_range='3389', priority=100, name='RDP01'), SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', description='Allow WinRM HTTPS port 5986', source_port_range='*', destination_port_range='5986', priority=101, name='WinRM01'), ] else: # Open custom ports parameters.security_rules = [] priority = 100 for port in open_ports: priority += 1 rule_name = "Rule_{0}".format(priority) parameters.security_rules.append( SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', source_port_range='*', destination_port_range=str(port), priority=priority, name=rule_name)) self.log( 'Creating default security group {0}'.format(security_group_name)) try: poller = self.network_client.network_security_groups.create_or_update( resource_group, security_group_name, parameters) except Exception as exc: self.fail("Error creating default security rule {0} - {1}".format( security_group_name, str(exc))) return self.get_poller_result(poller)
def test_remediate_success(self): compute_client = Mock() nw_profile = NetworkProfile(network_interfaces=[ NetworkInterfaceReference( id= "/subscriptions/subscription_id/resourceGroups/resource_group/providers/Microsoft.Network" "/networkInterfaces/vm_nameVMNic ") ]) compute_client.virtual_machines.get.return_value = VirtualMachine( id= "/subscriptions/subscription_id/resourceGroups/resource_group/providers/Microsoft.Compute" "/virtualMachines/vm_name", location="eastus", network_profile=nw_profile, ) nw_client = Mock() nw_client.network_interfaces.get.return_value = NetworkInterface( id= "/subscriptions/subscription_id/resourceGroups/resource_group/providers/Microsoft.Network" "/networkInterfaces/vm_nameVMNic", network_security_group=NetworkSecurityGroup( id= "/subscriptions/subscription_id/resourceGroups/resource_name/providers/Microsoft.Network" "/networkSecurityGroups/vm_nameNSG "), ) nw_client.network_security_groups.get.return_value = NetworkSecurityGroup( id= "/subscriptions/subscription_id/resourceGroups/resource_name/providers/Microsoft.Network" "/networkSecurityGroups/vm_nameNSG", security_rules=[ SecurityRule( protocol="All", access="Allow", direction="Inbound", source_address_prefix="*", destination_port_ranges=["22", "3389"], ), SecurityRule( protocol="All", access="Allow", direction="Inbound", source_address_prefix="*", destination_port_ranges=["20-30", "3389"], ), SecurityRule( protocol="All", access="Allow", direction="Inbound", source_address_prefix="*", destination_port_range="22", ), ], ) action = VMSecurityGroupClosePort22() assert (action.remediate(compute_client, nw_client, "resource_name", "vm_name") == 0) assert nw_client.network_security_groups.create_or_update.call_count == 1 call_args = nw_client.network_security_groups.create_or_update.call_args updated_sg = call_args.args[2] security_rules = updated_sg.security_rules assert len(security_rules) == 2 assert security_rules[0].destination_port_ranges == ["3389"] assert security_rules[1].destination_port_ranges == [ "20-21", "23-30", "3389" ]
def create_nsg_object(): return NetworkSecurityGroup()
def create_default_securitygroup(self, resource_group, location, name, os_type, open_ports): ''' Create a default security group <name>01 to associate with a network interface. If a security group matching <name>01 exists, return it. Otherwise, create one. :param resource_group: Resource group name :param location: azure location name :param name: base name to use for the security group :param os_type: one of 'Windows' or 'Linux'. Determins any default rules added to the security group. :param ssh_port: for os_type 'Linux' port used in rule allowing SSH access. :param rdp_port: for os_type 'Windows' port used in rule allowing RDP access. :return: security_group object ''' security_group_name = name + '01' group = None self.log("Create security group {0}".format(security_group_name)) self.log("Check to see if security group {0} exists".format(security_group_name)) try: group = self.network_client.network_security_groups.get(resource_group, security_group_name) except CloudError: pass if group: self.log("Security group {0} found.".format(security_group_name)) self.check_provisioning_state(group) return group parameters = NetworkSecurityGroup() parameters.location = location if not open_ports: # Open default ports based on OS type if os_type == 'Linux': # add an inbound SSH rule parameters.security_rules = [ SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', description='Allow SSH Access', source_port_range='*', destination_port_range='22', priority=100, name='SSH') ] parameters.location = location else: # for windows add inbound RDP and WinRM rules parameters.security_rules = [ SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', description='Allow RDP port 3389', source_port_range='*', destination_port_range='3389', priority=100, name='RDP01'), SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', description='Allow WinRM HTTPS port 5986', source_port_range='*', destination_port_range='5986', priority=101, name='WinRM01'), ] else: # Open custom ports parameters.security_rules = [] priority = 100 for port in open_ports: priority += 1 rule_name = "Rule_{0}".format(priority) parameters.security_rules.append( SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', source_port_range='*', destination_port_range=str(port), priority=priority, name=rule_name) ) self.log('Creating default security group {0}'.format(security_group_name)) try: poller = self.network_client.network_security_groups.create_or_update(resource_group, security_group_name, parameters) except Exception as exc: self.fail("Error creating default security rule {0} - {1}".format(security_group_name, str(exc))) return self.get_poller_result(poller)
def exec_module(self, **kwargs): nsg = None subnet = None for key in self.module_arg_spec: setattr(self, key, kwargs[key]) if self.state == 'present' and not CIDR_PATTERN.match( self.address_prefix_cidr): self.fail("Invalid address_prefix_cidr value {0}".format( self.address_prefix_cidr)) if self.security_group_name: nsg = self.get_security_group(self.security_group_name) results = dict() changed = False try: self.log('Fetching subnet {0}'.format(self.name)) subnet = self.network_client.subnets.get(self.resource_group, self.virtual_network_name, self.name) self.check_provisioning_state(subnet, self.state) results = subnet_to_dict(subnet) if self.state == 'present': if self.address_prefix_cidr: if results['address_prefix'] != self.address_prefix_cidr: self.log( "CHANGED: subnet {0} address_prefix_cidr".format( self.name)) changed = True results['address_prefix'] = self.address_prefix_cidr if self.security_group_name: if results['network_security_group'].get('id') != nsg.id: self.log("CHANGED: subnet {0} network security group". format(self.name)) changed = True results['network_security_group']['id'] = nsg.id results['network_security_group']['name'] = nsg.name elif self.state == 'absent': changed = True except CloudError: # the subnet does not exist if self.state == 'present': changed = True self.results['changed'] = changed self.results['state'] = results if not self.check_mode: if self.state == 'present' and changed: if not subnet: # create new subnet self.log('Creating subnet {0}'.format(self.name)) subnet = Subnet(address_prefix=self.address_prefix_cidr) if nsg: subnet.network_security_group = NetworkSecurityGroup( id=nsg.id, location=nsg.location, resource_guid=nsg.resource_guid) else: # update subnet self.log('Updating subnet {0}'.format(self.name)) subnet = Subnet(address_prefix=results['address_prefix']) if results['network_security_group'].get('id'): nsg = self.get_security_group( results['network_security_group']['name']) subnet.network_security_group = NetworkSecurityGroup( id=nsg.id, location=nsg.location, resource_guid=nsg.resource_guid) self.results['state'] = self.create_or_update_subnet(subnet) elif self.state == 'absent': # delete subnet self.delete_subnet() # the delete does not actually return anything. if no exception, then we'll assume # it worked. self.results['state']['status'] = 'Deleted' return self.results
def add_nsg_rule( self, rg_name=None, location=None, nsg_name=None, protocol="Tcp", direction="Inbound", access="Allow", description="Test automation rule", source_port_range="*", destination_port_range=None, priority=700, name="test_automation", source_address_prefix="*", destination_address_prefix="*", ): """ Add new rule to Azure Network Security Group. Args: rg_name (str): Azure resource group name location (str): Azure resource group location nsg_name (str): Azure NSG name protocol (str): protocol for rule (Tcp, Udp) direction (str): web traffic direction (Inbound, Outbound) access (str): access policy for rule (Allow, Deny) description (str): rule description source_port_range (str): source port range for rule destination_port_range (str): destination port range for rule priority (int): rule priority name (str): rule name source_address_prefix (str): source address prefix destination_address_prefix (str): destination address prefix """ parameters = NetworkSecurityGroup() parameters.location = location try: parameters.security_rules = self.get_nsg(rg_name, nsg_name).security_rules except CloudError: parameters.security_rules = [] parameters.security_rules.append( SecurityRule( protocol=protocol, direction=direction, access=access, description=description, source_port_range=source_port_range, destination_port_range=destination_port_range, priority=priority, name=name, source_address_prefix=source_address_prefix, destination_address_prefix=destination_address_prefix, ) ) try: poller_obj = self.network_client.network_security_groups.create_or_update( rg_name, nsg_name, parameters ) except CloudError as cloud_err: self.colored_print(cloud_err.__repr__(), level="error") raise poller_obj.wait()
def vm_open_port(resource_group_name, vm_name, network_security_group_name=None, apply_to_subnet=False): """ Opens a VM to all inbound traffic and protocols by adding a security rule to the network security group (NSG) that is attached to the VM's network interface (NIC) or subnet. The existing NSG will be used or a new one will be created. The rule name is 'open-port-cmd' and will overwrite an existing rule with this name. For multi-NIC VMs, or for more fine grained control, use the appropriate network commands directly (nsg rule create, etc). """ from azure.mgmt.network import NetworkManagementClient network = get_mgmt_service_client(NetworkManagementClient) vm = _vm_get(resource_group_name, vm_name) location = vm.location nic_ids = list(vm.network_profile.network_interfaces) if len(nic_ids) > 1: raise CLIError('Multiple NICs is not supported for this command. Create rules on the NSG ' 'directly.') elif not nic_ids: raise CLIError("No NIC associated with VM '{}'".format(vm_name)) # get existing NSG or create a new one nic = network.network_interfaces.get(resource_group_name, os.path.split(nic_ids[0].id)[1]) if not apply_to_subnet: nsg = nic.network_security_group else: from azure.cli.core.commands.arm import parse_resource_id subnet_id = parse_resource_id(nic.ip_configurations[0].subnet.id) subnet = network.subnets.get(resource_group_name, subnet_id['name'], subnet_id['child_name']) nsg = subnet.network_security_group if not nsg: from azure.mgmt.network.models import NetworkSecurityGroup nsg = LongRunningOperation('Creating network security group')( network.network_security_groups.create_or_update( resource_group_name=resource_group_name, network_security_group_name=network_security_group_name, parameters=NetworkSecurityGroup(location=location) ) ) # update the NSG with the new rule to allow inbound traffic from azure.mgmt.network.models import SecurityRule rule = SecurityRule(protocol='*', access='allow', direction='inbound', name='open-port-cmd', source_port_range='*', destination_port_range='*', priority=900, source_address_prefix='*', destination_address_prefix='*') nsg_name = nsg.name or os.path.split(nsg.id)[1] LongRunningOperation('Adding security rule')( network.security_rules.create_or_update( resource_group_name, nsg_name, 'open-port-cmd', rule) ) # update the NIC or subnet if not apply_to_subnet: nic.network_security_group = nsg return LongRunningOperation('Updating NIC')( network.network_interfaces.create_or_update( resource_group_name, nic.name, nic) ) else: from azure.mgmt.network.models import Subnet subnet.network_security_group = nsg return LongRunningOperation('Updating subnet')( network.subnets.create_or_update( resource_group_name=resource_group_name, virtual_network_name=subnet_id['name'], subnet_name=subnet_id['child_name'], subnet_parameters=subnet ) )
def exec_module(self, **kwargs): for key in self.module_arg_spec.keys() + ['tags']: setattr(self, key, kwargs[key]) results = dict() changed = False nic = None subnet = None nsg = None pip = None resource_group = self.get_resource_group(self.resource_group) if not self.location: # Set default location self.location = resource_group.location if not NAME_PATTERN.match(self.name): self.fail( "Parameter error: name must begin with a letter or number, end with a letter or number " "and contain at least one number.") if self.state == 'present': if self.virtual_network_name and not self.subnet_name: self.fail( "Parameter error: a subnet is required when passing a virtual_network_name." ) if self.subnet_name and not self.virtual_network_name: self.fail( "Parameter error: virtual_network_name is required when passing a subnet value." ) if self.virtual_network_name and self.subnet_name: subnet = self.get_subnet(self.virtual_network_name, self.subnet_name) if self.public_ip_address_name: pip = self.get_public_ip_address(self.public_ip_address_name) if self.security_group_name: nsg = self.get_security_group(self.security_group_name) try: self.log('Fetching network interface {0}'.format(self.name)) nic = self.network_client.network_interfaces.get( self.resource_group, self.name) self.log('Network interface {0} exists'.format(self.name)) self.check_provisioning_state(nic, self.state) results = nic_to_dict(nic) self.log(results, pretty_print=True) if self.state == 'present': update_tags, results['tags'] = self.update_tags( results['tags']) if update_tags: changed = True if self.private_ip_address: if results['ip_configuration'][ 'private_ip_address'] != self.private_ip_address: self.log( "CHANGED: network interface {0} private ip".format( self.name)) changed = True results['ip_configuration'][ 'private_ip_address'] = self.private_ip_address if self.public_ip_address_name: if results['ip_configuration']['public_ip_address'].get( 'id') != pip.id: self.log( "CHANGED: network interface {0} public ip".format( self.name)) changed = True results['ip_configuration']['public_ip_address'][ 'id'] = pip.id results['ip_configuration']['public_ip_address'][ 'name'] = pip.name if self.security_group_name: if results['network_security_group'].get('id') != nsg.id: self.log( "CHANGED: network interface {0} network security group" .format(self.name)) changed = True results['network_security_group']['id'] = nsg.id results['network_security_group']['name'] = nsg.name if self.private_ip_allocation_method: if results['ip_configuration'][ 'private_ip_allocation_method'] != self.private_ip_allocation_method: self.log( "CHANGED: network interface {0} private ip allocation" .format(self.name)) changed = True results['ip_configuration'][ 'private_ip_allocation_method'] = self.private_ip_allocation_method if self.private_ip_allocation_method == 'Dynamic': results['ip_configuration'][ 'private_ip_address'] = None if self.subnet_name: if results['ip_configuration']['subnet'].get( 'id') != subnet.id: changed = True self.log( "CHANGED: network interface {0} subnet".format( self.name)) results['ip_configuration']['subnet']['id'] = subnet.id results['ip_configuration']['subnet'][ 'name'] = subnet.name results['ip_configuration']['subnet'][ 'virtual_network_name'] = self.virtual_network_name elif self.state == 'absent': self.log( "CHANGED: network interface {0} exists but requested state is 'absent'" .format(self.name)) changed = True except CloudError: self.log('Network interface {0} does not exist'.format(self.name)) if self.state == 'present': self.log( "CHANGED: network interface {0} does not exist but requested state is " "'present'".format(self.name)) changed = True self.results['changed'] = changed self.results['state'] = results if self.check_mode: return self.results if changed: if self.state == 'present': if not nic: # create network interface self.log("Creating network interface {0}.".format( self.name)) # check required parameters if not self.subnet_name: self.fail( "parameter error: subnet_name required when creating a network interface." ) if not self.virtual_network_name: self.fail( "parameter error: virtual_network_name required when creating a network interface." ) if not self.security_group_name: # create default security group nsg = self.create_default_securitygroup( self.resource_group, self.location, self.name, self.os_type, self.open_ports) if not pip and self.public_ip: # create a default public_ip pip = self.create_default_pip( self.resource_group, self.location, self.name, self.public_ip_allocation_method) nic = NetworkInterface( location=self.location, name=self.name, tags=self.tags, ip_configurations=[ NetworkInterfaceIPConfiguration( name='default', private_ip_allocation_method=self. private_ip_allocation_method, ) ]) nic.ip_configurations[0].subnet = Subnet(id=subnet.id) nic.network_security_group = NetworkSecurityGroup( id=nsg.id, name=nsg.name, location=nsg.location, resource_guid=nsg.resource_guid) if self.private_ip_address: nic.ip_configurations[ 0].private_ip_address = self.private_ip_address if pip: nic.ip_configurations[ 0].public_ip_address = PublicIPAddress( id=pip.id, name=pip.name, location=pip.location, resource_guid=pip.resource_guid) else: self.log("Updating network interface {0}.".format( self.name)) nic = NetworkInterface( location=results['location'], name=results['name'], tags=results['tags'], ip_configurations=[ NetworkInterfaceIPConfiguration( name=results['ip_configuration']['name'], private_ip_allocation_method=results[ 'ip_configuration'] ['private_ip_allocation_method'], ) ], ) subnet = self.get_subnet( results['ip_configuration']['subnet'] ['virtual_network_name'], results['ip_configuration']['subnet']['name']) nic.ip_configurations[0].subnet = Subnet(id=subnet.id) if results['ip_configuration'].get('private_ip_address'): nic.ip_configurations[0].private_ip_address = results[ 'ip_configuration']['private_ip_address'] if results['ip_configuration']['public_ip_address'].get( 'id'): pip = \ self.get_public_ip_address(results['ip_configuration']['public_ip_address']['name']) nic.ip_configurations[ 0].public_ip_address = PublicIPAddress( id=pip.id, name=pip.name, location=pip.location, resource_guid=pip.resource_guid) if results['network_security_group'].get('id'): nsg = self.get_security_group( results['network_security_group']['name']) nic.network_security_group = NetworkSecurityGroup( id=nsg.id, name=nsg.name, location=nsg.location, resource_guid=nsg.resource_guid) # See what actually gets sent to the API request = self.serialize_obj(nic, 'NetworkInterface') self.log(request, pretty_print=True) self.results['state'] = self.create_or_update_nic(nic) elif self.state == 'absent': self.log('Deleting network interface {0}'.format(self.name)) self.delete_nic() return self.results