def aos_login(module): mod_args = module.params aos = Session(server=mod_args['server'], port=mod_args['port'], user=mod_args['user'], passwd=mod_args['passwd']) try: aos.login() except aosExc.LoginServerUnreachableError: module.fail_json( msg="AOS-server [%s] API not available/reachable, check server" % aos.server) except aosExc.LoginAuthError: module.fail_json(msg="AOS-server login credentials failed") module.exit_json(changed=False, ansible_facts=dict(aos_session=aos.session), aos_session=dict(aos_session=aos.session))
def __init__(self): """ Main execution path """ if not HAS_AOS_PYEZ: raise Exception( 'aos-pyez is not installed. Please see details here: https://github.com/Apstra/aos-pyez' ) if not HAS_ARGPARSE: raise Exception( 'argparse is not installed. Please install the argparse library or upgrade to python-2.7' ) # Initialize inventory self.inventory = dict() # A list of groups and the hosts in that group self.inventory['_meta'] = dict() self.inventory['_meta']['hostvars'] = dict() # Read settings and parse CLI arguments self.read_settings() self.parse_cli_args() # ---------------------------------------------------- # Open session to AOS # ---------------------------------------------------- aos = Session(server=self.aos_server, port=self.aos_server_port, user=self.aos_username, passwd=self.aos_password) aos.login() # Save session information in variables of group all self.add_var_to_group('all', 'aos_session', aos.session) # Add the AOS server itself in the inventory self.add_host_to_group("all", 'aos') self.add_var_to_host("aos", "ansible_ssh_host", self.aos_server) self.add_var_to_host("aos", "ansible_ssh_pass", self.aos_password) self.add_var_to_host("aos", "ansible_ssh_user", self.aos_username) # ---------------------------------------------------- # Build the inventory # 2 modes are supported: device based or blueprint based # - For device based, the list of device is taken from the global device list # the serial ID will be used as the inventory_hostname # - For Blueprint based, the list of device is taken from the given blueprint # the Node name will be used as the inventory_hostname # ---------------------------------------------------- if self.aos_blueprint: bp = aos.Blueprints[self.aos_blueprint] if bp.exists is False: fail("Unable to find the Blueprint: %s" % self.aos_blueprint) for dev_name, dev_id in bp.params['devices'].value.items(): self.add_host_to_group('all', dev_name) device = aos.Devices.find(uid=dev_id) if 'facts' in device.value.keys(): self.add_device_facts_to_var(dev_name, device) # Define admin State and Status if 'user_config' in device.value.keys(): if 'admin_state' in device.value['user_config'].keys(): self.add_var_to_host( dev_name, 'admin_state', device.value['user_config']['admin_state']) self.add_device_status_to_var(dev_name, device) # Go over the contents data structure for node in bp.contents['system']['nodes']: if node['display_name'] == dev_name: self.add_host_to_group(node['role'], dev_name) # Check for additional attribute to import attributes_to_import = [ 'loopback_ip', 'asn', 'role', 'position', ] for attr in attributes_to_import: if attr in node.keys(): self.add_var_to_host(dev_name, attr, node[attr]) # if blueprint_interface is enabled in the configuration # Collect links information if self.aos_blueprint_int: interfaces = dict() for link in bp.contents['system']['links']: # each link has 2 sides [0,1], and it's unknown which one match this device # at first we assume, first side match(0) and peer is (1) peer_id = 1 for side in link['endpoints']: if side['display_name'] == dev_name: # import local information first int_name = side['interface'] # init dict interfaces[int_name] = dict() if 'ip' in side.keys(): interfaces[int_name]['ip'] = side['ip'] if 'interface' in side.keys(): interfaces[int_name]['name'] = side[ 'interface'] if 'display_name' in link['endpoints'][ peer_id].keys(): interfaces[int_name]['peer'] = link[ 'endpoints'][peer_id]['display_name'] if 'ip' in link['endpoints'][peer_id].keys(): interfaces[int_name]['peer_ip'] = link[ 'endpoints'][peer_id]['ip'] if 'type' in link['endpoints'][peer_id].keys(): interfaces[int_name]['peer_type'] = link[ 'endpoints'][peer_id]['type'] else: # if we haven't match the first time, prepare the peer_id # for the second loop iteration peer_id = 0 self.add_var_to_host(dev_name, 'interfaces', interfaces) else: for device in aos.Devices: # If not reacheable, create by key and # If reacheable, create by hostname self.add_host_to_group('all', device.name) # populate information for this host self.add_device_status_to_var(device.name, device) if 'user_config' in device.value.keys(): for key, value in device.value['user_config'].items(): self.add_var_to_host(device.name, key, value) # Based on device status online|offline, collect facts as well if device.value['status']['comm_state'] == 'on': if 'facts' in device.value.keys(): self.add_device_facts_to_var(device.name, device) # Check if device is associated with a blueprint # if it's create a new group if 'blueprint_active' in device.value['status'].keys(): if 'blueprint_id' in device.value['status'].keys(): bp = aos.Blueprints.find( uid=device.value['status']['blueprint_id']) if bp: self.add_host_to_group(bp.name, device.name) # ---------------------------------------------------- # Convert the inventory and return a JSON String # ---------------------------------------------------- data_to_print = "" data_to_print += self.json_format_dict(self.inventory, True) print(data_to_print)
def __init__(self): """ Main execution path """ if not HAS_AOS_PYEZ: raise Exception('aos-pyez is not installed. Please see details here: https://github.com/Apstra/aos-pyez') if not HAS_ARGPARSE: raise Exception('argparse is not installed. Please install the argparse library or upgrade to python-2.7') # Initialize inventory self.inventory = dict() # A list of groups and the hosts in that group self.inventory['_meta'] = dict() self.inventory['_meta']['hostvars'] = dict() # Read settings and parse CLI arguments self.read_settings() self.parse_cli_args() # ---------------------------------------------------- # Open session to AOS # ---------------------------------------------------- aos = Session(server=self.aos_server, port=self.aos_server_port, user=self.aos_username, passwd=self.aos_password) aos.login() # Save session information in variables of group all self.add_var_to_group('all', 'aos_session', aos.session) # Add the AOS server itself in the inventory self.add_host_to_group("all", 'aos') self.add_var_to_host("aos", "ansible_ssh_host", self.aos_server) self.add_var_to_host("aos", "ansible_ssh_pass", self.aos_password) self.add_var_to_host("aos", "ansible_ssh_user", self.aos_username) # ---------------------------------------------------- # Build the inventory # 2 modes are supported: device based or blueprint based # - For device based, the list of device is taken from the global device list # the serial ID will be used as the inventory_hostname # - For Blueprint based, the list of device is taken from the given blueprint # the Node name will be used as the inventory_hostname # ---------------------------------------------------- if self.aos_blueprint: bp = aos.Blueprints[self.aos_blueprint] if bp.exists is False: fail("Unable to find the Blueprint: %s" % self.aos_blueprint) for dev_name, dev_id in bp.params['devices'].value.items(): self.add_host_to_group('all', dev_name) device = aos.Devices.find(uid=dev_id) if 'facts' in device.value.keys(): self.add_device_facts_to_var(dev_name, device) # Define admin State and Status if 'user_config' in device.value.keys(): if 'admin_state' in device.value['user_config'].keys(): self.add_var_to_host(dev_name, 'admin_state', device.value['user_config']['admin_state']) self.add_device_status_to_var(dev_name, device) # Go over the contents data structure for node in bp.contents['system']['nodes']: if node['display_name'] == dev_name: self.add_host_to_group(node['role'], dev_name) # Check for additional attribute to import attributes_to_import = [ 'loopback_ip', 'asn', 'role', 'position', ] for attr in attributes_to_import: if attr in node.keys(): self.add_var_to_host(dev_name, attr, node[attr]) # if blueprint_interface is enabled in the configuration # Collect links information if self.aos_blueprint_int: interfaces = dict() for link in bp.contents['system']['links']: # each link has 2 sides [0,1], and it's unknown which one match this device # at first we assume, first side match(0) and peer is (1) peer_id = 1 for side in link['endpoints']: if side['display_name'] == dev_name: # import local information first int_name = side['interface'] # init dict interfaces[int_name] = dict() if 'ip' in side.keys(): interfaces[int_name]['ip'] = side['ip'] if 'interface' in side.keys(): interfaces[int_name]['name'] = side['interface'] if 'display_name' in link['endpoints'][peer_id].keys(): interfaces[int_name]['peer'] = link['endpoints'][peer_id]['display_name'] if 'ip' in link['endpoints'][peer_id].keys(): interfaces[int_name]['peer_ip'] = link['endpoints'][peer_id]['ip'] if 'type' in link['endpoints'][peer_id].keys(): interfaces[int_name]['peer_type'] = link['endpoints'][peer_id]['type'] else: # if we haven't match the first time, prepare the peer_id # for the second loop iteration peer_id = 0 self.add_var_to_host(dev_name, 'interfaces', interfaces) else: for device in aos.Devices: # If not reacheable, create by key and # If reacheable, create by hostname self.add_host_to_group('all', device.name) # populate information for this host self.add_device_status_to_var(device.name, device) if 'user_config' in device.value.keys(): for key, value in device.value['user_config'].items(): self.add_var_to_host(device.name, key, value) # Based on device status online|offline, collect facts as well if device.value['status']['comm_state'] == 'on': if 'facts' in device.value.keys(): self.add_device_facts_to_var(device.name, device) # Check if device is associated with a blueprint # if it's create a new group if 'blueprint_active' in device.value['status'].keys(): if 'blueprint_id' in device.value['status'].keys(): bp = aos.Blueprints.find(uid=device.value['status']['blueprint_id']) if bp: self.add_host_to_group(bp.name, device.name) # ---------------------------------------------------- # Convert the inventory and return a JSON String # ---------------------------------------------------- data_to_print = "" data_to_print += self.json_format_dict(self.inventory, True) print(data_to_print)
class TestSession(AosPyEzCommonTestCase): """ Test cases to verify the functionality of the Session object, mainly focused around the various login pass/failure cases. """ def setUp(self): self.adapter = requests_mock.Adapter() self.aos = Session(Config.test_server) self.aos.api.requests.mount('http://%s' % Config.test_server, self.adapter) self.adapter.register_uri( 'GET', '/api/versions/api', json=dict(version=Config.test_server_version)) self.adapter.register_uri( 'POST', '/api/user/login', json=dict(token=Config.test_auth_token)) # generally enable the probe step to pass patch.object(self.aos.api, 'probe', return_value=True).start() def test_login_pass(self): self.aos.login() self.assertEquals(self.aos.session, Config.test_session) self.assertEquals(self.aos.token, Config.test_auth_token) self.assertEquals(self.aos.api.version['version'], Config.test_server_version) def test_login_no_server(self): had_server = self.aos.server self.aos.server = None try: self.aos.login() except LoginNoServerError: pass else: self.fail('LoginNoServerError not raised as expected') finally: self.aos.server = had_server def test_login_unreachable_server(self): try: # noinspection PyUnresolvedReferences with patch.object(self.aos.api, 'probe', return_value=False): self.aos.login() except LoginServerUnreachableError: pass else: self.fail('LoginServerUnreachableError not raised as expected') def test_login_bad_credentials(self): self.adapter.register_uri('POST', '/api/user/login', status_code=400) try: self.aos.login() except LoginAuthError: pass else: self.fail('LoginAuthError not raised as expected') # ##### ------------------------------------------------------------------- # ##### resume session test cases # ##### ------------------------------------------------------------------- @staticmethod def validate_token(request, context): context.status_code = [400, 200][int(request.headers['AUTHTOKEN'] == Config.test_auth_token)] return {} def test_login_resume_pass(self): self.adapter.register_uri('GET', '/api/user', json=self.validate_token) self.aos.session = Config.test_session def test_login_resume_bad_token(self): self.adapter.register_uri('GET', '/api/user', json=self.validate_token) try: bad_session = copy(Config.test_session) bad_session['token'] = 'i am a bad token' self.aos.session = bad_session except LoginAuthError: pass else: self.fail('LoginAuthError not raised as expected') def test_login_resume_bad_url(self): self.adapter.register_uri('GET', '/api/user', json=self.validate_token) try: bad_session = copy(Config.test_session) del bad_session['server'] self.aos.session = bad_session except LoginError: pass else: self.fail('LoginError not raised as expected') def test_login_resume_unreachable_server(self): self.adapter.register_uri('GET', '/api/user', json=self.validate_token) try: with patch.object(self.aos.api, 'probe', return_value=False): self.aos.session = Config.test_session except LoginServerUnreachableError: pass else: self.fail('LoginServerUnreachableError not raised as expected') # ##### ------------------------------------------------------------------- # ##### test probing against real target # ##### ------------------------------------------------------------------- def test_probe_real_target_ok(self): test_target = Session.Api() test_target.set_url(server='www.google.com', port=80) self.assertTrue(test_target.probe()) def test_probe_real_target_fail(self): test_target = Session.Api() test_target.set_url(server='www.google.com', port=81) self.assertFalse(test_target.probe()) # ##### ------------------------------------------------------------------- # ##### test misc properties # ##### ------------------------------------------------------------------- def test_property_token_missing(self): try: _ = self.aos.token except NoLoginError: pass else: self.assertTrue( False, msg='NoLoginError not raised as expected') def test_property_token_ok(self): self.aos.login() self.assertEquals(self.aos.token, Config.test_auth_token) def test_property_url_missing(self): try: _ = self.aos.url except NoLoginError: pass else: self.assertTrue( False, msg='NoLoginError not raised as expected') def test_property_url_ok(self): self.aos.login() _ = self.aos.url
def __init__(self): """ Main execution path """ if not HAS_AOS_PYEZ: raise Exception( 'aos-pyez is not installed. Please see details here: https://github.com/Apstra/aos-pyez' ) # Initialize inventory self.inventory = dict() # A list of groups and the hosts in that group self.inventory['_meta'] = dict() self.inventory['_meta']['hostvars'] = dict() # Read settings and parse CLI arguments self.read_settings() self.parse_cli_args() # ---------------------------------------------------- # Open session to AOS # ---------------------------------------------------- aos = Session(server=self.aos_server, port=self.aos_server_port, user=self.aos_username, passwd=self.aos_password) aos.login() # ---------------------------------------------------- # Build the inventory # ---------------------------------------------------- for device in aos.Devices: # If not reacheable, create by key and # If reacheable, create by hostname self.add_host_to_group('all', device.name) # populate information for this host if 'status' in device.value.keys(): for key, value in device.value['status'].items(): self.add_var_to_host(device.name, key, value) if 'user_config' in device.value.keys(): for key, value in device.value['user_config'].items(): self.add_var_to_host(device.name, key, value) # Based on device status online|offline, collect facts as well if device.value['status']['comm_state'] == 'on': if 'facts' in device.value.keys(): # Populate variables for this host self.add_var_to_host(device.name, 'ansible_ssh_host', device.value['facts']['mgmt_ipaddr']) # self.add_host_to_group('all', device.name) for key, value in device.value['facts'].items(): self.add_var_to_host(device.name, key, value) if key == 'os_family': self.add_host_to_group(value, device.name) elif key == 'hw_model': self.add_host_to_group(value, device.name) # Check if device is associated with a blueprint # if it's create a new group if 'blueprint_active' in device.value['status'].keys(): if 'blueprint_id' in device.value['status'].keys(): bp = aos.Blueprints.find( method='id', key=device.value['status']['blueprint_id']) if bp: self.add_host_to_group(bp['display_name'], device.name) # ---------------------------------------------------- # Convert the inventory and return a JSON String # ---------------------------------------------------- data_to_print = "" data_to_print += self.json_format_dict(self.inventory, True) print(data_to_print)