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(): 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 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 ns_device_profile_exists(self): log('ModuleExecutor.ns_device_profile_exists()') if self.fetched_ns_device_profile == {}: return False else: return True
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 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 managed_device_exists(self): log('ModuleExecutor.managed_device_exists()') if self.fetched_managed_device == {}: return False else: return True
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 rba_policy_exists(self): log('ModuleExecutor.rba_policy_exists()') if self.fetched_rba_policy == {}: return False else: return True
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 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 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 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 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 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 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 poll_instances(module, module_result): log('poll_instances') # Process HTTP headers http_headers = {} http_headers['Content-Type'] = 'application/json' nitro_auth_token = module.params.get('nitro_auth_token') if nitro_auth_token is not None: http_headers['Cookie'] = "SESSID=%s" % nitro_auth_token nitro_user = module.params.get('nitro_user') if nitro_user is not None: http_headers['X-NITRO-USER'] = nitro_user nitro_pass = module.params.get('nitro_pass') if nitro_pass is not None: http_headers['X-NITRO-PASS'] = nitro_pass url = '%s://%s/nitro/v2/config/ns_emon_poll_policy' % ( module.params['nitro_protocol'], module.params['nsip'], ) poll_payload = { 'params': { 'action': 'do_poll' }, 'ns_emon_poll_policy': {}, } r, info = fetch_url( module, url=url, headers=http_headers, data=module.jsonify(poll_payload), method='POST', ) log('info: %s' % info) # Anything but a 200 is an error status = info.get('status') http_msg = info.get('msg') if status != 200: msg = 'Poll instances failure. HTTP status %s, msg: %s' % (status, http_msg) module.fail_json(msg=msg, **module_result)
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 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 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 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 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 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 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 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 poll_instances(self): log('poll_instances') url = '%s://%s/nitro/v2/config/ns_emon_poll_policy' % ( self.module.params['nitro_protocol'], self.module.params['nsip'], ) poll_payload = { 'params': { 'action': 'do_poll' }, 'ns_emon_poll_policy': {}, } r, info = fetch_url( self.module, url=url, headers=self.http_headers, data=self.module.jsonify(poll_payload), method='POST', ) log('r: %s' % r.read()) log('info: %s' % info) # Anything but a 200 is an error status = info.get('status') http_msg = info.get('msg') if status != 200: msg = 'Poll instances failure. HTTP status %s, msg: %s' % ( status, http_msg) self.module.fail_json(msg=msg, **self.module_result)
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 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 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 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