コード例 #1
0
ファイル: aos_login.py プロジェクト: ernstp/ansible
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))
コード例 #2
0
    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)
コード例 #3
0
ファイル: apstra_aos.py プロジェクト: awiddersheim/ansible
    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)
コード例 #4
0
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
コード例 #5
0
    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)