def resolve_storage_source(self, source): blob_uri = None disk = None snapshot = None # blob URI can only be given by str if isinstance(source, str) and source.lower().endswith('.vhd'): blob_uri = source return (blob_uri, disk, snapshot) tokenize = dict() if isinstance(source, dict): tokenize = source elif isinstance(source, str): tokenize = parse_resource_id(source) else: self.fail( "source parameter should be in type string or dictionary") if tokenize.get('type') == 'disks': disk = format_resource_id( tokenize['name'], tokenize.get('subscription_id') or self.subscription_id, 'Microsoft.Compute', 'disks', tokenize.get('resource_group') or self.resource_group) return (blob_uri, disk, snapshot) if tokenize.get('type') == 'snapshots': snapshot = format_resource_id( tokenize['name'], tokenize.get('subscription_id') or self.subscription_id, 'Microsoft.Compute', 'snapshots', tokenize.get('resource_group') or self.resource_group) return (blob_uri, disk, snapshot) # not a disk or snapshots if 'type' in tokenize: return (blob_uri, disk, snapshot) # source can be name of snapshot or disk snapshot_instance = self.get_snapshot( tokenize.get('resource_group') or self.resource_group, tokenize['name']) if snapshot_instance: snapshot = snapshot_instance.id return (blob_uri, disk, snapshot) disk_instance = self.get_disk( tokenize.get('resource_group') or self.resource_group, tokenize['name']) if disk_instance: disk = disk_instance.id return (blob_uri, disk, snapshot)
def create_or_update_vnet_peering(self): ''' Creates or Update Azure Virtual Network Peering. :return: deserialized Azure Virtual Network Peering instance state dictionary ''' self.log("Creating or Updating the Azure Virtual Network Peering {0}". format(self.name)) vnet_id = format_resource_id(self.virtual_network['name'], self.subscription_id, 'Microsoft.Network', 'virtualNetworks', self.virtual_network['resource_group']) peering = self.network_models.VirtualNetworkPeering( id=vnet_id, name=self.name, remote_virtual_network=self.network_models.SubResource( id=self.remote_virtual_network), allow_virtual_network_access=self.allow_virtual_network_access, allow_gateway_transit=self.allow_gateway_transit, allow_forwarded_traffic=self.allow_forwarded_traffic, use_remote_gateways=self.use_remote_gateways) try: response = self.network_client.virtual_network_peerings.create_or_update( self.resource_group, self.virtual_network['name'], self.name, peering) if isinstance(response, LROPoller): response = self.get_poller_result(response) return vnetpeering_to_dict(response) except CloudError as exc: self.fail( "Error creating Azure Virtual Network Peering: {0}.".format( exc.message))
def get_public_ip_address_instance(self, id): """Get a reference to the public ip address resource""" self.log('Fetching public ip address {0}'.format(id)) resource_id = format_resource_id(id, self.subscription_id, 'Microsoft.Network', 'publicIPAddresses', self.resource_group) return self.network_models.PublicIPAddress(id=resource_id)
def format_elastic_pool_id(self): parrent_id = format_resource_id(val=self.server_name, subscription_id=self.subscription_id, namespace="Microsoft.Sql", types="servers", resource_group=self.resource_group) self.parameters[ 'elastic_pool_id'] = parrent_id + "/elasticPools/" + self.parameters[ 'elastic_pool_id']
def parse_vn_id(self, vn): vn_dict = self.parse_resource_to_dict(vn) if not isinstance( vn, dict) else vn return format_resource_id(val=vn_dict['name'], subscription_id=vn_dict.get('subscription') or self.subscription_id, namespace='Microsoft.Network', types='virtualNetworks', resource_group=vn_dict.get('resource_group') or self.resource_group)
def parse_nsg(self): nsg = self.security_group resource_group = self.resource_group if isinstance(self.security_group, dict): nsg = self.security_group.get('name') resource_group = self.security_group.get('resource_group', self.resource_group) id = format_resource_id(val=nsg, subscription_id=self.subscription_id, namespace='Microsoft.Network', types='networkSecurityGroups', resource_group=resource_group) name = azure_id_to_dict(id).get('name') return dict(id=id, name=name)
def format_vnet_id(self, vnet): if not vnet: return vnet if isinstance( vnet, dict) and vnet.get('name') and vnet.get('resource_group'): remote_vnet_id = format_resource_id(vnet['name'], self.subscription_id, 'Microsoft.Network', 'virtualNetworks', vnet['resource_group']) elif isinstance(vnet, str): if is_valid_resource_id(vnet): remote_vnet_id = vnet else: remote_vnet_id = format_resource_id(vnet, self.subscription_id, 'Microsoft.Network', 'virtualNetworks', self.resource_group) else: self.fail( "remote_virtual_network could be a valid resource id, dict of name and resource_group, name of virtual network in same resource group." ) return remote_vnet_id
def get_source_vm(self): # self.resource can be a vm (id/name/dict), or not a vm. return the vm iff it is an existing vm. resource = dict() if isinstance(self.source, dict): if self.source.get('type') != 'virtual_machines': return None resource = dict(type='virtualMachines', name=self.source['name'], resource_group=self.source.get('resource_group') or self.resource_group) elif isinstance(self.source, str): vm_resource_id = format_resource_id(self.source, self.subscription_id, 'Microsoft.Compute', 'virtualMachines', self.resource_group) resource = parse_resource_id(vm_resource_id) else: self.fail( "Unsupported type of source parameter, please give string or dictionary" ) return self.get_vm(resource['resource_group'], resource['name'] ) if resource['type'] == 'virtualMachines' else None
def exec_module(self, **kwargs): for key in list(self.module_arg_spec.keys()) + ['tags']: setattr(self, key, kwargs[key]) results = None changed = False nic = None nsg = None resource_group = self.get_resource_group(self.resource_group) if not self.location: # Set default location self.location = resource_group.location self.location = normalize_location_name(self.location) # parse the virtual network resource group and name self.virtual_network = self.parse_resource_to_dict(self.virtual_network) # if not set the security group name, use nic name for default self.security_group = self.parse_resource_to_dict(self.security_group or self.name) # if application security groups set, convert to resource id format if self.ip_configurations: for config in self.ip_configurations: if config.get('application_security_groups'): asgs = [] for asg in config['application_security_groups']: asg_resource_id = asg if isinstance(asg, str) and (not is_valid_resource_id(asg)): asg = self.parse_resource_to_dict(asg) if isinstance(asg, dict): asg_resource_id = format_resource_id(val=asg['name'], subscription_id=self.subscription_id, namespace='Microsoft.Network', types='applicationSecurityGroups', resource_group=asg['resource_group']) asgs.append(asg_resource_id) if len(asgs) > 0: config['application_security_groups'] = asgs if self.state == 'present' and not self.ip_configurations: # construct the ip_configurations array for compatible self.deprecate('Setting ip_configuration flatten is deprecated and will be removed.' ' Using ip_configurations list to define the ip configuration', version='2.9') self.ip_configurations = [ dict( private_ip_address=self.private_ip_address, private_ip_allocation_method=self.private_ip_allocation_method, public_ip_address_name=self.public_ip_address_name if self.public_ip else None, public_ip_allocation_method=self.public_ip_allocation_method, name='default', primary=True ) ] 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) nsg = None if self.state == 'present': # check for update update_tags, results['tags'] = self.update_tags(results['tags']) if update_tags: changed = True if self.create_with_security_group != bool(results.get('network_security_group')): self.log("CHANGED: add or remove network interface {0} network security group".format(self.name)) changed = True if self.enable_accelerated_networking != bool(results.get('enable_accelerated_networking')): self.log("CHANGED: Accelerated Networking set to {0} (previously {1})".format( self.enable_accelerated_networking, results.get('enable_accelerated_networking'))) changed = True if self.enable_ip_forwarding != bool(results.get('enable_ip_forwarding')): self.log("CHANGED: IP forwarding set to {0} (previously {1})".format( self.enable_ip_forwarding, results.get('enable_ip_forwarding'))) changed = True # We need to ensure that dns_servers are list like dns_servers_res = results.get('dns_settings').get('dns_servers') _dns_servers_set = sorted(self.dns_servers) if isinstance(self.dns_servers, list) else list() _dns_servers_res = sorted(dns_servers_res) if isinstance(self.dns_servers, list) else list() if _dns_servers_set != _dns_servers_res: self.log("CHANGED: DNS servers set to {0} (previously {1})".format( ", ".join(_dns_servers_set), ", ".join(_dns_servers_res))) changed = True if not changed: nsg = self.get_security_group(self.security_group['resource_group'], self.security_group['name']) if nsg and results.get('network_security_group') and results['network_security_group'].get('id') != nsg.id: self.log("CHANGED: network interface {0} network security group".format(self.name)) changed = True if results['ip_configurations'][0]['subnet']['virtual_network_name'] != self.virtual_network['name']: self.log("CHANGED: network interface {0} virtual network name".format(self.name)) changed = True if results['ip_configurations'][0]['subnet']['resource_group'] != self.virtual_network['resource_group']: self.log("CHANGED: network interface {0} virtual network resource group".format(self.name)) changed = True if results['ip_configurations'][0]['subnet']['name'] != self.subnet_name: self.log("CHANGED: network interface {0} subnet name".format(self.name)) changed = True # check the ip_configuration is changed # construct two set with the same structure and then compare # the list should contains: # name, private_ip_address, public_ip_address_name, private_ip_allocation_method, subnet_name ip_configuration_result = self.construct_ip_configuration_set(results['ip_configurations']) ip_configuration_request = self.construct_ip_configuration_set(self.ip_configurations) if ip_configuration_result != ip_configuration_request: self.log("CHANGED: network interface {0} ip configurations".format(self.name)) changed = True 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': subnet = self.network_models.SubResource( id='/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Network/virtualNetworks/{2}/subnets/{3}'.format( self.virtual_network['subscription_id'], self.virtual_network['resource_group'], self.virtual_network['name'], self.subnet_name)) nic_ip_configurations = [ self.network_models.NetworkInterfaceIPConfiguration( private_ip_allocation_method=ip_config.get('private_ip_allocation_method'), private_ip_address=ip_config.get('private_ip_address'), name=ip_config.get('name'), subnet=subnet, public_ip_address=self.get_or_create_public_ip_address(ip_config), load_balancer_backend_address_pools=([self.network_models.BackendAddressPool(id=self.backend_addr_pool_id(bap_id)) for bap_id in ip_config.get('load_balancer_backend_address_pools')] if ip_config.get('load_balancer_backend_address_pools') else None), primary=ip_config.get('primary'), application_security_groups=([self.network_models.ApplicationSecurityGroup(id=asg_id) for asg_id in ip_config.get('application_security_groups')] if ip_config.get('application_security_groups') else None) ) for ip_config in self.ip_configurations ] nsg = self.create_default_securitygroup(self.security_group['resource_group'], self.location, self.security_group['name'], self.os_type, self.open_ports) if self.create_with_security_group else None self.log('Creating or updating network interface {0}'.format(self.name)) nic = self.network_models.NetworkInterface( id=results['id'] if results else None, location=self.location, tags=self.tags, ip_configurations=nic_ip_configurations, enable_accelerated_networking=self.enable_accelerated_networking, enable_ip_forwarding=self.enable_ip_forwarding, network_security_group=nsg ) if self.dns_servers: dns_settings = self.network_models.NetworkInterfaceDnsSettings( dns_servers=self.dns_servers) nic.dns_settings = dns_settings 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() # Delete doesn't return anything. If we get this far, assume success self.results['state']['status'] = 'Deleted' return self.results
def exec_module(self, **kwargs): """Main module execution method""" for key in list(self.module_arg_spec.keys()) + ['tags']: setattr(self, key, kwargs[key]) old_response = None response = None to_be_updated = False # get storage account id if self.storage_account: if isinstance(self.storage_account, dict): self.storage_account = format_resource_id( val=self.storage_account['name'], subscription_id=self.storage_account.get('subscription') or self.subscription_id, namespace='Microsoft.Storage', types='storageAccounts', resource_group=self.storage_account.get('resource_group')) elif not is_valid_resource_id(self.storage_account): self.fail( "storage_account either be a resource id or a dict containing resource_group and name" ) # get existing log profile old_response = self.get_logprofile() if old_response: self.results['id'] = old_response['id'] if self.state == 'present': # if profile not exists, create new if not old_response: self.log("Log profile instance doesn't exist") to_be_updated = True self.to_do = Actions.CreateOrUpdate else: # log profile exists already, do update self.log("Log profile instance already exists") update_tags, self.tags = self.update_tags( old_response.get('tags', None)) if update_tags: to_be_updated = True self.to_do = Actions.CreateOrUpdate # check if update if self.check_update(old_response): to_be_updated = True self.to_do = Actions.CreateOrUpdate elif self.state == 'absent': if old_response: self.log("Delete log profile instance") self.results['id'] = old_response['id'] to_be_updated = True self.to_do = Actions.Delete else: self.results['changed'] = False self.log("Log profile {0} not exists.".format(self.name)) if to_be_updated: self.log('Need to Create/Update log profile') self.results['changed'] = True if self.check_mode: return self.results if self.to_do == Actions.CreateOrUpdate: response = self.create_or_update_logprofile() self.results['id'] = response['id'] if self.to_do == Actions.Delete: self.delete_logprofile() self.log('Log profile instance deleted') return self.results
def exec_module(self, **kwargs): nsg = None subnet = None for key in self.module_arg_spec: setattr(self, key, kwargs[key]) if self.address_prefix_cidr and not CIDR_PATTERN.match( self.address_prefix_cidr): self.fail("Invalid address_prefix_cidr value {0}".format( self.address_prefix_cidr)) nsg = dict() if self.security_group: nsg = self.parse_nsg() route_table = dict() if self.route_table: route_table = self.parse_resource_to_dict(self.route_table) self.route_table = format_resource_id( val=route_table['name'], subscription_id=route_table['subscription_id'], namespace='Microsoft.Network', types='routeTables', resource_group=route_table['resource_group']) 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 and 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 is not None and results[ 'network_security_group'].get('id') != nsg.get('id'): self.log( "CHANGED: subnet {0} network security group".format( self.name)) changed = True results['network_security_group']['id'] = nsg.get('id') results['network_security_group']['name'] = nsg.get('name') if self.route_table is not None and self.route_table != results[ 'route_table'].get('id'): changed = True results['route_table']['id'] = self.route_table self.log("CHANGED: subnet {0} route_table to {1}".format( self.name, route_table.get('name'))) if self.service_endpoints: oldd = {} for item in self.service_endpoints: name = item['service'] locations = item.get('locations') or [] oldd[name] = { 'service': name, 'locations': locations.sort() } newd = {} if 'service_endpoints' in results: for item in results['service_endpoints']: name = item['service'] locations = item.get('locations') or [] newd[name] = { 'service': name, 'locations': locations.sort() } if newd != oldd: changed = True results['service_endpoints'] = self.service_endpoints 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 if not self.address_prefix_cidr: self.fail('address_prefix_cidr is not set') self.log('Creating subnet {0}'.format(self.name)) subnet = self.network_models.Subnet( address_prefix=self.address_prefix_cidr) if nsg: subnet.network_security_group = self.network_models.NetworkSecurityGroup( id=nsg.get('id')) if self.route_table: subnet.route_table = self.network_models.RouteTable( id=self.route_table) if self.service_endpoints: subnet.service_endpoints = self.service_endpoints else: # update subnet self.log('Updating subnet {0}'.format(self.name)) subnet = self.network_models.Subnet( address_prefix=results['address_prefix']) if results['network_security_group'].get('id') is not None: subnet.network_security_group = self.network_models.NetworkSecurityGroup( id=results['network_security_group'].get('id')) if results['route_table'].get('id') is not None: subnet.route_table = self.network_models.RouteTable( id=results['route_table'].get('id')) if results.get('service_endpoints') is not None: subnet.service_endpoints = results['service_endpoints'] self.results['state'] = self.create_or_update_subnet(subnet) elif self.state == 'absent' and changed: # 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 exec_module(self, **kwargs): for key in list(self.module_arg_spec.keys()) + ['tags']: setattr(self, key, kwargs[key]) results = None changed = False self.log('Fetching auto scale settings {0}'.format(self.name)) results = self.get_auto_scale() if results and self.state == 'absent': # delete changed = True if not self.check_mode: self.delete_auto_scale() elif self.state == 'present': if not self.location: # Set default location resource_group = self.get_resource_group(self.resource_group) self.location = resource_group.location resource_id = self.target if isinstance(self.target, dict): resource_id = format_resource_id( val=self.target['name'], subscription_id=self.target.get('subscription_id') or self.subscription_id, namespace=self.target['namespace'], types=self.target['types'], resource_group=self.target.get('resource_group') or self.resource_group) self.target = resource_id resource_name = self.name def create_rule_instance(params): rule = params.copy() rule['metric_resource_uri'] = rule.get('metric_resource_uri', self.target) rule['time_grain'] = timedelta( minutes=rule.get('time_grain', 0)) rule['time_window'] = timedelta( minutes=rule.get('time_window', 0)) rule['cooldown'] = timedelta(minutes=rule.get('cooldown', 0)) return ScaleRule(metric_trigger=MetricTrigger(**rule), scale_action=ScaleAction(**rule)) profiles = [ AutoscaleProfile( name=p.get('name'), capacity=ScaleCapacity(minimum=p.get('min_count'), maximum=p.get('max_count'), default=p.get('count')), rules=[ create_rule_instance(r) for r in p.get('rules') or [] ], fixed_date=TimeWindow( time_zone=p.get('fixed_date_timezone'), start=p.get('fixed_date_start'), end=p.get('fixed_date_end')) if p.get('fixed_date_timezone') else None, recurrence=Recurrence( frequency=p.get('recurrence_frequency'), schedule=(RecurrentSchedule( time_zone=p.get('recurrence_timezone'), days=p.get('recurrence_days'), hours=p.get('recurrence_hours'), minutes=p.get('recurrence_mins')))) if p.get('recurrence_frequency') and p['recurrence_frequency'] != 'None' else None) for p in self.profiles or [] ] notifications = [ AutoscaleNotification(email=EmailNotification(**n), webhooks=[ WebhookNotification(service_uri=w) for w in n.get('webhooks') or [] ]) for n in self.notifications or [] ] if not results: # create new changed = True else: # check changed resource_name = results.autoscale_setting_resource_name or self.name update_tags, tags = self.update_tags(results.tags) if update_tags: changed = True self.tags = tags if self.target != results.target_resource_uri: changed = True if self.enabled != results.enabled: changed = True profile_result_set = set( [str(profile_to_dict(p)) for p in results.profiles or []]) if profile_result_set != set( [str(profile_to_dict(p)) for p in profiles]): changed = True notification_result_set = set([ str(notification_to_dict(n)) for n in results.notifications or [] ]) if notification_result_set != set( [str(notification_to_dict(n)) for n in notifications]): changed = True if changed: # construct the instance will be send to create_or_update api results = AutoscaleSettingResource( location=self.location, tags=self.tags, profiles=profiles, notifications=notifications, enabled=self.enabled, autoscale_setting_resource_name=resource_name, target_resource_uri=self.target) if not self.check_mode: results = self.create_or_update_auto_scale(results) # results should be the dict of the instance self.results = auto_scale_to_dict(results) self.results['changed'] = changed return self.results