def main(): module = AnsibleModule( argument_spec=netscaler_common_arguments, supports_check_mode=False, ) module_result = dict( changed=False, failed=False, loglines=loglines, ) try: fetcher = NitroAPIFetcher(module, api_path='nitro/v2/config') result = fetcher.delete(resource='login') log('DELETE result %s' % result) if result['nitro_errorcode'] not in (None, 0): errorcode = result.get('nitro_errorcode') message = result.get('nitro_message') severity = result.get('nitro_severity') msg = "nitro exception errorcode=%s, message=%s, severity=%s" % ( str(errorcode), message, severity) module.fail_json(msg=msg, **module_result) else: module.exit_json(**module_result) except Exception as e: msg = 'Exception %s: %s' % (type(e), str(e)) module.fail_json(msg=msg, **module_result)
def main(): module_specific_arguments = dict( id=dict(type='str'), secret=dict(type='str'), ) argument_spec = dict() argument_spec.update(netscaler_common_arguments) argument_spec.update(module_specific_arguments) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=False, ) module_result = dict( changed=False, failed=False, loglines=loglines, ) try: fetcher = NitroAPIFetcher(module, api_path='nitro/v2/config') if module.params['is_cloud']: post_data = { 'login': { 'ID': module.params['id'], 'Secret': module.params['secret'], } } else: post_data = { 'login': { 'username': module.params['nitro_user'], 'password': module.params['nitro_pass'], } } result = fetcher.post(post_data=post_data, resource='login') log('POST result %s' % result) log(result['nitro_errorcode']) if result['nitro_errorcode'] not in (None, 0): errorcode = result.get('nitro_errorcode') message = result.get('nitro_message') severity = result.get('nitro_severity') msg = "nitro exception errorcode=%s, message=%s, severity=%s" % ( str(errorcode), message, severity) module.fail_json(msg=msg, **module_result) else: module_result.update( dict(session_id=result['data']['login'][0]['sessionid'])) module.exit_json(**module_result) except Exception as e: msg = 'Exception %s: %s' % (type(e), str(e)) module.fail_json(msg=msg, **module_result)
def __init__(self, module): self.module = module self.main_nitro_class = 'ns_device_profile' self.fetcher = NitroAPIFetcher(module) # Dictionary containing attribute information # for each NITRO object utilized by this module self.attribute_config = { 'ns_device_profile': { 'attributes_list': [ 'name', 'svm_ns_comm', 'use_global_setting_for_communication_with_ns', 'id', 'type', 'snmpsecurityname', 'snmpauthprotocol', 'ssl_private_key', 'ssl_cert', 'http_port', 'ns_profile_name', 'ssh_port', 'password', 'snmpsecuritylevel', 'snmpcommunity', 'passphrase', 'snmpprivprotocol', 'https_port', 'username', 'host_password', 'max_wait_time_reboot', 'snmpprivpassword', 'snmpversion', 'cb_profile_name', 'snmpauthpassword', 'host_username', ], 'transforms': {}, 'get_id_attributes': [ 'name', ], 'delete_id_attributes': [], }, } self.module_result = dict( changed=False, failed=False, loglines=loglines, ) self.calculate_configured_ns_device_profile() self.fetch_ns_device_profile()
def __init__(self, module): self.module = module customer_id = self.module.params.get('customer_id') if customer_id is not None: api_path = 'massvc/%s/provisioning/nitro/v1/config' % customer_id self.nitro_api_fetcher = NitroAPIFetcher(module, api_path=api_path) else: self.nitro_api_fetcher = NitroAPIFetcher(module) self.module_result = dict( changed=False, failed=False, loglines=loglines, )
def __init__(self, module): self.module = module self.nitro_api_fetcher = NitroAPIFetcher(module, api_path='stylebook/nitro/v1/config') self.main_nitro_class = 'stylebook' # Dictionary containing attribute information # for each NITRO object utilized by this module self.attribute_config = { 'stylebook': { 'attributes_list': [ 'source', 'namespace', 'version', 'name', 'display_name', ], 'transforms': { }, 'get_id_attributes': [ 'namespace', 'version', 'name', ], 'delete_id_attributes': [ 'namespace', 'version', 'name', ], }, } self.module_result = dict( changed=False, failed=False, loglines=loglines, ) self.calculate_configured_stylebook() self.fetch_stylebook()
def __init__(self, module): self.module = module self.main_nitro_class = 'rba_policy' self.fetcher = NitroAPIFetcher(module) # Dictionary containing attribute information # for each NITRO object utilized by this module self.attribute_config = { 'rba_policy': { 'attributes_list': [ 'tenant_id', 'statement', 'ui', 'name', 'id', 'description', ], 'transforms': {}, 'get_id_attributes': [ 'name', 'id', ], 'delete_id_attributes': [ 'name', 'id', ], }, } self.module_result = dict( changed=False, failed=False, loglines=loglines, ) self.calculate_configured_rba_policy() self.fetch_rba_policy()
class ModuleExecutor(object): def __init__(self, module): self.module = module customer_id = self.module.params.get('customer_id') if customer_id is not None: api_path = 'massvc/%s/nitro/v2/config' % customer_id self.nitro_api_fetcher = NitroAPIFetcher(module, api_path=api_path) else: self.nitro_api_fetcher = NitroAPIFetcher(module, api_path='nitro/v2/config') self.module_result = dict( changed=False, failed=False, loglines=loglines, ) def get_mps_agent_facts(self): log('ModuleExecutor.get_mps_agent_facts()') result = self.nitro_api_fetcher.get( resource='mps_agent', ) log('result of get %s' % result) if result['http_response_data']['status'] != 200: raise Exception('Status code not 200 %s' % result['http_response_data']['status']) agents = result['data'].get('mps_agent', []) log('Will look for name %s' % self.module.params.get('name')) for agent in agents: log('Examining agent %s' % agent['name']) if agent['name'] == self.module.params.get('name'): return agent return {} def main(self): try: mps_agent = self.get_mps_agent_facts() self.module_result.update(dict(mps_agent=mps_agent)) self.module.exit_json(**self.module_result) except Exception as e: msg = 'Exception %s: %s' % (type(e), str(e)) self.module.fail_json(msg=msg, **self.module_result)
def __init__(self, module): self.module = module self.main_nitro_class = 'managed_device' self.fetcher = NitroAPIFetcher(module) # Dictionary containing attribute information # for each NITRO object utilized by this module self.attribute_config = { 'managed_device': { 'attributes_list': [ 'instance_classifier', 'hostname', 'std_bw_config', 'gateway_deployment', 'gateway_ipv6', 'instance_available', 'device_finger_print', 'name', 'ent_bw_available', 'description', 'is_autoscale_group', 'geo_support', 'sslvpn_config', 'mastools_version', 'sysservices', 'ent_bw_total', 'vcpu_config', 'netmask', 'autoprovisioned', 'ent_bw_config', 'datacenter_id', 'instance_config', 'is_managed', 'discovery_time', 'instance_mode', 'instance_total', 'is_ha_configured', 'trust_id', 'ipv4_address', 'profile_name', 'std_bw_available', 'servicepackage', 'last_updated_time', 'plt_bw_total', 'id', 'mgmt_ip_address', 'ipv6_address', 'partition_id', 'license_edition', 'plt_bw_available', 'device_family', 'template_interval', 'type', 'gateway', 'internal_annotation', 'config_type', 'node_id', 'isolation_policy', 'ip_address', 'provision_request_id', 'httpxforwardedfor', 'std_bw_total', 'display_name', 'plt_bw_config', 'partition_name', 'agent_id', 'sslvpn_total', 'peer_device_ip', 'profile_password', 'file_name', 'profile_username', 'file_location_path', 'peer_host_device_ip', 'device_host_ip', 'tr_task_id', 'entity_tag', ], 'transforms': { }, 'get_id_attributes': [ 'ip_address', ], 'delete_id_attributes': [ ], }, } self.module_result = dict( changed=False, failed=False, loglines=loglines, ) self.calculate_configured_managed_device() self.fetch_managed_device()
class ModuleExecutor(object): def __init__(self, module): self.module = module self.main_nitro_class = 'managed_device' self.fetcher = NitroAPIFetcher(module) # Dictionary containing attribute information # for each NITRO object utilized by this module self.attribute_config = { 'managed_device': { 'attributes_list': [ 'instance_classifier', 'hostname', 'std_bw_config', 'gateway_deployment', 'gateway_ipv6', 'instance_available', 'device_finger_print', 'name', 'ent_bw_available', 'description', 'is_autoscale_group', 'geo_support', 'sslvpn_config', 'mastools_version', 'sysservices', 'ent_bw_total', 'vcpu_config', 'netmask', 'autoprovisioned', 'ent_bw_config', 'datacenter_id', 'instance_config', 'is_managed', 'discovery_time', 'instance_mode', 'instance_total', 'is_ha_configured', 'trust_id', 'ipv4_address', 'profile_name', 'std_bw_available', 'servicepackage', 'last_updated_time', 'plt_bw_total', 'id', 'mgmt_ip_address', 'ipv6_address', 'partition_id', 'license_edition', 'plt_bw_available', 'device_family', 'template_interval', 'type', 'gateway', 'internal_annotation', 'config_type', 'node_id', 'isolation_policy', 'ip_address', 'provision_request_id', 'httpxforwardedfor', 'std_bw_total', 'display_name', 'plt_bw_config', 'partition_name', 'agent_id', 'sslvpn_total', 'peer_device_ip', 'profile_password', 'file_name', 'profile_username', 'file_location_path', 'peer_host_device_ip', 'device_host_ip', 'tr_task_id', 'entity_tag', ], 'transforms': { }, 'get_id_attributes': [ 'ip_address', ], 'delete_id_attributes': [ ], }, } self.module_result = dict( changed=False, failed=False, loglines=loglines, ) self.calculate_configured_managed_device() self.fetch_managed_device() def calculate_configured_managed_device(self): log('ModuleExecutor.calculate_configured_managed_device()') self.configured_managed_device = {} for attribute in self.attribute_config['managed_device']['attributes_list']: value = self.module.params.get(attribute) # Skip null values if value is None: continue transform = self.attribute_config['managed_device']['transforms'].get(attribute) if transform is not None: value = transform(value) self.configured_managed_device[attribute] = value log('calculated configured managed_device %s' % self.configured_managed_device) def fetch_managed_device(self): log('ModuleExecutor.fetch_managed_device()') self.fetched_managed_device = {} # The following fetch will always succeed # The result will be an array of all existing managed devices result = self.fetcher.get('managed_device') log('get result %s' % result) for managed_device in result['data']['managed_device']: match = True for get_id_attribute in self.attribute_config['managed_device']['get_id_attributes']: fetched_value = managed_device.get(get_id_attribute) configured_value = self.configured_managed_device.get(get_id_attribute) # Do not compare if it is not defined if configured_value is None: continue # Emulate AND between get_id_attributes if configured_value != fetched_value: match = False if match: self.fetched_managed_device = managed_device log('fetched managed device %s' % self.fetched_managed_device) def managed_device_exists(self): log('ModuleExecutor.managed_device_exists()') if self.fetched_managed_device == {}: return False else: return True def managed_device_identical(self): log('ModuleExecutor.managed_device_identical()') is_identical = True # Compare simple attributes for attribute in self.configured_managed_device: configured_value = self.configured_managed_device.get(attribute) fetched_value = self.fetched_managed_device.get(attribute) if configured_value != fetched_value: is_identical = False str_tuple = (attribute, type(configured_value), configured_value, type(fetched_value), fetched_value) log('Attribute %s differs. configured: (%s) %s fetched: (%s) %s' % str_tuple) return is_identical def create_managed_device(self): log('ModuleExecutor.create_managed_device()') post_data = { 'managed_device': self.configured_managed_device, } log('post data: %s' % post_data) result = self.fetcher.post(post_data=post_data, resource='managed_device', action='add_device') log('result of post: %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result['http_response_data']['status'] self.module.fail_json(msg=msg, **self.module_result) def update_managed_device(self): log('ModuleExecutor.update_managed_device()') put_payload = self.configured_managed_device put_data = { 'managed_device': put_payload } log('request put data: %s' % put_data) id = self.fetched_managed_device['id'] result = self.fetcher.put(put_data=put_data, resource='managed_device', id=id) log('result of put: %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result['http_response_data']['status'] def delete_managed_device(self): log('ModuleExecutor.delete_managed_device()') id = self.fetched_managed_device['id'] result = self.fetcher.delete(resource='managed_device', id=id) log('delete result %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result['http_response_data']['status'] def update_or_create(self): log('ModuleExecutor.update_or_create()') if not self.managed_device_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.create_managed_device() else: if not self.managed_device_identical(): self.module_result['changed'] = True if not self.module.check_mode: self.update_managed_device() # Update with managed device key self.fetch_managed_device() self.module_result['managed_device'] = self.fetched_managed_device def delete(self): log('ModuleExecutor.delete()') if self.managed_device_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.delete_managed_device() def main(self): try: if self.module.params['state'] == 'present': self.update_or_create() elif self.module.params['state'] == 'absent': self.delete() self.module.exit_json(**self.module_result) except NitroException as e: msg = "nitro exception errorcode=%s, message=%s, severity=%s" % (str(e.errorcode), e.message, e.severity) self.module.fail_json(msg=msg, **self.module_result) except Exception as e: msg = 'Exception %s: %s' % (type(e), str(e)) self.module.fail_json(msg=msg, **self.module_result)
class ModuleExecutor(object): def __init__(self, module): self.module = module customer_id = self.module.params.get('customer_id') if customer_id is not None: api_path = 'massvc/%s/provisioning/nitro/v1/config' % customer_id self.nitro_api_fetcher = NitroAPIFetcher(module, api_path=api_path) else: self.nitro_api_fetcher = NitroAPIFetcher(module) self.module_result = dict( changed=False, failed=False, loglines=loglines, ) def profile_exists(self): log('ModuleExecutor.profile_exists()') result = self.nitro_api_fetcher.get(resource="provisioning_profiles", ) log('get result %s' % result) if result['http_response_data']['status'] == 200: for profile in result['data']['provisioning_profiles']: if profile['name'] == self.module.params[ 'provisioning_profile']['name']: return True # Fallthrough return False else: raise Exception('http response code is %s' % result['http_response_data']['status']) def create_provisioning_profile(self): log('ModuleExecutor.create_provisioning_profile()') payload = { 'provisioning_profiles': self.module.params['provisioning_profile'] } log('create profile payload is %s' % payload) result = self.nitro_api_fetcher.post(post_data=payload, resource='provisioning_profiles') log('create profile post result: %s' % result) if result['http_response_data']['status'] not in (200, 201): raise Exception('http response code is %s' % result['http_response_data']['status']) self.provisioning_profile_id = result['data']['provisioning_profiles'][ 0]['id'] log("Provisioning profile id %s" % self.provisioning_profile_id) self.post_instance() def post_instance(self): log('ModuleExecutor.post_instance()') payload = { 'instances': { 'name': self.module.params['provisioning_profile']['name'], 'provisioning_profile_id': self.provisioning_profile_id, } } result = self.nitro_api_fetcher.post(post_data=payload, resource='instances') if result['http_response_data']['status'] != 200: raise Exception('http response code is %s' % result['http_response_data']['status']) self.job_id = result['data']['instance']['job_id'] self.poll_job_id() def poll_job_id(self): log('ModuleExecutor.poll_job_id()') while (True): result = self.nitro_api_fetcher.get( resource='jobs', id=self.job_id, ) log('job poll result: %s' % result) if result['http_response_data']['status'] != 200: raise Exception('http response code is %s' % result['http_response_data']['status']) job_status = result['data']['job']['status'] if job_status == 'failed': raise Exception('job failed') if job_status == 'completed': log('Job completed') return if job_status == 'stalled': if self.module.params['fail_on_stall']: raise Exception('Job stalled') else: log('Job stalled') break if job_status == 'inprogress': log('Job in progress') time.sleep(self.module.params['poll_interval']) def provision_vpx(self): log('ModuleExecutor.provision_vpx()') self.create_provisioning_profile() self.post_instance() self.poll_job_id() def delete_vpx(self): log('ModuleExecutor.delete_vpx()') # Delete is a noop since deletion of provisioning profiles # is not supported on ADM service as of this writing def main(self): try: if self.module.params['state'] == 'present': if not self.profile_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.provision_vpx() elif self.module.params['state'] == 'absent': if self.profile_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.delete_vpx() self.module.exit_json(**self.module_result) except Exception as e: msg = 'Exception %s: %s' % (type(e), str(e)) self.module.fail_json(msg=msg, **self.module_result)
class ModuleExecutor(object): def __init__(self, module): self.module = module self.nitro_api_fetcher = NitroAPIFetcher( module, api_path='stylebook/nitro/v1/config') self.main_nitro_class = 'stylebook' # Dictionary containing attribute information # for each NITRO object utilized by this module self.attribute_config = { 'stylebook': { 'attributes_list': [ 'source', 'namespace', 'version', 'name', 'display_name', ], 'transforms': {}, 'get_id_attributes': [ 'namespace', 'version', 'name', ], 'delete_id_attributes': [ 'namespace', 'version', 'name', ], }, } self.module_result = dict( changed=False, failed=False, loglines=loglines, ) self.calculate_configured_stylebook() self.fetch_stylebook() def calculate_configured_stylebook(self): log('ModuleExecutor.calculate_configured_stylebook()') self.configured_stylebook = {} for attribute in self.attribute_config['stylebook']['attributes_list']: value = self.module.params.get(attribute) # Skip null values if value is None: continue transform = self.attribute_config['stylebook']['transforms'].get( attribute) if transform is not None: value = transform(value) self.configured_stylebook[attribute] = value log('calculated configured stylebook %s' % self.configured_stylebook) def fetch_stylebook(self): log('ModuleExecutor.fetch_stylebook()') resource_tuple = ( self.configured_stylebook['namespace'], self.configured_stylebook['version'], self.configured_stylebook['name'], ) resource = 'stylebooks/%s/%s/%s' % resource_tuple result = self.nitro_api_fetcher.get(resource=resource) log('get result %s' % result) if result['http_response_data']['status'] == 200: self.fetched_stylebook = result['data'].get('stylebook', {}) elif result['http_response_data']['status'] == 400: unexpected_error = True if 'data' in result: if 'error_code' in result['data']: if result['data']['error_code'] == 555: unexpected_error = False self.fetched_stylebook = {} if unexpected_error: self.module.fail_json(msg='Unexpected error during fetch', **self.module_result) else: self.module.fail_json(msg='Unexpected error during fetch', **self.module_result) def stylebook_exists(self): if self.fetched_stylebook != {}: return True else: return False def stylebook_identical(self): log('ModuleExecutor.stylebook_identical()') identical = True for attribute in self.configured_stylebook: if attribute == 'source': continue configured_value = self.configured_stylebook[attribute] fetched_value = self.fetched_stylebook.get(attribute) if configured_value != fetched_value: str_tuple = (attribute, type(configured_value), configured_value, type(fetched_value), fetched_value) log('Attribute %s differs. configured: (%s) %s fetched: (%s) %s' % str_tuple) identical = False if 'source' in self.configured_stylebook: configured_value = self.configured_stylebook['source'] fetched_value = self.fetched_stylebook.get('source') if fetched_value is not None: fetched_value = codecs.decode(base64.b64decode(fetched_value)) str_tuple = ('source', type(configured_value), configured_value, type(fetched_value), fetched_value) if configured_value != fetched_value: log('Attribute %s differs. configured: (%s) %s fetched: (%s) %s' % str_tuple) identical = False return identical def create_stylebook(self): log('ModuleExecutor.create_stylebook()') post_data = {'stylebook': self.configured_stylebook} result = self.nitro_api_fetcher.post(post_data=post_data, resource='stylebooks') log('result of stylebook creation %s' % result) if result['http_response_data']['status'] != 200: message_tuple = ( result['http_response_data']['status'], result['nitro_errorcode'], result['nitro_message'], result['nitro_severity'], ) self.module.fail_json( msg= 'POST http status %s. nitro_errorcode=%s, nitro_message=%s, nitro_severity=%s' % message_tuple, **self.module_result) return result def get_stylebook(self): resource_tuple = ( self.module.params['namespace'], self.module.params['version'], self.module.params['name'], ) resource = 'stylebooks/%s/%s/%s' % resource_tuple result = self.nitro_api_fetcher.get(resource=resource) if result['http_response_data']['status'] != 200: message_tuple = ( result['http_response_data']['status'], result['nitro_errorcode'], result['nitro_message'], result['nitro_severity'], ) msg = 'GET http status %s. nitro_errorcode=%s, nitro_message=%s, nitro_severity=%s' % message_tuple self.module.fail_json(msg=msg, **self.module_result) log('result of get stylebooks %s' % result) stylebooks = result['data']['stylebooks'] if not isinstance(stylebooks, list): msg = 'Unexpected stylebooks result type %s' % type(stylebooks) self.module.fail_json(msg=msg, **self.module_result) if stylebooks == []: self.module.fail_json(msg='Failed to get the created stylebook', **self.module_result) elif len(stylebooks) > 1: self.module.fail_json(msg='Multiple stylebooks were returned', **self.module_result) else: return stylebooks[0] def update_stylebook(self): log('ModuleExecutor.update_stylebook()') self.delete_stylebook() self.create_stylebook() def delete_stylebook(self): # Go on with the deletion resource_tuple = ( self.configured_stylebook['namespace'], self.configured_stylebook['version'], self.configured_stylebook['name'], ) resource = 'stylebooks/%s/%s/%s' % resource_tuple result = self.nitro_api_fetcher.delete(resource=resource) log('result of delete %s' % result) if result['http_response_data']['status'] != 200: message_tuple = ( result['http_response_data']['status'], result['nitro_errorcode'], result['nitro_message'], result['nitro_severity'], ) msg = 'DELETE http status %s. nitro_errorcode=%s, nitro_message=%s, nitro_severity=%s' % message_tuple self.module.fail_json(msg=msg, **self.module_result) def main(self): try: if self.module.params['state'] == 'present': if not self.stylebook_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.create_stylebook() else: if not self.stylebook_identical(): self.module_result['changed'] = True if not self.module.check_mode: self.update_stylebook() elif self.module.params['state'] == 'absent': if self.stylebook_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.delete_stylebook() self.module.exit_json(**self.module_result) except Exception as e: msg = 'Exception %s: %s' % (type(e), str(e)) self.module.fail_json(msg=msg, **self.module_result)
class ModuleExecutor(object): def __init__(self, module): self.module = module self.main_nitro_class = 'rba_policy' self.fetcher = NitroAPIFetcher(module) # Dictionary containing attribute information # for each NITRO object utilized by this module self.attribute_config = { 'rba_policy': { 'attributes_list': [ 'tenant_id', 'statement', 'ui', 'name', 'id', 'description', ], 'transforms': {}, 'get_id_attributes': [ 'name', 'id', ], 'delete_id_attributes': [ 'name', 'id', ], }, } self.module_result = dict( changed=False, failed=False, loglines=loglines, ) self.calculate_configured_rba_policy() self.fetch_rba_policy() def calculate_configured_rba_policy(self): log('ModuleExecutor.calculate_configured_rba_policy()') self.configured_rba_policy = {} for attribute in self.attribute_config['rba_policy'][ 'attributes_list']: value = self.module.params.get(attribute) # Skip null values if value is None: continue transform = self.attribute_config['rba_policy']['transforms'].get( attribute) if transform is not None: value = transform(value) self.configured_rba_policy[attribute] = value log('calculated configured rba_policy %s' % self.configured_rba_policy) def fetch_rba_policy(self): log('ModuleExecutor.fetch_rba_policy()') self.fetched_rba_policy = {} # The following fetch will always succeed # The result will be an array of all existing rba_policies result = self.fetcher.get('rba_policy') log('get result %s' % result) for rba_policy in result['data']['rba_policy']: match = True for get_id_attribute in self.attribute_config['rba_policy'][ 'get_id_attributes']: fetched_value = rba_policy.get(get_id_attribute) configured_value = self.configured_rba_policy.get( get_id_attribute) # Do not compare if it is not defined if configured_value is None: continue # Emulate AND between get_id_attributes if configured_value != fetched_value: match = False if match: self.fetched_rba_policy = rba_policy log('fetched rba_policy %s' % self.fetched_rba_policy) def rba_policy_exists(self): log('ModuleExecutor.rba_policy_exists()') if self.fetched_rba_policy == {}: return False else: return True def element_in_fetched(self, item, fetched): # task configured item keys drive the comparison log('ModuleExecutor.element_in_fetched()') for fetched_item in fetched: identical = True for attribute in item: item_value = item.get(attribute) fetched_value = fetched_item.get(attribute) if item_value != fetched_value: str_tuple = (attribute, type(item_value), item_value, type(fetched_value), fetched_value) # Message is too verbose for normal use # Leaving it commented here for debugging when needed # log('fetched item differs %s item: (%s) %s fetched: (%s) %s' % str_tuple) identical = False break if identical: return True # Fallthrough return False def element_in_configured(self, item, configured): # task configured list item keys drive the comparison log('ModuleExecutor.element_in_configured()') for configured_item in configured: identical = True for attribute in configured_item: item_value = item.get(attribute) configured_value = configured_item.get(attribute) if item_value != configured_value: str_tuple = (attribute, type(item_value), item_value, type(configured_value), configured_value) # Message is too verbose for normal use # Leaving it commented here for debugging when needed # log('configured item differs %s item: (%s) %s configured: (%s) %s' % str_tuple) identical = False break if identical: return True # Fallthrough return False def rba_policy_identical(self): log('ModuleExecutor.rba_policy_identical()') is_identical = True # Compare simple attributes for attribute in self.configured_rba_policy: if attribute in ['ui', 'statement']: continue configured_value = self.configured_rba_policy.get(attribute) fetched_value = self.fetched_rba_policy.get(attribute) if configured_value != fetched_value: is_identical = False str_tuple = (attribute, type(configured_value), configured_value, type(fetched_value), fetched_value) log('Attribute %s differs. configured: (%s) %s fetched: (%s) %s' % str_tuple) # Compare ui and statement elements for item in self.configured_rba_policy['ui']: if not self.element_in_fetched(item, self.fetched_rba_policy['ui']): log('ui element not found in fetched %s' % item) is_identical = False for item in self.configured_rba_policy['statement']: if not self.element_in_fetched( item, self.fetched_rba_policy['statement']): log('statement element not found in fetched %s' % item) is_identical = False for item in self.fetched_rba_policy['ui']: if not self.element_in_configured( item, self.configured_rba_policy['ui']): log('ui element not found in configured %s' % item) is_identical = False for item in self.fetched_rba_policy['statement']: if not self.element_in_configured( item, self.configured_rba_policy['statement']): log('statement element not found in configured %s' % item) is_identical = False return is_identical def create_rba_policy(self): log('ModuleExecutor.create_rba_policy()') post_data = {'rba_policy': self.configured_rba_policy} log('post data: %s' % post_data) result = self.fetcher.post(post_data=post_data, resource='rba_policy') log('result of post: %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result[ 'http_response_data']['status'] self.module.fail_json(msg=msg, **self.module_result) def update_rba_policy(self): log('ModuleExecutor.update_rba_policy()') put_payload = self.configured_rba_policy put_data = {'rba_policy': put_payload} log('request put data: %s' % put_data) id = self.fetched_rba_policy['id'] result = self.fetcher.put(put_data=put_data, resource='rba_policy', id=id) log('result of put: %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result[ 'http_response_data']['status'] def delete_rba_policy(self): log('ModuleExecutor.delete_rba_policy()') id = self.fetched_rba_policy['id'] result = self.fetcher.delete(resource='rba_policy', id=id) log('delete result %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result[ 'http_response_data']['status'] def update_or_create(self): log('ModuleExecutor.update_or_create()') if not self.rba_policy_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.create_rba_policy() else: if not self.rba_policy_identical(): self.module_result['changed'] = True if not self.module.check_mode: self.update_rba_policy() # Update with rba_policy key self.fetch_rba_policy() self.module_result['rba_policy'] = self.fetched_rba_policy def delete(self): log('ModuleExecutor.delete()') if self.rba_policy_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.delete_rba_policy() def main(self): try: if self.module.params['state'] == 'present': self.update_or_create() elif self.module.params['state'] == 'absent': self.delete() self.module.exit_json(**self.module_result) except NitroException as e: msg = "nitro exception errorcode=%s, message=%s, severity=%s" % ( str(e.errorcode), e.message, e.severity) self.module.fail_json(msg=msg, **self.module_result) except Exception as e: msg = 'Exception %s: %s' % (type(e), str(e)) self.module.fail_json(msg=msg, **self.module_result)
class ModuleExecutor(object): def __init__(self, module): self.module = module self.main_nitro_class = 'ns_device_profile' self.fetcher = NitroAPIFetcher(module) # Dictionary containing attribute information # for each NITRO object utilized by this module self.attribute_config = { 'ns_device_profile': { 'attributes_list': [ 'name', 'svm_ns_comm', 'use_global_setting_for_communication_with_ns', 'id', 'type', 'snmpsecurityname', 'snmpauthprotocol', 'ssl_private_key', 'ssl_cert', 'http_port', 'ns_profile_name', 'ssh_port', 'password', 'snmpsecuritylevel', 'snmpcommunity', 'passphrase', 'snmpprivprotocol', 'https_port', 'username', 'host_password', 'max_wait_time_reboot', 'snmpprivpassword', 'snmpversion', 'cb_profile_name', 'snmpauthpassword', 'host_username', ], 'transforms': {}, 'get_id_attributes': [ 'name', ], 'delete_id_attributes': [], }, } self.module_result = dict( changed=False, failed=False, loglines=loglines, ) self.calculate_configured_ns_device_profile() self.fetch_ns_device_profile() def calculate_configured_ns_device_profile(self): log('ModuleExecutor.calculate_configured_ns_device_profile()') self.configured_ns_device_profile = {} for attribute in self.attribute_config['ns_device_profile'][ 'attributes_list']: value = self.module.params.get(attribute) # Skip null values if value is None: continue transform = self.attribute_config['ns_device_profile'][ 'transforms'].get(attribute) if transform is not None: value = transform(value) self.configured_ns_device_profile[attribute] = value log('calculated configured ns_device_profile %s' % self.configured_ns_device_profile) def fetch_ns_device_profile(self): log('ModuleExecutor.fetch_ns_device_profile()') self.fetched_ns_device_profile = {} # The following fetch will always succeed # The result will be an array of all existing profiles result = self.fetcher.get('ns_device_profile') log('get result %s' % result) for ns_device_profile in result['data']['ns_device_profile']: match = True for get_id_attribute in self.attribute_config['ns_device_profile'][ 'get_id_attributes']: fetched_value = ns_device_profile.get(get_id_attribute) configured_value = self.configured_ns_device_profile.get( get_id_attribute) # Do not compare if it is not defined if configured_value is None: continue # Emulate AND between get_id_attributes if configured_value != fetched_value: match = False if match: self.fetched_ns_device_profile = ns_device_profile log('fetched ns_device_profile device %s' % self.fetched_ns_device_profile) def ns_device_profile_exists(self): log('ModuleExecutor.ns_device_profile_exists()') if self.fetched_ns_device_profile == {}: return False else: return True def ns_device_profile_identical(self): log('ModuleExecutor.ns_device_profile_identical()') is_identical = True # Compare simple attributes skip_attributes = [ 'password', 'host_password', 'passphrase', 'snmpprivpassword', 'snmpauthpassword', ] for attribute in self.configured_ns_device_profile: if attribute in skip_attributes: continue configured_value = self.configured_ns_device_profile.get(attribute) fetched_value = self.fetched_ns_device_profile.get(attribute) if configured_value != fetched_value: is_identical = False str_tuple = (attribute, type(configured_value), configured_value, type(fetched_value), fetched_value) log('Attribute %s differs. configured: (%s) %s fetched: (%s) %s' % str_tuple) return is_identical def create_ns_device_profile(self): log('ModuleExecutor.create_ns_device_profile()') post_data = { 'ns_device_profile': self.configured_ns_device_profile, } log('post data: %s' % post_data) result = self.fetcher.post(post_data=post_data, resource='ns_device_profile') log('result of post: %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result[ 'http_response_data']['status'] self.module.fail_json(msg=msg, **self.module_result) def update_ns_device_profile(self): log('ModuleExecutor.update_ns_device_profile()') put_payload = self.configured_ns_device_profile put_data = {'ns_device_profile': put_payload} log('request put data: %s' % put_data) id = self.fetched_ns_device_profile['id'] result = self.fetcher.put(put_data=put_data, resource='ns_device_profile', id=id) log('result of put: %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result[ 'http_response_data']['status'] def delete_ns_device_profile(self): log('ModuleExecutor.delete_ns_device_profile()') id = self.fetched_ns_device_profile['id'] result = self.fetcher.delete(resource='ns_device_profile', id=id) log('delete result %s' % result) if result['http_response_data']['status'] == 200: if result.get('nitro_errorcode') is not None: if result['nitro_errorcode'] != 0: raise NitroException( errorcode=result['nitro_errorcode'], message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) elif 400 <= result['http_response_data']['status'] <= 599: raise NitroException( errorcode=result.get('nitro_errorcode'), message=result.get('nitro_message'), severity=result.get('nitro_severity'), ) else: msg = 'Did not get nitro errorcode and http status was not 200 or 4xx (%s)' % result[ 'http_response_data']['status'] def update_or_create(self): log('ModuleExecutor.update_or_create()') if not self.ns_device_profile_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.create_ns_device_profile() else: if not self.ns_device_profile_identical(): self.module_result['changed'] = True if not self.module.check_mode: self.update_ns_device_profile() # Update with fetched ns device profile key self.fetch_ns_device_profile() self.module_result[ 'ns_device_profile'] = self.fetched_ns_device_profile def delete(self): log('ModuleExecutor.delete()') if self.ns_device_profile_exists(): self.module_result['changed'] = True if not self.module.check_mode: self.delete_ns_device_profile() def main(self): try: if self.module.params['state'] == 'present': self.update_or_create() elif self.module.params['state'] == 'absent': self.delete() self.module.exit_json(**self.module_result) except NitroException as e: msg = "nitro exception errorcode=%s, message=%s, severity=%s" % ( str(e.errorcode), e.message, e.severity) self.module.fail_json(msg=msg, **self.module_result) except Exception as e: msg = 'Exception %s: %s' % (type(e), str(e)) self.module.fail_json(msg=msg, **self.module_result)