Beispiel #1
0
    def reserve_authority_member(self):
        """Reserves the next available authority member.

        Find the next available authority member and reserve it, then
        update mapping metadata and load managers if the authority member is
        CPM.
        :return: None
        """
        session = self.context.session
        network_view = self.mapping.network_view
        authority_member = None

        # get next available member
        if self.grid_config.dhcp_support is False:
            authority_member = dbi.get_next_authority_member_for_ipam(
                session, self.grid_id)
        else:
            # as default, authority member is 'GM'
            gm_member = utils.find_one_in_list('member_type',
                                               const.MEMBER_TYPE_GRID_MASTER,
                                               self.discovered_grid_members)
            authority_member = gm_member

            cp_member = utils.find_one_in_list('member_type',
                                               const.MEMBER_TYPE_CP_MEMBER,
                                               self.discovered_grid_members)
            if self.grid_config.is_cloud_wapi and cp_member:
                authority_member = dbi.get_next_authority_member_for_dhcp(
                    session, self.grid_id)
                if not authority_member:
                    # if no CPM available, use GM
                    authority_member = gm_member

        if not authority_member:
            raise exc.InfobloxCannotReserveAuthorityMember(
                network_view=network_view)

        # create network view mapping and update mapping
        dns_view = self._get_dns_view()
        # network_view_id will be updated with nios object id once the network
        # view is created
        network_view_id = utils.get_hash()
        dbi.add_network_view(session,
                             network_view_id,
                             network_view,
                             self.grid_id,
                             authority_member.member_id,
                             False,
                             dns_view,
                             network_view,
                             dns_view,
                             True,
                             False)
        self.mapping.network_view_id = network_view_id
        self.mapping.authority_member = authority_member
        self.mapping.dns_view = dns_view

        # change connector if authority member is changed.
        if self.connector.host != self.mapping.authority_member.member_wapi:
            self._load_managers()
    def reserve_authority_member(self):
        """Reserves the next available authority member.

        Find the next available authority member and reserve it, then
        update mapping metadata and load managers if the authority member is
        CPM.
        :return: None
        """
        session = self.context.session
        network_view = self.mapping.network_view
        authority_member = None

        # get next available member
        if self.grid_config.dhcp_support is False:
            authority_member = dbi.get_next_authority_member_for_ipam(
                session, self.grid_id)
        else:
            # as default, authority member is 'GM'
            gm_member = utils.find_one_in_list('member_type',
                                               const.MEMBER_TYPE_GRID_MASTER,
                                               self.discovered_grid_members)
            authority_member = gm_member

            cp_member = utils.find_one_in_list('member_type',
                                               const.MEMBER_TYPE_CP_MEMBER,
                                               self.discovered_grid_members)
            if self.grid_config.is_cloud_wapi and cp_member:
                authority_member = dbi.get_next_authority_member_for_dhcp(
                    session, self.grid_id)
                if not authority_member:
                    # if no CPM available, use GM
                    authority_member = gm_member

        if not authority_member:
            raise exc.InfobloxCannotReserveAuthorityMember(
                network_view=network_view)

        # create network view mapping and update mapping
        dns_view = self._get_dns_view()
        # network_view_id will be updated with nios object id once the network
        # view is created
        network_view_id = utils.get_hash()
        dbi.add_network_view(session,
                             network_view_id,
                             network_view,
                             self.grid_id,
                             authority_member.member_id,
                             False,
                             dns_view,
                             network_view,
                             dns_view,
                             True,
                             False)
        self.mapping.network_view_id = network_view_id
        self.mapping.authority_member = authority_member
        self.mapping.dns_view = dns_view

        # change connector if authority member is changed.
        if self.connector.host != self.mapping.authority_member.member_wapi:
            self._load_managers()
Beispiel #3
0
 def _get_authority_member(self, authority_member_id=None):
     if authority_member_id is None:
         netview_row = utils.find_one_in_list('id',
                                              self.mapping.network_view_id,
                                              self.discovered_network_views)
         authority_member_id = netview_row.authority_member_id
     member = utils.find_one_in_list('member_id', authority_member_id,
                                     self.discovered_grid_members)
     return member
 def _get_authority_member(self, authority_member_id=None):
     if authority_member_id is None:
         netview_row = utils.find_one_in_list('id',
                                              self.mapping.network_view_id,
                                              self.discovered_network_views)
         authority_member_id = netview_row.authority_member_id
     member = utils.find_one_in_list('member_id',
                                     authority_member_id,
                                     self.discovered_grid_members)
     return member
Beispiel #5
0
    def test_network_view_management(self):
        # prepare grid
        self._create_default_grid()

        # prepare members
        self._create_simple_members()
        db_members = infoblox_db.get_members(self.ctx.session)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)

        # should be no network views
        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        self.assertEqual(0, len(db_network_views))

        # test network view additions
        netview_dict = {
            'default': gm_member.member_id,
            'hs-view-1': gm_member.member_id,
            'hs-view-2': gm_member.member_id,
            'hs-view-3': gm_member.member_id
        }
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        actual_rows = utils.get_values_from_records('network_view',
                                                    db_network_views)
        self.assertEqual(netview_dict.keys(), actual_rows)

        # test network view removals
        # - remove 'hs-view-1', 'hs-view-2'
        removing_list = [netview_dict['hs-view-1'], netview_dict['hs-view-2']]
        infoblox_db.remove_network_views_by_names(self.ctx.session,
                                                  removing_list, self.grid_id)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        actual_rows = utils.get_values_from_records('network_view',
                                                    db_network_views)
        actual_set = set(actual_rows)
        expected_set = set(netview_dict.keys()).difference(removing_list)
        self.assertEqual(expected_set, actual_set)

        # - remove 'hs-view-3'
        removing_netview_name = 'hs-view-3'
        removing_netview = utils.find_one_in_list('network_view',
                                                  removing_netview_name,
                                                  db_network_views)
        removing_netview_id = removing_netview.id
        infoblox_db.remove_network_views(self.ctx.session,
                                         [removing_netview_id])

        actual_network_views = infoblox_db.get_network_views(
            self.ctx.session, network_view=removing_netview_name)
        self.assertEqual([], actual_network_views)
    def test_network_view_mapping_conditions_with_single_scope(self):
        user_id = 'test user'
        tenant_id = 'test-tenant'

        # prepare network
        network_name = 'Test Network'
        network = self.plugin_stub.create_network(tenant_id, network_name)

        # prepare subnet with cidr tat is not used in mapping conditions
        subnet_name = 'Test Subnet'
        subnet_cidr = '10.0.0.0/24'
        subnet = self.plugin_stub.create_subnet(tenant_id, subnet_name,
                                                network['id'], subnet_cidr)

        # make sure that no subnet cidr is used in mapping conditions
        db_conditions = dbi.get_mapping_conditions(
            self.ctx.session,
            grid_id=self.grid_id,
            neutron_object_value=subnet_cidr)
        self.assertEqual([], db_conditions)

        # check default network view when no mapping condition matches
        self.assertEqual('Single',
                         self.grid_config.default_network_view_scope)
        self.assertEqual('default', self.grid_config.default_network_view)

        # test default mapping as 'Single'
        ib_cxt = ib_context.InfobloxContext(self.ctx, user_id, network, subnet,
                                            self.grid_config, self.plugin)
        ib_cxt.connector = mock.Mock()
        ib_cxt.ibom = mock.Mock()
        ib_cxt.ip_allocator = mock.Mock()

        # verify that 'default' view is used
        db_netviews = dbi.get_network_views(self.ctx.session,
                                            grid_id=self.grid_id)
        netview_row = utils.find_one_in_list('network_view', 'default',
                                             db_netviews)
        expected_netview_id = netview_row.id

        db_grid_members = dbi.get_members(self.ctx.session,
                                          grid_id=self.grid_id)
        member_row = utils.find_one_in_list('member_type', 'GM',
                                            db_grid_members)
        expected_member_name = member_row.member_name

        self.assertEqual(expected_netview_id,
                         ib_cxt.mapping.network_view_id)
        self.assertEqual('default',
                         ib_cxt.mapping.network_view)
        self.assertEqual(expected_member_name,
                         ib_cxt.mapping.authority_member.member_name)
Beispiel #7
0
    def test_network_view_mapping_conditions_with_single_scope(self):
        user_id = 'test user'
        tenant_id = 'test-tenant'

        # prepare network
        network_name = 'Test Network'
        network = self.plugin_stub.create_network(tenant_id, network_name)

        # prepare subnet with cidr tat is not used in mapping conditions
        subnet_name = 'Test Subnet'
        subnet_cidr = '10.0.0.0/24'
        subnet = self.plugin_stub.create_subnet(tenant_id, subnet_name,
                                                network['id'], subnet_cidr)

        # make sure that no subnet cidr is used in mapping conditions
        db_conditions = dbi.get_mapping_conditions(
            self.ctx.session,
            grid_id=self.grid_id,
            neutron_object_value=subnet_cidr)
        self.assertEqual([], db_conditions)

        # check default network view when no mapping condition matches
        self.assertEqual('Single',
                         self.grid_config.default_network_view_scope)
        self.assertEqual('default', self.grid_config.default_network_view)

        # test default mapping as 'Single'
        ib_cxt = self._get_ib_context(user_id, network, subnet)
        ib_cxt.connector = mock.Mock()
        ib_cxt.ibom = mock.Mock()
        ib_cxt.ip_allocator = mock.Mock()

        # verify that 'default' view is used
        db_netviews = dbi.get_network_views(self.ctx.session,
                                            grid_id=self.grid_id)
        netview_row = utils.find_one_in_list('network_view', 'default',
                                             db_netviews)
        expected_netview_id = netview_row.id

        db_grid_members = dbi.get_members(self.ctx.session,
                                          grid_id=self.grid_id)
        member_row = utils.find_one_in_list('member_type', 'GM',
                                            db_grid_members)
        expected_member_name = member_row.member_name

        self.assertEqual(expected_netview_id,
                         ib_cxt.mapping.network_view_id)
        self.assertEqual('default',
                         ib_cxt.mapping.network_view)
        self.assertEqual(expected_member_name,
                         ib_cxt.mapping.authority_member.member_name)
    def test_network_view_management(self):
        # prepare grid
        self._create_default_grid()

        # prepare members
        self._create_simple_members()
        db_members = infoblox_db.get_members(self.ctx.session)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)

        # should be no network views
        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        self.assertEqual(0, len(db_network_views))

        # test network view additions
        netview_dict = {'default': gm_member.member_id,
                        'hs-view-1': gm_member.member_id,
                        'hs-view-2': gm_member.member_id,
                        'hs-view-3': gm_member.member_id}
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        actual_rows = utils.get_values_from_records('network_view',
                                                    db_network_views)
        self.assertEqual(netview_dict.keys(), actual_rows)

        # test network view removals
        # - remove 'hs-view-1', 'hs-view-2'
        removing_list = [netview_dict['hs-view-1'], netview_dict['hs-view-2']]
        infoblox_db.remove_network_views_by_names(self.ctx.session,
                                                  removing_list,
                                                  self.grid_id)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        actual_rows = utils.get_values_from_records('network_view',
                                                    db_network_views)
        actual_set = set(actual_rows)
        expected_set = set(netview_dict.keys()).difference(removing_list)
        self.assertEqual(expected_set, actual_set)

        # - remove 'hs-view-3'
        removing_netview_name = 'hs-view-3'
        removing_netview = utils.find_one_in_list('network_view',
                                                  removing_netview_name,
                                                  db_network_views)
        removing_netview_id = removing_netview.id
        infoblox_db.remove_network_views(self.ctx.session,
                                         [removing_netview_id])

        actual_network_views = infoblox_db.get_network_views(
            self.ctx.session, network_view=removing_netview_name)
        self.assertEqual([], actual_network_views)
Beispiel #9
0
    def test_find_one_in_list(self):
        self.assertRaises(ValueError, utils.find_one_in_list, None, None, None)
        self.assertEqual(None, utils.find_one_in_list('key', None, []))
        self.assertEqual(None, utils.find_one_in_list('key', 'val', []))

        search_list = [{'key1': 'val1', 'key2': 'val2', 'key3': True},
                       {'key1': 'val11', 'key2': 'val22', 'key3': False}]

        expected = None
        actual = utils.find_one_in_list('key2', 'val33', search_list)
        self.assertEqual(expected, actual)

        expected = {'key1': 'val11', 'key2': 'val22', 'key3': False}
        actual = utils.find_one_in_list('key2', 'val22', search_list)
        self.assertEqual(expected, actual)
    def _validate_mapping_conditions(self, network_view_json):
        db_network_views = dbi.get_network_views(self.ctx.session)
        db_mapping_conditions = dbi.get_mapping_conditions(self.ctx.session)

        expected_conditions = dict((nv['name'], nv['extattrs'])
                                   for nv in network_view_json
                                   if nv['extattrs'])
        expected_condition_rows = []
        for netview in expected_conditions:
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 db_network_views)
            netview_id = netview_row.id
            for condition_name in expected_conditions[netview]:
                if 'Mapping' not in condition_name:
                    continue
                values = expected_conditions[netview][condition_name]['value']
                if not isinstance(values, list):
                    expected_condition_rows.append(netview_id + DELIMITER +
                                                   condition_name + DELIMITER +
                                                   values)
                    continue
                for value in values:
                    expected_condition_rows.append(netview_id + DELIMITER +
                                                   condition_name + DELIMITER +
                                                   value)

        actual_condition_rows = utils.get_composite_values_from_records(
            ['network_view_id', 'neutron_object_name', 'neutron_object_value'],
            db_mapping_conditions)
        self.assertEqual(set(expected_condition_rows),
                         set(actual_condition_rows))
Beispiel #11
0
    def update_port_sync(self, port):
        if not port or not port.get('fixed_ips'):
            return

        session = self.ib_cxt.context.session

        for fip in port['fixed_ips']:
            subnet_id = fip['subnet_id']
            ip_address = fip['ip_address']

            netview_mappings = dbi.get_network_view_mappings(
                session,
                network_id=port['network_id'],
                subnet_id=subnet_id)
            if netview_mappings:
                netview_row = utils.find_one_in_list(
                    'id', netview_mappings[0].network_view_id,
                    self.ib_cxt.discovered_network_views)
                network_view = netview_row.network_view

                port_tenant_name = self.ib_cxt.get_tenant_name(
                    port['tenant_id'])
                ea_ip_address = eam.get_ea_for_ip(self.ib_cxt.user_id,
                                                  port['tenant_id'],
                                                  port_tenant_name,
                                                  network_view,
                                                  port['id'],
                                                  port['device_id'],
                                                  port['device_owner'])
                self.ib_cxt.ibom.update_fixed_address_eas(network_view,
                                                          ip_address,
                                                          ea_ip_address)
Beispiel #12
0
    def update_port_sync(self, port):
        if not port or not port.get('fixed_ips'):
            return

        session = self.ib_cxt.context.session

        for fip in port['fixed_ips']:
            subnet_id = fip['subnet_id']
            ip_address = fip['ip_address']

            netview_mappings = dbi.get_network_view_mappings(
                session, network_id=port['network_id'], subnet_id=subnet_id)
            if netview_mappings:
                netview_row = utils.find_one_in_list(
                    'id', netview_mappings[0].network_view_id,
                    self.ib_cxt.discovered_network_views)
                network_view = netview_row.network_view

                port_tenant_name = self.ib_cxt.get_tenant_name(
                    port['tenant_id'])
                ea_ip_address = eam.get_ea_for_ip(self.ib_cxt.user_id,
                                                  port['tenant_id'],
                                                  port_tenant_name,
                                                  network_view, port['id'],
                                                  port['device_id'],
                                                  port['device_owner'])
                self.ib_cxt.ibom.update_fixed_address_eas(
                    network_view, ip_address, ea_ip_address)
Beispiel #13
0
    def _validate_mapping_conditions(self, network_view_json):
        db_network_views = dbi.get_network_views(self.ctx.session)
        db_mapping_conditions = dbi.get_mapping_conditions(self.ctx.session)

        expected_conditions = dict((nv['name'], nv['extattrs'])
                                   for nv in network_view_json
                                   if nv['extattrs'])
        expected_condition_rows = []
        for netview in expected_conditions:
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 db_network_views)
            netview_id = netview_row.id
            for condition_name in expected_conditions[netview]:
                if 'Mapping' not in condition_name:
                    continue
                values = expected_conditions[netview][condition_name]['value']
                if not isinstance(values, list):
                    expected_condition_rows.append(netview_id + DELIMITER +
                                                   condition_name + DELIMITER +
                                                   values)
                    continue
                for value in values:
                    expected_condition_rows.append(netview_id + DELIMITER +
                                                   condition_name + DELIMITER +
                                                   value)

        actual_condition_rows = utils.get_composite_values_from_records(
            ['network_view_id', 'neutron_object_name', 'neutron_object_value'],
            db_mapping_conditions)
        self.assertEqual(set(expected_condition_rows),
                         set(actual_condition_rows))
    def test_network_view_mapping_conditions_with_tenant_id_condition(self):
        user_id = 'test user'
        tenant_id = '80afaaba012acb9c12888128d5123a09'

        # prepare network
        network_name = 'Test Network'
        network = self.plugin_stub.create_network(tenant_id, network_name)

        # prepare subnet with cidr tat is not used in mapping conditions
        subnet_name = 'Test Subnet'
        subnet_cidr = '10.0.0.0/24'
        subnet = self.plugin_stub.create_subnet(tenant_id, subnet_name,
                                                network['id'], subnet_cidr)

        # make sure that no subnet cidr is used in mapping conditions
        db_conditions = dbi.get_mapping_conditions(
            self.ctx.session,
            grid_id=self.grid_id,
            neutron_object_value=subnet_cidr)
        self.assertEqual([], db_conditions)

        # make sure that tenant id is used in mapping condition once
        db_conditions = dbi.get_mapping_conditions(
            self.ctx.session,
            grid_id=self.grid_id,
            neutron_object_value=tenant_id)
        self.assertEqual(1, len(db_conditions))

        # test mapping where tenant id mapping is found
        ib_cxt = ib_context.InfobloxContext(self.ctx, user_id, network, subnet,
                                            self.grid_config, self.plugin)
        ib_cxt.connector = mock.Mock()
        ib_cxt.ibom = mock.Mock()
        ib_cxt.ip_allocator = mock.Mock()

        # validate the mapping network view
        expected_netview_id = db_conditions[0].network_view_id
        db_netviews = dbi.get_network_views(self.ctx.session,
                                            grid_id=self.grid_id)
        netview_row = utils.find_one_in_list('id', expected_netview_id,
                                             db_netviews)
        expected_netview = netview_row.network_view

        db_mapping_members = dbi.get_mapping_members(self.ctx.session,
                                                     expected_netview_id,
                                                     grid_id=self.grid_id)
        expected_member_id = db_mapping_members[0].member_id

        self.assertEqual(expected_netview_id,
                         ib_cxt.mapping.network_view_id)
        self.assertEqual(expected_netview,
                         ib_cxt.mapping.network_view)
        self.assertEqual(expected_member_id,
                         ib_cxt.mapping.authority_member.member_id)
 def _get_delegated_member(self, network_dict):
     delegated_member = None
     if (network_dict.get('cloud_info') and
             network_dict['cloud_info'].get('delegated_member')):
         delegated_member_name = (
             network_dict['cloud_info']['delegated_member']['name'])
         delegated_member = utils.find_one_in_list(
             'member_name', delegated_member_name, self.db_members)
         if not delegated_member:
             raise exc.InfobloxCannotFindMember(
                 member=delegated_member_name)
     return delegated_member
Beispiel #16
0
    def test_network_view_mapping_conditions_with_tenant_id_condition(self):
        user_id = 'test user'
        tenant_id = '80afaaba012acb9c12888128d5123a09'

        # prepare network
        network_name = 'Test Network'
        network = self.plugin_stub.create_network(tenant_id, network_name)

        # prepare subnet with cidr tat is not used in mapping conditions
        subnet_name = 'Test Subnet'
        subnet_cidr = '10.0.0.0/24'
        subnet = self.plugin_stub.create_subnet(tenant_id, subnet_name,
                                                network['id'], subnet_cidr)

        # make sure that no subnet cidr is used in mapping conditions
        db_conditions = dbi.get_mapping_conditions(
            self.ctx.session,
            grid_id=self.grid_id,
            neutron_object_value=subnet_cidr)
        self.assertEqual([], db_conditions)

        # make sure that tenant id is used in mapping condition once
        db_conditions = dbi.get_mapping_conditions(
            self.ctx.session,
            grid_id=self.grid_id,
            neutron_object_value=tenant_id)
        self.assertEqual(1, len(db_conditions))

        # test mapping where tenant id mapping is found
        ib_cxt = self._get_ib_context(user_id, network, subnet)
        ib_cxt.connector = mock.Mock()
        ib_cxt.ibom = mock.Mock()
        ib_cxt.ip_allocator = mock.Mock()

        # validate the mapping network view
        expected_netview_id = db_conditions[0].network_view_id
        db_netviews = dbi.get_network_views(self.ctx.session,
                                            grid_id=self.grid_id)
        netview_row = utils.find_one_in_list('id', expected_netview_id,
                                             db_netviews)
        expected_netview = netview_row.network_view

        db_mapping_members = dbi.get_mapping_members(self.ctx.session,
                                                     expected_netview_id,
                                                     grid_id=self.grid_id)
        expected_member_id = db_mapping_members[0].member_id

        self.assertEqual(expected_netview_id,
                         ib_cxt.mapping.network_view_id)
        self.assertEqual(expected_netview,
                         ib_cxt.mapping.network_view)
        self.assertEqual(expected_member_id,
                         ib_cxt.mapping.authority_member.member_id)
Beispiel #17
0
 def _get_delegated_member(self, network_dict):
     delegated_member = None
     if (network_dict.get('cloud_info')
             and network_dict['cloud_info'].get('delegated_member')):
         delegated_member_name = (
             network_dict['cloud_info']['delegated_member']['name'])
         delegated_member = utils.find_one_in_list('member_name',
                                                   delegated_member_name,
                                                   self.db_members)
         if not delegated_member:
             raise exc.InfobloxCannotFindMember(
                 member=delegated_member_name)
     return delegated_member
Beispiel #18
0
    def _reserve_dhcp_member(self):
        # for CPM, the authority member itself serves DHCP
        if (self.mapping.authority_member.member_type ==
                const.MEMBER_TYPE_CP_MEMBER):
            return self.mapping.authority_member

        # for GM,
        # check if a network view is already serving dhcp.
        #   if true, then use the same dhcp member.
        #   if false, see if gm itself is serving dhcp for other network view.
        #     if true, then try to get the next available dhcp member.
        #     if false, use gm for dhcp
        session = self.context.session
        dhcp_member = None

        dhcp_service_members = dbi.get_service_members(
            session,
            network_view_id=self.mapping.network_view_id,
            service=const.SERVICE_TYPE_DHCP)
        if dhcp_service_members:
            dhcp_member = utils.find_one_in_list(
                'member_id',
                dhcp_service_members[0].member_id,
                self.discovered_grid_members)
        else:
            if self.grid_config.use_grid_master_for_dhcp:
                dhcp_service_members = dbi.get_service_members(
                    session,
                    member_id=self.mapping.authority_member.member_id,
                    service=const.SERVICE_TYPE_DHCP)
                if dhcp_service_members:
                    # authority is GM, a dhcp member needs to be selected.
                    dhcp_member = dbi.get_next_dhcp_member(session,
                                                           self.grid_id, True)
                    if not dhcp_member:
                        raise exc.InfobloxDHCPMemberNotReserved(
                            network_view=self.mapping.network_view,
                            cidr=self.subnet.get('cidr'))
                else:
                    dhcp_member = self.mapping.authority_member
            else:
                dhcp_member = dbi.get_next_dhcp_member(session,
                                                       self.grid_id, False)
                if not dhcp_member:
                    raise exc.InfobloxDHCPMemberNotReserved(
                        network_view=self.mapping.network_view,
                        cidr=self.subnet.get('cidr'))

        return dhcp_member
    def _reserve_dhcp_member(self):
        # for CPM, the authority member itself serves DHCP
        if (self.mapping.authority_member.member_type ==
                const.MEMBER_TYPE_CP_MEMBER):
            return self.mapping.authority_member

        # for GM,
        # check if a network view is already serving dhcp.
        #   if true, then use the same dhcp member.
        #   if false, see if gm itself is serving dhcp for other network view.
        #     if true, then try to get the next available dhcp member.
        #     if false, use gm for dhcp
        session = self.context.session
        dhcp_member = None

        dhcp_service_members = dbi.get_service_members(
            session,
            network_view_id=self.mapping.network_view_id,
            service=const.SERVICE_TYPE_DHCP)
        if dhcp_service_members:
            dhcp_member = utils.find_one_in_list(
                'member_id',
                dhcp_service_members[0].member_id,
                self.discovered_grid_members)
        else:
            if self.grid_config.use_grid_master_for_dhcp:
                dhcp_service_members = dbi.get_service_members(
                    session,
                    member_id=self.mapping.authority_member.member_id,
                    service=const.SERVICE_TYPE_DHCP)
                if dhcp_service_members:
                    # authority is GM, a dhcp member needs to be selected.
                    dhcp_member = dbi.get_next_dhcp_member(session,
                                                           self.grid_id, True)
                    if not dhcp_member:
                        raise exc.InfobloxDHCPMemberNotReserved(
                            network_view=self.mapping.network_view,
                            cidr=self.subnet.get('cidr'))
                else:
                    dhcp_member = self.mapping.authority_member
            else:
                dhcp_member = dbi.get_next_dhcp_member(session,
                                                       self.grid_id, False)
                if not dhcp_member:
                    raise exc.InfobloxDHCPMemberNotReserved(
                        network_view=self.mapping.network_view,
                        cidr=self.subnet.get('cidr'))

        return dhcp_member
    def test_network_view_mapping_conditions_with_subnet_cidr_condition(self):
        user_id = 'test user'
        tenant_id = '90fbad5a098a4b7cb98826128d5b40b3'

        # prepare network
        network_name = 'Test Network'
        network = self.plugin_stub.create_network(tenant_id, network_name)

        # prepare subnet with cidr used in mapping conditions
        subnet_name = 'Test Subnet'
        subnet_cidr = '12.12.2.0/24'
        subnet = self.plugin_stub.create_subnet(tenant_id, subnet_name,
                                                network['id'], subnet_cidr)

        # make sure that mapping condition exists and prepare expectations
        db_conditions = dbi.get_mapping_conditions(
            self.ctx.session,
            grid_id=self.grid_id,
            neutron_object_value=subnet_cidr)
        self.assertEqual(1, len(db_conditions))
        expected_network_view_id = db_conditions[0].network_view_id

        db_network_views = dbi.get_network_views(self.ctx.session,
                                                 grid_id=self.grid_id)
        expected_netview_row = utils.find_one_in_list(
            'id', expected_network_view_id, db_network_views)
        expected_authority_member_id = expected_netview_row.authority_member_id
        expected_network_view = expected_netview_row.network_view

        # prepare network view mapping to neutron network and subnet
        dbi.associate_network_view(
            self.ctx.session, expected_network_view_id, network['id'],
            subnet['id'])

        # test mapping where both tenant id and tenant cidr match
        ib_cxt = ib_context.InfobloxContext(self.ctx, user_id, network, subnet,
                                            self.grid_config, self.plugin)
        ib_cxt.connector = mock.Mock()
        ib_cxt.ibom = mock.Mock()
        ib_cxt.ip_allocator = mock.Mock()

        # validate mapping
        self.assertEqual(expected_network_view_id,
                         ib_cxt.mapping.network_view_id)
        self.assertEqual(expected_network_view,
                         ib_cxt.mapping.network_view)
        self.assertEqual(expected_authority_member_id,
                         ib_cxt.mapping.authority_member.member_id)
    def _get_dns_view(self):
        """Return dns view name.

        The following matrix describes all the dns view naming rule.

        | Network View Name | Grid Config DNS View Name | Final DNS View Name |
        | ----------------- | ------------------------- | ------------------- |
        | default           | default                   | default             |
        | default           | test_view                 | test_view           |
        | net_view_1        | default                   | default.net_view_1  |
        | net_view_2        | dns_view_2                | dns_view_2          |

        If 'default' name has been changed. the rule is slightly different.
        Assume that 'default' network view is changed to 'default_view' and
        'default' dns view is changed to 'default_dns'

        | Network View Name | Grid Config DNS View Name | Final DNS View Name |
        | ----------------- | ------------------------- | ------------------- |
        | default_view      | default_dns               | default_dns         |
        | default_view      | test_view                 | test_view           |
        | net_view_1        | default_dns               | default.net_view_1  |
        | net_view_2        | dns_view_2                | dns_view_2          |
        """
        if self.mapping.network_view_id:
            db_netview = dbi.get_network_views(
                self.context.session,
                network_view_id=self.mapping.network_view_id)
            if db_netview and db_netview[0].dns_view:
                return db_netview[0].dns_view

        # check if grid config dns view is 'default' dns view.
        is_default_view = False
        if self.grid_config.dns_view == const.DEFAULT_DNS_VIEW:
            is_default_view = True
        else:
            db_netview = utils.find_one_in_list('dns_view',
                                                self.grid_config.dns_view,
                                                self.discovered_network_views)
            if (db_netview and
                    db_netview.internal_dns_view == const.DEFAULT_DNS_VIEW):
                is_default_view = True

        if (is_default_view and
                self.mapping.network_view != const.DEFAULT_NETWORK_VIEW):
            return '.'.join(
                [const.DEFAULT_DNS_VIEW, self.mapping.network_view])
        return self.grid_config.dns_view
Beispiel #22
0
    def test_network_view_mapping_conditions_with_subnet_cidr_condition(self):
        user_id = 'test user'
        tenant_id = '90fbad5a098a4b7cb98826128d5b40b3'

        # prepare network
        network_name = 'Test Network'
        network = self.plugin_stub.create_network(tenant_id, network_name)

        # prepare subnet with cidr used in mapping conditions
        subnet_name = 'Test Subnet'
        subnet_cidr = '12.12.2.0/24'
        subnet = self.plugin_stub.create_subnet(tenant_id, subnet_name,
                                                network['id'], subnet_cidr)

        # make sure that mapping condition exists and prepare expectations
        db_conditions = dbi.get_mapping_conditions(
            self.ctx.session,
            grid_id=self.grid_id,
            neutron_object_value=subnet_cidr)
        self.assertEqual(1, len(db_conditions))
        expected_network_view_id = db_conditions[0].network_view_id

        db_network_views = dbi.get_network_views(self.ctx.session,
                                                 grid_id=self.grid_id)
        expected_netview_row = utils.find_one_in_list(
            'id', expected_network_view_id, db_network_views)
        expected_authority_member_id = expected_netview_row.authority_member_id
        expected_network_view = expected_netview_row.network_view

        # prepare network view mapping to neutron network and subnet
        dbi.associate_network_view(
            self.ctx.session, expected_network_view_id, network['id'],
            subnet['id'])

        # test mapping where both tenant id and tenant cidr match
        ib_cxt = self._get_ib_context(user_id, network, subnet)
        ib_cxt.connector = mock.Mock()
        ib_cxt.ibom = mock.Mock()
        ib_cxt.ip_allocator = mock.Mock()

        # validate mapping
        self.assertEqual(expected_network_view_id,
                         ib_cxt.mapping.network_view_id)
        self.assertEqual(expected_network_view,
                         ib_cxt.mapping.network_view)
        self.assertEqual(expected_authority_member_id,
                         ib_cxt.mapping.authority_member.member_id)
Beispiel #23
0
    def _get_dns_view(self):
        """Return dns view name.

        The following matrix describes all the dns view naming rule.

        | Network View Name | Grid Config DNS View Name | Final DNS View Name |
        | ----------------- | ------------------------- | ------------------- |
        | default           | default                   | default             |
        | default           | test_view                 | test_view           |
        | net_view_1        | default                   | default.net_view_1  |
        | net_view_2        | dns_view_2                | dns_view_2          |

        If 'default' name has been changed. the rule is slightly different.
        Assume that 'default' network view is changed to 'default_view' and
        'default' dns view is changed to 'default_dns'

        | Network View Name | Grid Config DNS View Name | Final DNS View Name |
        | ----------------- | ------------------------- | ------------------- |
        | default_view      | default_dns               | default_dns         |
        | default_view      | test_view                 | test_view           |
        | net_view_1        | default_dns               | default.net_view_1  |
        | net_view_2        | dns_view_2                | dns_view_2          |
        """
        if self.mapping.network_view_id:
            db_netview = dbi.get_network_views(
                self.context.session,
                network_view_id=self.mapping.network_view_id)
            if db_netview and db_netview[0].dns_view:
                return db_netview[0].dns_view

        # check if grid config dns view is 'default' dns view.
        is_default_view = False
        if self.grid_config.dns_view == const.DEFAULT_DNS_VIEW:
            is_default_view = True
        else:
            db_netview = utils.find_one_in_list('dns_view',
                                                self.grid_config.dns_view,
                                                self.discovered_network_views)
            if (db_netview and db_netview.internal_dns_view
                    == const.DEFAULT_DNS_VIEW):
                is_default_view = True

        if (is_default_view
                and self.mapping.network_view != const.DEFAULT_NETWORK_VIEW):
            return '.'.join(
                [const.DEFAULT_DNS_VIEW, self.mapping.network_view])
        return self.grid_config.dns_view
Beispiel #24
0
    def update_network_sync(self, need_new_zones=False):
        """Updates EAs for each subnet that belongs to the updated network."""
        session = self.ib_cxt.context.session
        network = self.ib_cxt.network
        network_id = network.get('id')

        subnets = dbi.get_subnets_by_network_id(session, network_id)
        for subnet in subnets:
            network_view = None
            cidr = subnet.get('cidr')
            subnet_id = subnet.get('id')

            netview_mappings = dbi.get_network_view_mappings(
                session, network_id=network_id, subnet_id=subnet_id)
            if netview_mappings:
                netview_row = utils.find_one_in_list(
                    'id', netview_mappings[0].network_view_id,
                    self.ib_cxt.discovered_network_views)
                network_view = netview_row.network_view

            ib_network = None
            if network_view:
                ib_network = self.ib_cxt.ibom.get_network(network_view, cidr)
                ea_network = eam.get_ea_for_network(self.ib_cxt.user_id,
                                                    self.ib_cxt.tenant_id,
                                                    self.ib_cxt.tenant_name,
                                                    network, subnet)
                self.ib_cxt.ibom.update_network_options(ib_network, ea_network)

            if need_new_zones:
                # Need context with ib_network to create zones
                ib_cxt = context.InfobloxContext(self.ib_cxt.context,
                                                 self.ib_cxt.user_id,
                                                 network,
                                                 subnet,
                                                 self.grid_config,
                                                 self.ib_cxt.plugin,
                                                 ib_network=ib_network)
                dns_controller = dns.DnsController(ib_cxt)
                rollback_list = []
                dns_controller.create_dns_zones(rollback_list)
            else:
                self.ib_cxt.subnet = subnet
                dns_controller = dns.DnsController(self.ib_cxt)
                dns_controller.update_dns_zones()
    def test_network_view_mapping(self):
        # prepare grid
        self._create_default_grid()

        # prepare members
        self._create_simple_members()
        db_members = infoblox_db.get_members(self.ctx.session)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)

        # prepare network
        network = models_v2.Network(name="Test Network", status="ON",
                                    admin_state_up=True)
        self.ctx.session.add(network)
        self.ctx.session.flush()

        # prepare network view
        netview_dict = {'hs-view-1': gm_member.member_id}
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        network_view_id = db_network_views[0].id

        # test associate network view
        network_id = network.id
        subnet_id = 'test-subnet-id'
        infoblox_db.associate_network_view(self.ctx.session, network_view_id,
                                           network_id, subnet_id)
        db_network_view_mappings = infoblox_db.get_network_view_mappings(
            self.ctx.session)
        self.assertEqual(network_id, db_network_view_mappings[0].network_id)
        self.assertEqual(subnet_id, db_network_view_mappings[0].subnet_id)

        db_network_views = infoblox_db.get_network_view_by_mapping(
            self.ctx.session,
            network_id=network_id,
            subnet_id=subnet_id)
        self.assertEqual(network_view_id, db_network_views[0].id)

        # test dissociate network view
        infoblox_db.dissociate_network_view(self.ctx.session, network_id,
                                            subnet_id)
        db_network_view_mappings = infoblox_db.get_network_view_mappings(
            self.ctx.session, network_id=network_id, subnet_id=subnet_id)
        self.assertEqual([], db_network_view_mappings)
    def test_network_view_mapping(self):
        # prepare grid
        self._create_default_grid()

        # prepare members
        self._create_simple_members()
        db_members = infoblox_db.get_members(self.ctx.session)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)

        # prepare network
        network = models_v2.Network(name="Test Network", status="ON",
                                    admin_state_up=True)
        self.ctx.session.add(network)
        self.ctx.session.flush()

        # prepare network view
        netview_dict = {'hs-view-1': gm_member.member_id}
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        network_view_id = db_network_views[0].id

        # test associate network view
        network_id = network.id
        subnet_id = 'test-subnet-id'
        infoblox_db.associate_network_view(self.ctx.session, network_view_id,
                                           network_id, subnet_id)
        db_network_view_mappings = infoblox_db.get_network_view_mappings(
            self.ctx.session)
        self.assertEqual(network_id, db_network_view_mappings[0].network_id)
        self.assertEqual(subnet_id, db_network_view_mappings[0].subnet_id)

        db_network_views = infoblox_db.get_network_view_by_mapping(
            self.ctx.session,
            network_id=network_id,
            subnet_id=subnet_id)
        self.assertEqual(network_view_id, db_network_views[0].id)

        # test dissociate network view
        infoblox_db.dissociate_network_view(self.ctx.session, network_id,
                                            subnet_id)
        db_network_view_mappings = infoblox_db.get_network_view_mappings(
            self.ctx.session, network_id=network_id, subnet_id=subnet_id)
        self.assertEqual([], db_network_view_mappings)
Beispiel #27
0
    def _update_service_member_mapping(self):
        if not self.ib_network:
            return

        if not self.grid_config.dhcp_support:
            return

        session = self.context.session

        # dhcp members
        dhcp_members = self._get_dhcp_members(self.ib_network)
        if not dhcp_members:
            return

        ib_dhcp_members = []
        for m in dhcp_members:
            dhcp_ip = m.member_dhcp_ip or m.member_ip
            ib_dhcp_members.append(
                ib_objects.AnyMember(_struct='dhcpmember',
                                     name=m.member_name,
                                     ipv4addr=dhcp_ip))

        # get dns members from ib network if member exists. if not, get them
        # from service members
        dns_members = self._get_dns_members(self.ib_network)
        if not dns_members:
            dns_members = []
            dns_service_members = dbi.get_service_members(
                session,
                network_view_id=self.mapping.network_view_id,
                service=const.SERVICE_TYPE_DNS)
            for sm in dns_service_members:
                member = utils.find_one_in_list('member_id', sm.member_id,
                                                self.discovered_grid_members)
                if member:
                    dns_members.append(member)

        nameservers = self._get_nameservers(dns_members)

        self.mapping.dhcp_members = dhcp_members
        self.mapping.dns_members = dns_members
        self.mapping.ib_dhcp_members = ib_dhcp_members
        self.mapping.ib_nameservers = nameservers
Beispiel #28
0
    def update_network_sync(self, need_new_zones=False):
        """Updates EAs for each subnet that belongs to the updated network."""
        session = self.ib_cxt.context.session
        network = self.ib_cxt.network
        network_id = network.get('id')

        subnets = dbi.get_subnets_by_network_id(session, network_id)
        for subnet in subnets:
            network_view = None
            cidr = subnet.get('cidr')
            subnet_id = subnet.get('id')

            netview_mappings = dbi.get_network_view_mappings(
                session, network_id=network_id, subnet_id=subnet_id)
            if netview_mappings:
                netview_row = utils.find_one_in_list(
                    'id', netview_mappings[0].network_view_id,
                    self.ib_cxt.discovered_network_views)
                network_view = netview_row.network_view

            ib_network = None
            if network_view:
                ib_network = self.ib_cxt.ibom.get_network(network_view, cidr)
                ea_network = eam.get_ea_for_network(self.ib_cxt.user_id,
                                                    self.ib_cxt.tenant_id,
                                                    self.ib_cxt.tenant_name,
                                                    network,
                                                    subnet)
                self.ib_cxt.ibom.update_network_options(ib_network, ea_network)

            if need_new_zones:
                # Need context with ib_network to create zones
                ib_cxt = context.InfobloxContext(
                    self.ib_cxt.context, self.ib_cxt.user_id,
                    network, subnet, self.grid_config,
                    self.ib_cxt.plugin, ib_network=ib_network)
                dns_controller = dns.DnsController(ib_cxt)
                rollback_list = []
                dns_controller.create_dns_zones(rollback_list)
            else:
                self.ib_cxt.subnet = subnet
                dns_controller = dns.DnsController(self.ib_cxt)
                dns_controller.update_dns_zones()
    def _update_service_member_mapping(self):
        if not self.ib_network:
            return

        if not self.grid_config.dhcp_support:
            return

        session = self.context.session

        # dhcp members
        dhcp_members = self._get_dhcp_members(self.ib_network)
        if not dhcp_members:
            return

        ib_dhcp_members = []
        for m in dhcp_members:
            dhcp_ip = m.member_dhcp_ip or m.member_ip
            ib_dhcp_members.append(ib_objects.AnyMember(_struct='dhcpmember',
                                                        name=m.member_name,
                                                        ipv4addr=dhcp_ip))

        # get dns members from ib network if member exists. if not, get them
        # from service members
        dns_members = self._get_dns_members(self.ib_network)
        if not dns_members:
            dns_members = []
            dns_service_members = dbi.get_service_members(
                session,
                network_view_id=self.mapping.network_view_id,
                service=const.SERVICE_TYPE_DNS)
            for sm in dns_service_members:
                member = utils.find_one_in_list('member_id',
                                                sm.member_id,
                                                self.discovered_grid_members)
                if member:
                    dns_members.append(member)

        nameservers = self._get_nameservers(dns_members)

        self.mapping.dhcp_members = dhcp_members
        self.mapping.dns_members = dns_members
        self.mapping.ib_dhcp_members = ib_dhcp_members
        self.mapping.ib_nameservers = nameservers
    def test_mapping_management_mapping_conditions(self):
        # prepare grid
        self._create_default_grid()

        # prepare members
        self._create_simple_members()
        db_members = infoblox_db.get_members(self.ctx.session)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)

        # prepare network views
        netview_dict = {'default': gm_member.member_id}
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        netview_default_row = utils.find_one_in_list('network_view',
                                                     'default',
                                                     db_network_views)
        netview_id = netview_default_row.id

        # should be no conditions
        db_conditions = infoblox_db.get_mapping_conditions(self.ctx.session)
        self.assertEqual(0, len(db_conditions))

        expected_rows = []

        # test mapping condition additions
        neutron_object_name = const.EA_MAPPING_TENANT_ID
        neutron_object_value = '90fbad5a098a4b7cb98826128d5b40b3'
        expected_rows.append(netview_id + ':' + neutron_object_name +
                             ':' + neutron_object_value)
        infoblox_db.add_mapping_condition(self.ctx.session,
                                          netview_id,
                                          neutron_object_name,
                                          neutron_object_value)

        neutron_object_name = const.EA_MAPPING_SUBNET_CIDR
        neutron_object_values = ["12.12.1.0/24", "13.13.1.0/24"]
        for value in neutron_object_values:
            expected_rows.append(netview_id + ':' + neutron_object_name +
                                 ':' + value)
        infoblox_db.add_mapping_conditions(self.ctx.session,
                                           netview_id,
                                           neutron_object_name,
                                           neutron_object_values)

        db_conditions = infoblox_db.get_mapping_conditions(self.ctx.session)
        actual_rows = utils.get_composite_values_from_records(
            ['network_view_id', 'neutron_object_name', 'neutron_object_value'],
            db_conditions, ':')
        self.assertEqual(expected_rows, actual_rows)

        # test mapping condition removals
        # - remove Tenant ID Mapping condition
        condition_1 = expected_rows[0].split(':')
        condition_neutron_object_name = condition_1[1]
        condition_neutron_object_value = condition_1[2]
        infoblox_db.remove_mapping_condition(self.ctx.session,
                                             netview_id,
                                             condition_neutron_object_name,
                                             condition_neutron_object_value)

        db_conditions = infoblox_db.get_mapping_conditions(
            self.ctx.session,
            network_view_id=netview_id,
            grid_id=self.grid_id,
            neutron_object_name=condition_neutron_object_name)
        self.assertEqual([], db_conditions)

        # - remove two Tenant CIDR Mapping conditions
        condition_2 = expected_rows[1].split(':')
        condition_3 = expected_rows[2].split(':')
        condition_neutron_object_name = condition_2[1]
        condition_neutron_object_values = [condition_2[2], condition_3[2]]
        infoblox_db.remove_mapping_conditions(self.ctx.session,
                                              netview_id,
                                              condition_neutron_object_name,
                                              condition_neutron_object_values)

        db_conditions = infoblox_db.get_mapping_conditions(
            self.ctx.session,
            network_view_id=netview_id,
            grid_id=self.grid_id,
            neutron_object_name=condition_neutron_object_name)
        self.assertEqual([], db_conditions)

        db_conditions = infoblox_db.get_mapping_conditions(self.ctx.session)
        self.assertEqual([], db_conditions)
def sync_neutron_to_infoblox(context, credentials, grid_manager):
    """Sync neutron objects to Infoblox grid

    Prerequisites:
        1. network views to sync must have "Cloud Adapter ID" EA set.
        2. infoblox agent sync should have been processed and updated members
           and network views.
    """
    LOG.info("Starting migration...\n")

    delete_unknown_ips = cfg.CONF.delete_unknown_ips

    grid_config = grid_manager.grid_config
    grid_id = grid_config.grid_id
    session = context.session

    neutron_api = neutron_client.Client(**credentials)
    payload = neutron_api.list_networks()
    networks = payload['networks']
    if not networks:
        LOG.info("No network exists...Exiting...")
        return

    payload = neutron_api.list_subnets()
    subnets = payload['subnets']
    if not subnets:
        LOG.info("No subnet exists...Exiting...")
        return

    payload = neutron_api.list_ports()
    ports = payload['ports']
    nova_api = nova_client.Client(NOVA_API_VERSION,
                                  session=credentials['session'])

    instance_names_by_instance_id = dict()
    instance_names_by_floating_ip = dict()
    for server in nova_api.servers.list(search_opts={'all_tenants': 1}):
        instance_names_by_instance_id[server.id] = server.name
        floating_ips = []
        for net in server.addresses:
            floating_ips += [ip['addr'] for ip in server.addresses[net]
                             if ip['OS-EXT-IPS:type'] == 'floating']
        for fip in floating_ips:
            instance_names_by_floating_ip[fip] = server.name

    user_id = neutron_api.httpclient.get_user_id()
    user_tenant_id = neutron_api.httpclient.get_project_id()

    ib_networks = []
    should_exit = False

    # sync subnets
    for subnet in subnets:
        subnet_id = subnet['id']
        subnet_name = subnet['name']
        network_id = subnet['network_id']
        network = utils.find_one_in_list('id', network_id, networks)
        if not network:
            LOG.warning("network (%s) is not found. Skipping subnet (%s)",
                        network_id, subnet_id)
            continue

        network_name = network['name']
        ib_cxt = ib_context.InfobloxContext(context, user_id,
                                            network, subnet,
                                            grid_config,
                                            plugin=neutron_api)
        db_mapped_netview = dbi.get_network_view_by_mapping(
            session,
            grid_id=grid_id,
            network_id=network_id,
            subnet_id=subnet_id)
        if db_mapped_netview:
            LOG.info("Mapping found for network (%s), subnet (%s)",
                     network_name, subnet_name)
            if len(db_mapped_netview) > 1:
                LOG.warning("More that one db_mapped_netview returned")
            if delete_unknown_ips:
                ib_network = ib_objects.Network.search(
                    ib_cxt.connector,
                    network_view=db_mapped_netview[0].network_view,
                    cidr=subnet.get('cidr'))
                ib_networks.append(ib_network)
            continue

        ipam_controller = ipam.IpamSyncController(ib_cxt)
        dns_controller = dns.DnsController(ib_cxt)

        rollback_list = []
        try:
            ib_network = ipam_controller.create_subnet(rollback_list)
            if ib_network:
                if delete_unknown_ips:
                    ib_networks.append(ib_network)
                dns_controller.create_dns_zones(rollback_list)
            LOG.info("Created network (%s), subnet (%s)",
                     network_name, subnet_name)
        except Exception as e:
            LOG.error(_LE("Error occurred: %(error)s"), {'error': e})
            for ib_obj in reversed(rollback_list):
                try:
                    ib_obj.delete()
                except ib_exc.InfobloxException as e:
                    LOG.warning(_LW("Unable to delete %(obj)s due to "
                                    "error: %(error)s."),
                                {'obj': ib_obj, 'error': e})
            should_exit = True
            break

    if should_exit:
        LOG.info("Exiting due to the error in creating subnet...")
        return

    # sync ports
    for port in ports:
        port_id = port['id']
        port_name = port['name']
        port_mac_address = port['mac_address']
        tenant_id = port.get('tenant_id') or user_tenant_id
        network_id = port['network_id']
        device_owner = port['device_owner']
        device_id = port['device_id']

        instance_name = (instance_names_by_instance_id[device_id]
                         if device_id in instance_names_by_instance_id
                         else None)

        network = utils.find_one_in_list('id', network_id, networks)
        if not network:
            LOG.error("network (%s) not found", network_id)
            break

        for ip_set in port.get('fixed_ips'):
            subnet_id = ip_set['subnet_id']
            ip_address = ip_set['ip_address']
            LOG.info("Adding port for %s: %s...", device_owner, ip_address)

            subnet = utils.find_one_in_list('id', subnet_id, subnets)
            if not subnet:
                should_exit = True
                LOG.error("subnet (%s) not found", subnet_id)
                break

            ib_cxt = ib_context.InfobloxContext(context, user_id,
                                                network, subnet,
                                                grid_config,
                                                plugin=neutron_api)
            connector = ib_cxt.connector
            netview = ib_cxt.mapping.network_view

            search_fields = {
                'network_view': netview,
                'ip_address': ip_address
            }
            obj_type = ('ipv4address'if utils.get_ip_version(ip_address) == 4
                        else 'ipv6address')
            ib_address = connector.get_object(obj_type,
                                              search_fields,
                                              return_fields=['objects'],
                                              force_proxy=True)
            if ib_address and ib_address[0]['objects']:
                LOG.info("%s is found...no need to create", ip_address)
                continue

            ipam_controller = ipam.IpamSyncController(ib_cxt)
            dns_controller = dns.DnsController(ib_cxt)

            # for a floating ip port, check for its association.
            # if associated, then port info needs to be the associated port,
            # not the floating ip port because the associated port contains
            # actual attached device info
            is_floating_ip = False
            if ip_address in instance_names_by_floating_ip:
                db_floatingip = dbi.get_floatingip_by_ip_address(session,
                                                                 ip_address)
                db_port = dbi.get_port_by_id(session,
                                             db_floatingip.fixed_port_id)
                port_id = db_port.id
                port_name = db_port.name
                tenant_id = db_port.tenant_id
                device_id = db_port.device_id
                device_owner = db_port.device_owner
                instance_name = instance_names_by_floating_ip[ip_address]
                is_floating_ip = True

            allocated_ip = ipam_controller.allocate_specific_ip(
                ip_address,
                port_mac_address,
                port_id,
                tenant_id,
                device_id,
                device_owner)
            if allocated_ip and device_owner:
                try:
                    dns_controller.bind_names(
                        allocated_ip,
                        instance_name,
                        port_id,
                        tenant_id,
                        device_id,
                        device_owner,
                        is_floating_ip,
                        port_name)
                except Exception as e:
                    should_exit = True
                    LOG.error("Unable to allocate ip (%s): %s", ip_address, e)
                    ipam_controller.deallocate_ip(allocated_ip)
                    break

            LOG.info("Allocated %s", ip_address)

        if should_exit:
            LOG.info("Existing due to error in port creation...")
            break

    if delete_unknown_ips:
        LOG.info("Start deleting unknown Fixed IP's from Infoblox...")
        for ib_network in ib_networks:

            nw_ea = ib_network.extattrs
            # Skip network if it doesn't have EA or if EA indicates it's
            # shared or external.
            if (not nw_ea or
                    nw_ea.get('Is External') or nw_ea.get('Is Shared')):
                continue

            LOG.info("Searching for Fixed IP: network_view='%s', cidr='%s'" %
                     (ib_network.network_view, ib_network.network))
            fixed_ips = ib_objects.FixedAddress.search_all(
                ib_cxt.connector,
                network_view=ib_network.network_view,
                network=ib_network.network)

            if not fixed_ips:
                LOG.info("No FixedIP found: network_view='%s', cidr='%s'" %
                         (ib_network.network_view, ib_network.network))
                continue

            for fixed_ip in fixed_ips:
                ea = fixed_ip.extattrs
                port_id = None
                if ea:
                    port_id = ea.get('Port ID')

                # Delete Fixed IP if:
                #   - Fixed IP does not have 'Port ID' EA, or
                #   - No port_id in neutron matches 'Port ID' EA value
                if not (port_id and
                        utils.find_one_in_list('id', port_id, ports)):
                    LOG.info("Deleting Fixed IP from Infoblox: '%s'" %
                             fixed_ip)
                    fixed_ip.delete()

    LOG.info("Ending migration...")
Beispiel #32
0
    def _validate_member_mapping(self, network_view_json, network_json):
        db_members = dbi.get_members(self.ctx.session,
                                     grid_id=self.test_grid_config.grid_id)
        db_network_views = dbi.get_network_views(self.ctx.session)
        db_mapping_members = dbi.get_mapping_members(self.ctx.session)
        db_service_members = dbi.get_service_members(self.ctx.session)

        gm_row = utils.find_one_in_list('member_type',
                                        const.MEMBER_TYPE_GRID_MASTER,
                                        db_members)
        gm_member_id = gm_row.member_id

        dedicated_delegation_members = dict()
        for netview in network_view_json:
            netview_name = netview['name']
            if (netview.get('cloud_info')
                    and netview.get('cloud_info').get('delegated_member')):
                delegated_member = utils.find_one_in_list(
                    'member_name',
                    netview['cloud_info']['delegated_member']['name'],
                    db_members)
                dedicated_delegation_members[netview_name] = (
                    delegated_member.member_id)

        expected_mapping_members = []
        expected_service_members = []

        # get delegated authority members from network views
        for netview in dedicated_delegation_members:
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 db_network_views)
            netview_id = netview_row.id
            authority_member = dedicated_delegation_members[netview]
            mapping_relation = const.MAPPING_RELATION_DELEGATED
            mapping_row_info = (netview_id + DELIMITER + authority_member +
                                DELIMITER + mapping_relation)
            expected_mapping_members.append(mapping_row_info)

        # get authority members from networks
        for network in network_json:
            netview = network['network_view']
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 db_network_views)
            netview_id = netview_row.id

            mapping_relation = const.MAPPING_RELATION_GM_OWNED
            authority_member = gm_member_id
            if netview in dedicated_delegation_members:
                authority_member = dedicated_delegation_members[netview]
                mapping_relation = const.MAPPING_RELATION_DELEGATED
            elif (network.get('cloud_info')
                  and network['cloud_info'].get('delegated_member')):
                delegated_member = utils.find_one_in_list(
                    'member_name',
                    network['cloud_info']['delegated_member']['name'],
                    db_members)
                authority_member = delegated_member.member_id
                mapping_relation = const.MAPPING_RELATION_DELEGATED

            mapping_row_info = (netview_id + DELIMITER + authority_member +
                                DELIMITER + mapping_relation)
            if mapping_row_info not in expected_mapping_members:
                expected_mapping_members.append(mapping_row_info)

            if network.get('members'):
                for m in network['members']:
                    if m['_struct'] == 'dhcpmember':
                        dhcp_member = utils.find_one_in_list(
                            'member_name', m['name'], db_members)
                        mapping_row_info = (netview_id + DELIMITER +
                                            dhcp_member.member_id + DELIMITER +
                                            const.SERVICE_TYPE_DHCP)
                        if mapping_row_info not in expected_service_members:
                            expected_service_members.append(mapping_row_info)

            if network.get('options'):
                dns_membe_ips = []
                for option in network['options']:
                    if option.get('name') == 'domain-name-servers':
                        option_values = option.get('value')
                        if option_values:
                            dns_membe_ips = option_values.split(',')
                            break
                for membe_ip in dns_membe_ips:
                    dns_member = utils.find_one_in_list(
                        'member_ip', membe_ip, db_members)
                    mapping_row_info = (netview_id + DELIMITER +
                                        dns_member.member_id + DELIMITER +
                                        const.SERVICE_TYPE_DNS)
                    if mapping_row_info not in expected_service_members:
                        expected_service_members.append(mapping_row_info)

        actual_mapping_members = utils.get_composite_values_from_records(
            ['network_view_id', 'member_id', 'mapping_relation'],
            db_mapping_members)
        self.assertEqual(set(expected_mapping_members),
                         set(actual_mapping_members))

        actual_service_members = utils.get_composite_values_from_records(
            ['network_view_id', 'member_id', 'service'], db_service_members)
        self.assertEqual(set(expected_service_members),
                         set(actual_service_members))
Beispiel #33
0
    def _sync_network_views(self, discovered_netviews, dns_views):
        """Discover network views and sync with db.

        The discovered network view json contains the following data:
        - network view
        - cloud_info for delegated member if cloud platform is supported
        - mapping conditional EAs

        So discovered information will be updated in tables such as
        infoblox_network_views and infoblox_mapping_conditions.

        :param discovered_netviews: discovered network view json
        :return: None
        """
        session = self._context.session
        self._load_persisted_mappings()
        discovered_delegations = dict()

        persisted_netview_ids = utils.get_values_from_records(
            'id', self.db_network_views)
        discovered_netview_ids = []

        for netview in discovered_netviews:
            netview_name = netview['name']
            is_default = netview[const.IS_DEFAULT]
            netview_id = utils.get_network_view_id(self._grid_id,
                                                   netview['_ref'])

            cloud_adapter_id_vals = utils.get_ea_value(
                const.EA_CLOUD_ADAPTER_ID, netview, True)
            if cloud_adapter_id_vals is None:
                participated = False
            else:
                cloud_adapter_ids = [
                    gid for gid in cloud_adapter_id_vals
                    if int(gid) == self._grid_id
                ]
                participated = True if cloud_adapter_ids else False

            if not participated:
                continue

            shared_val = utils.get_ea_value(const.EA_IS_SHARED, netview)
            is_shared = types.Boolean()(shared_val) if shared_val else False

            # authority member is default to GM
            gm_row = utils.find_one_in_list('member_type',
                                            const.MEMBER_TYPE_GRID_MASTER,
                                            self.db_members)
            authority_member_id = gm_row.member_id

            # get delegation member if cloud platform is supported
            delegated_member = self._get_delegated_member(netview)
            if delegated_member:
                authority_member_id = delegated_member.member_id
                discovered_delegations[netview_name] = (
                    delegated_member.member_id)

            dns_view = (dns_views[netview_name]
                        if dns_views.get(netview_name) else None)

            # see if the network view already exists in db
            netview_row = utils.find_one_in_list('id', netview_id,
                                                 self.db_network_views)
            if netview_row:
                dbi.update_network_view(session, netview_id, netview_name,
                                        authority_member_id, is_shared,
                                        dns_view, participated, is_default)
            else:
                internal_netview = (const.DEFAULT_NETWORK_VIEW
                                    if is_default else netview_name)
                internal_dnsview = (const.DEFAULT_DNS_VIEW
                                    if is_default else dns_view)
                dbi.add_network_view(session, netview_id, netview_name,
                                     self._grid_id, authority_member_id,
                                     is_shared, dns_view, internal_netview,
                                     internal_dnsview, participated,
                                     is_default)

            discovered_netview_ids.append(netview_id)

            # update mapping conditions for the current network view
            self._update_mapping_conditions(netview, netview_id, participated)

        # we have added new network views. now let's remove persisted
        # network views not found from discovery
        persisted_set = set(persisted_netview_ids)
        removable_set = persisted_set.difference(discovered_netview_ids)
        removable_netviews = list(removable_set)
        if removable_netviews:
            dbi.remove_network_views(session, removable_netviews)
        session.flush()
        return discovered_delegations
Beispiel #34
0
    def sync_members(self):
        """Synchronizes grid members.

        Members in the active grid are discovered from NIOS backend and
        grid members are in sync in neutron db. The members who are no longer
        in used are set to 'OFF' status.
        """
        session = self._context.session
        grid_id = self._grid_config.grid_id

        db_grids = dbi.get_grids(session)
        db_grid = utils.find_one_in_list('grid_id', grid_id, db_grids)
        gm_member_id = db_grid.gm_id

        db_members = dbi.get_members(session, grid_id=grid_id)
        gm_member = utils.find_one_in_list('member_id', gm_member_id,
                                           db_members)

        discovered_members = self._discover_members()
        if not discovered_members:
            return

        dns_member_settings = self._discover_dns_settings()
        dhcp_member_settings = self._discover_dhcp_settings()

        discovered_licenses = self._discover_member_licenses()

        discovered_member_ids = []

        for member in discovered_members:
            member_name = member['host_name']
            member_ip, member_ipv6 = self._get_lan1_ips(member)
            member_wapi = member_ip if member_ip else member_ipv6
            member_hwid = member['node_info'][0].get('hwid')
            member_status = self._get_member_status(
                member['node_info'][0]['service_status'])
            member_type = self._get_member_type(discovered_licenses,
                                                member_name,
                                                member_hwid)

            require_db_update = False
            if member_type == const.MEMBER_TYPE_GRID_MASTER:
                if gm_member:
                    require_db_update = True
                member_id = gm_member_id
                member_wapi = self._grid_config.grid_master_host
            else:
                # no need to process 'Is Cloud Member' flag for non GM members
                ea_is_cloud_member = utils.get_ea_value(
                    const.EA_IS_CLOUD_MEMBER, member)
                is_cloud_member = (types.Boolean()(ea_is_cloud_member)
                                   if ea_is_cloud_member else False)
                if not is_cloud_member:
                    continue

                db_member = utils.find_one_in_list('member_name', member_name,
                                                   db_members)
                if db_member:
                    require_db_update = True
                    member_id = db_member.member_id
                else:
                    member_id = utils.get_hash(str(grid_id) + member_name)

            member_dhcp_ip, member_dhcp_ipv6 = self._get_dhcp_ips(
                member, dhcp_member_settings)
            member_dns_ip, member_dns_ipv6 = self._get_dns_ips(
                member, dns_member_settings)

            if require_db_update:
                dbi.update_member(session,
                                  member_id,
                                  grid_id,
                                  member_name,
                                  member_ip,
                                  member_ipv6,
                                  member_type,
                                  member_status,
                                  member_dhcp_ip,
                                  member_dhcp_ipv6,
                                  member_dns_ip,
                                  member_dns_ipv6,
                                  member_wapi)
            else:
                dbi.add_member(session,
                               member_id,
                               grid_id,
                               member_name,
                               member_ip,
                               member_ipv6,
                               member_type,
                               member_status,
                               member_dhcp_ip,
                               member_dhcp_ipv6,
                               member_dns_ip,
                               member_dns_ipv6,
                               member_wapi)

            discovered_member_ids.append(member_id)

        # deleting members are delicate operation so we won't allow it
        # but we will set member status to OFF to unused members.
        db_member_ids = utils.get_values_from_records('member_id', db_members)
        persisted_set = set(db_member_ids)
        discovered_set = set(discovered_member_ids)
        disable_set = persisted_set.difference(discovered_set)
        disabling_member_ids = list(disable_set)
        for member_id in disabling_member_ids:
            dbi.update_member(session,
                              member_id,
                              grid_id,
                              member_status=const.MEMBER_STATUS_OFF)
        session.flush()
Beispiel #35
0
    def _get_member_mapping(self, discovered_networks, discovered_delegations):
        """Returns members that are used for authority and dhcp.

        Authority members own network views because they are either GM who owns
        non delegated network views or Cloud Platform Member(CPM) who owns
        delegated network views.

        DHCP members are the members who serve DHCP protocols.
        """
        gm_row = utils.find_one_in_list('member_type',
                                        const.MEMBER_TYPE_GRID_MASTER,
                                        self.db_members)
        gm_member_id = gm_row.member_id
        mapping_authority_members = []
        mapping_service_members = []

        # first get delegated authority members from Infoblox network views
        for netview in discovered_delegations:
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 self.db_network_views)
            if not netview_row:
                continue
            netview_id = netview_row.id
            authority_member = discovered_delegations[netview]
            mapping_relation = const.MAPPING_RELATION_DELEGATED
            mapping_row_info = (netview_id + DELIMITER + authority_member +
                                DELIMITER + mapping_relation)
            mapping_authority_members.append(mapping_row_info)

        # then get authority and dhcp members from Infoblox networks
        for network in discovered_networks:
            netview = network['network_view']
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 self.db_network_views)
            if not netview_row or not netview_row.participated:
                continue

            netview_id = netview_row.id

            # get authority member
            mapping_relation = const.MAPPING_RELATION_GM_OWNED
            authority_member = gm_member_id
            delegated_member = self._get_delegated_member(network)

            if netview in discovered_delegations:
                authority_member = discovered_delegations[netview]
                mapping_relation = const.MAPPING_RELATION_DELEGATED
            elif delegated_member:
                authority_member = delegated_member.member_id
                mapping_relation = const.MAPPING_RELATION_DELEGATED

            mapping_member_info = (netview_id + DELIMITER + authority_member +
                                   DELIMITER + mapping_relation)
            if mapping_member_info not in mapping_authority_members:
                mapping_authority_members.append(mapping_member_info)

            # get dhcp member
            dhcp_members = self._get_dhcp_members(network)
            for member in dhcp_members:
                mapping_member_info = (netview_id + DELIMITER +
                                       member.member_id + DELIMITER +
                                       const.SERVICE_TYPE_DHCP)
                if mapping_member_info not in mapping_service_members:
                    mapping_service_members.append(mapping_member_info)

            # get dns member
            dns_members = self._get_dns_members(network)
            for member in dns_members:
                mapping_member_info = (netview_id + DELIMITER +
                                       member.member_id + DELIMITER +
                                       const.SERVICE_TYPE_DNS)
                if mapping_member_info not in mapping_service_members:
                    mapping_service_members.append(mapping_member_info)

        return {
            'authority_members': mapping_authority_members,
            'service_members': mapping_service_members
        }
    def _sync_network_views(self, discovered_netviews, dns_views):
        """Discover network views and sync with db.

        The discovered network view json contains the following data:
        - network view
        - cloud_info for delegated member if cloud platform is supported
        - mapping conditional EAs

        So discovered information will be updated in tables such as
        infoblox_network_views and infoblox_mapping_conditions.

        :param discovered_netviews: discovered network view json
        :return: None
        """
        session = self._context.session
        self._load_persisted_mappings()
        discovered_delegations = dict()

        persisted_netview_ids = utils.get_values_from_records(
            'id', self.db_network_views)
        discovered_netview_ids = []

        for netview in discovered_netviews:
            netview_name = netview['name']
            is_default = netview[const.IS_DEFAULT]
            netview_id = utils.get_network_view_id(self._grid_id,
                                                   netview['_ref'])

            cloud_adapter_id_vals = utils.get_ea_value(
                const.EA_CLOUD_ADAPTER_ID, netview, True)
            if cloud_adapter_id_vals is None:
                participated = False
            else:
                cloud_adapter_ids = [gid for gid in cloud_adapter_id_vals
                                     if int(gid) == self._grid_id]
                participated = True if cloud_adapter_ids else False

            if not participated:
                continue

            shared_val = utils.get_ea_value(const.EA_IS_SHARED, netview)
            is_shared = types.Boolean()(shared_val) if shared_val else False

            # authority member is default to GM
            gm_row = utils.find_one_in_list('member_type',
                                            const.MEMBER_TYPE_GRID_MASTER,
                                            self.db_members)
            authority_member_id = gm_row.member_id

            # get delegation member if cloud platform is supported
            delegated_member = self._get_delegated_member(netview)
            if delegated_member:
                authority_member_id = delegated_member.member_id
                discovered_delegations[netview_name] = (
                    delegated_member.member_id)

            dns_view = (dns_views[netview_name] if dns_views.get(netview_name)
                        else None)

            # see if the network view already exists in db
            netview_row = utils.find_one_in_list('id',
                                                 netview_id,
                                                 self.db_network_views)
            if netview_row:
                dbi.update_network_view(session, netview_id, netview_name,
                                        authority_member_id, is_shared,
                                        dns_view, participated, is_default)
            else:
                internal_netview = (const.DEFAULT_NETWORK_VIEW if is_default
                                    else netview_name)
                internal_dnsview = (const.DEFAULT_DNS_VIEW if is_default
                                    else dns_view)
                dbi.add_network_view(session,
                                     netview_id,
                                     netview_name,
                                     self._grid_id,
                                     authority_member_id,
                                     is_shared,
                                     dns_view,
                                     internal_netview,
                                     internal_dnsview,
                                     participated,
                                     is_default)

            discovered_netview_ids.append(netview_id)

            # update mapping conditions for the current network view
            self._update_mapping_conditions(netview, netview_id, participated)

        # we have added new network views. now let's remove persisted
        # network views not found from discovery
        persisted_set = set(persisted_netview_ids)
        removable_set = persisted_set.difference(discovered_netview_ids)
        removable_netviews = list(removable_set)
        if removable_netviews:
            dbi.remove_network_views(session, removable_netviews)
        session.flush()
        return discovered_delegations
    def _get_network_view_by_scope(self, netview_scope, neutron_objs):
        netview_name = None

        if netview_scope == const.NETWORK_VIEW_SCOPE_SINGLE:
            db_netview = utils.find_one_in_list(
                'network_view',
                self.grid_config.default_network_view,
                self.discovered_network_views)
            if db_netview:
                if db_netview.participated:
                    netview_name = self.grid_config.default_network_view
                else:
                    raise exc.InfobloxNetworkViewNotParticipated(
                        network_view=self.grid_config.default_network_view)
            else:
                raise exc.InfobloxNetworkViewNotFound(
                    network_view=self.grid_config.default_network_view)
        else:
            object_id = None
            object_name = None

            if netview_scope == const.NETWORK_VIEW_SCOPE_SUBNET:
                object_id = neutron_objs['subnet_id']
                object_name = neutron_objs['subnet_name']
            elif netview_scope == const.NETWORK_VIEW_SCOPE_NETWORK:
                object_id = neutron_objs['network_id']
                object_name = neutron_objs['network_name']
            elif netview_scope == const.NETWORK_VIEW_SCOPE_TENANT:
                object_id = neutron_objs['tenant_id']
                object_name = neutron_objs['tenant_name']
            elif netview_scope == const.NETWORK_VIEW_SCOPE_ADDRESS_SCOPE:
                object_id = neutron_objs['address_scope_id']
                object_name = neutron_objs['address_scope_name']

            if object_id:
                netview_name = utils.generate_network_view_name(object_id,
                                                                object_name)

        # see if formulated netview name matches internal name in db
        # if matches then return the current netview name;
        # this is needed to support the netview name change
        db_netviews = dbi.get_network_views(
            self.context.session,
            grid_id=self.grid_id,
            internal_network_view=netview_name)
        if db_netviews:
            if db_netviews[0].participated:
                netview_name = db_netviews[0].network_view
            else:
                raise exc.InfobloxNetworkViewNotParticipated(
                    network_view=netview_name)

        # still no network view, then try to use default
        if not netview_name:
            default_netview = utils.find_one_in_list(
                'default', True, self.discovered_network_views)
            if default_netview:
                if default_netview.participated:
                    netview_name = default_netview.network_view
                else:
                    raise exc.InfobloxNetworkViewNotParticipated(
                        network_view=netview_name)
            else:
                raise exc.InfobloxDefaultNetworkViewNotFound()

        return netview_name
Beispiel #38
0
    def _get_network_view_by_scope(self, netview_scope, neutron_objs):
        netview_name = None

        if netview_scope == const.NETWORK_VIEW_SCOPE_SINGLE:
            db_netview = utils.find_one_in_list(
                'network_view', self.grid_config.default_network_view,
                self.discovered_network_views)
            if db_netview:
                if db_netview.participated:
                    netview_name = self.grid_config.default_network_view
                else:
                    raise exc.InfobloxNetworkViewNotParticipated(
                        network_view=self.grid_config.default_network_view)
            else:
                raise exc.InfobloxNetworkViewNotFound(
                    network_view=self.grid_config.default_network_view)
        else:
            object_id = None
            object_name = None

            if netview_scope == const.NETWORK_VIEW_SCOPE_SUBNET:
                object_id = neutron_objs['subnet_id']
                object_name = neutron_objs['subnet_name']
            elif netview_scope == const.NETWORK_VIEW_SCOPE_NETWORK:
                object_id = neutron_objs['network_id']
                object_name = neutron_objs['network_name']
            elif netview_scope == const.NETWORK_VIEW_SCOPE_TENANT:
                object_id = neutron_objs['tenant_id']
                object_name = neutron_objs['tenant_name']
            elif netview_scope == const.NETWORK_VIEW_SCOPE_ADDRESS_SCOPE:
                object_id = neutron_objs['address_scope_id']
                object_name = neutron_objs['address_scope_name']

            if object_id:
                netview_name = utils.generate_network_view_name(
                    object_id, object_name)

        # see if formulated netview name matches internal name in db
        # if matches then return the current netview name;
        # this is needed to support the netview name change
        db_netviews = dbi.get_network_views(self.context.session,
                                            grid_id=self.grid_id,
                                            internal_network_view=netview_name)
        if db_netviews:
            if db_netviews[0].participated:
                netview_name = db_netviews[0].network_view
            else:
                raise exc.InfobloxNetworkViewNotParticipated(
                    network_view=netview_name)

        # still no network view, then try to use default
        if not netview_name:
            default_netview = utils.find_one_in_list(
                'default', True, self.discovered_network_views)
            if default_netview:
                if default_netview.participated:
                    netview_name = default_netview.network_view
                else:
                    raise exc.InfobloxNetworkViewNotParticipated(
                        network_view=netview_name)
            else:
                raise exc.InfobloxDefaultNetworkViewNotFound()

        return netview_name
Beispiel #39
0
    def test_mapping_management_mapping_conditions(self):
        # prepare grid
        self._create_default_grid()

        # prepare members
        self._create_simple_members()
        db_members = infoblox_db.get_members(self.ctx.session)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)

        # prepare network views
        netview_dict = {'default': gm_member.member_id}
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        netview_default_row = utils.find_one_in_list('network_view', 'default',
                                                     db_network_views)
        netview_id = netview_default_row.id

        # should be no conditions
        db_conditions = infoblox_db.get_mapping_conditions(self.ctx.session)
        self.assertEqual(0, len(db_conditions))

        expected_rows = []

        # test mapping condition additions
        neutron_object_name = const.EA_MAPPING_TENANT_ID
        neutron_object_value = '90fbad5a098a4b7cb98826128d5b40b3'
        expected_rows.append(netview_id + ':' + neutron_object_name + ':' +
                             neutron_object_value)
        infoblox_db.add_mapping_condition(self.ctx.session, netview_id,
                                          neutron_object_name,
                                          neutron_object_value)

        neutron_object_name = const.EA_MAPPING_SUBNET_CIDR
        neutron_object_values = ["12.12.1.0/24", "13.13.1.0/24"]
        for value in neutron_object_values:
            expected_rows.append(netview_id + ':' + neutron_object_name + ':' +
                                 value)
        infoblox_db.add_mapping_conditions(self.ctx.session, netview_id,
                                           neutron_object_name,
                                           neutron_object_values)

        db_conditions = infoblox_db.get_mapping_conditions(self.ctx.session)
        actual_rows = utils.get_composite_values_from_records(
            ['network_view_id', 'neutron_object_name', 'neutron_object_value'],
            db_conditions, ':')
        self.assertEqual(expected_rows, actual_rows)

        # test mapping condition removals
        # - remove Tenant ID Mapping condition
        condition_1 = expected_rows[0].split(':')
        condition_neutron_object_name = condition_1[1]
        condition_neutron_object_value = condition_1[2]
        infoblox_db.remove_mapping_condition(self.ctx.session, netview_id,
                                             condition_neutron_object_name,
                                             condition_neutron_object_value)

        db_conditions = infoblox_db.get_mapping_conditions(
            self.ctx.session,
            network_view_id=netview_id,
            grid_id=self.grid_id,
            neutron_object_name=condition_neutron_object_name)
        self.assertEqual([], db_conditions)

        # - remove two Tenant CIDR Mapping conditions
        condition_2 = expected_rows[1].split(':')
        condition_3 = expected_rows[2].split(':')
        condition_neutron_object_name = condition_2[1]
        condition_neutron_object_values = [condition_2[2], condition_3[2]]
        infoblox_db.remove_mapping_conditions(self.ctx.session, netview_id,
                                              condition_neutron_object_name,
                                              condition_neutron_object_values)

        db_conditions = infoblox_db.get_mapping_conditions(
            self.ctx.session,
            network_view_id=netview_id,
            grid_id=self.grid_id,
            neutron_object_name=condition_neutron_object_name)
        self.assertEqual([], db_conditions)

        db_conditions = infoblox_db.get_mapping_conditions(self.ctx.session)
        self.assertEqual([], db_conditions)
    def _validate_member_mapping(self, network_view_json, network_json):
        db_members = dbi.get_members(self.ctx.session,
                                     grid_id=self.test_grid_config.grid_id)
        db_network_views = dbi.get_network_views(self.ctx.session)
        db_mapping_members = dbi.get_mapping_members(self.ctx.session)
        db_service_members = dbi.get_service_members(self.ctx.session)

        gm_row = utils.find_one_in_list('member_type',
                                        const.MEMBER_TYPE_GRID_MASTER,
                                        db_members)
        gm_member_id = gm_row.member_id

        dedicated_delegation_members = dict()
        for netview in network_view_json:
            netview_name = netview['name']
            if (netview.get('cloud_info') and
                    netview.get('cloud_info').get('delegated_member')):
                delegated_member = utils.find_one_in_list(
                    'member_name',
                    netview['cloud_info']['delegated_member']['name'],
                    db_members)
                dedicated_delegation_members[netview_name] = (
                    delegated_member.member_id)

        expected_mapping_members = []
        expected_service_members = []

        # get delegated authority members from network views
        for netview in dedicated_delegation_members:
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 db_network_views)
            netview_id = netview_row.id
            authority_member = dedicated_delegation_members[netview]
            mapping_relation = const.MAPPING_RELATION_DELEGATED
            mapping_row_info = (netview_id + DELIMITER + authority_member +
                                DELIMITER + mapping_relation)
            expected_mapping_members.append(mapping_row_info)

        # get authority members from networks
        for network in network_json:
            netview = network['network_view']
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 db_network_views)
            netview_id = netview_row.id

            mapping_relation = const.MAPPING_RELATION_GM_OWNED
            authority_member = gm_member_id
            if netview in dedicated_delegation_members:
                authority_member = dedicated_delegation_members[netview]
                mapping_relation = const.MAPPING_RELATION_DELEGATED
            elif (network.get('cloud_info') and
                    network['cloud_info'].get('delegated_member')):
                delegated_member = utils.find_one_in_list(
                    'member_name',
                    network['cloud_info']['delegated_member']['name'],
                    db_members)
                authority_member = delegated_member.member_id
                mapping_relation = const.MAPPING_RELATION_DELEGATED

            mapping_row_info = (netview_id + DELIMITER + authority_member +
                                DELIMITER + mapping_relation)
            if mapping_row_info not in expected_mapping_members:
                expected_mapping_members.append(mapping_row_info)

            if network.get('members'):
                for m in network['members']:
                    if m['_struct'] == 'dhcpmember':
                        dhcp_member = utils.find_one_in_list(
                            'member_name', m['name'], db_members)
                        mapping_row_info = (netview_id + DELIMITER +
                                            dhcp_member.member_id + DELIMITER +
                                            const.SERVICE_TYPE_DHCP)
                        if mapping_row_info not in expected_service_members:
                            expected_service_members.append(mapping_row_info)

            if network.get('options'):
                dns_membe_ips = []
                for option in network['options']:
                    if option.get('name') == 'domain-name-servers':
                        option_values = option.get('value')
                        if option_values:
                            dns_membe_ips = option_values.split(',')
                            break
                for membe_ip in dns_membe_ips:
                    dns_member = utils.find_one_in_list(
                        'member_ip', membe_ip, db_members)
                    mapping_row_info = (netview_id + DELIMITER +
                                        dns_member.member_id + DELIMITER +
                                        const.SERVICE_TYPE_DNS)
                    if mapping_row_info not in expected_service_members:
                        expected_service_members.append(mapping_row_info)

        actual_mapping_members = utils.get_composite_values_from_records(
            ['network_view_id', 'member_id', 'mapping_relation'],
            db_mapping_members)
        self.assertEqual(set(expected_mapping_members),
                         set(actual_mapping_members))

        actual_service_members = utils.get_composite_values_from_records(
            ['network_view_id', 'member_id', 'service'],
            db_service_members)
        self.assertEqual(set(expected_service_members),
                         set(actual_service_members))
Beispiel #41
0
    def sync_members(self):
        """Synchronizes grid members.

        Members in the active grid are discovered from NIOS backend and
        grid members are in sync in neutron db. The members who are no longer
        in used are set to 'OFF' status.
        """
        session = self._context.session
        grid_id = self._grid_config.grid_id

        db_grids = dbi.get_grids(session)
        db_grid = utils.find_one_in_list('grid_id', grid_id, db_grids)
        gm_member_id = db_grid.gm_id

        db_members = dbi.get_members(session, grid_id=grid_id)
        gm_member = utils.find_one_in_list('member_id', gm_member_id,
                                           db_members)

        discovered_members = self._discover_members()
        if not discovered_members:
            return

        dns_member_settings = self._discover_dns_settings()
        dhcp_member_settings = self._discover_dhcp_settings()

        discovered_licenses = self._discover_member_licenses()

        discovered_member_ids = []

        for member in discovered_members:
            member_name = member['host_name']
            member_ip, member_ipv6 = self._get_lan1_ips(member)
            member_wapi = member_ip if member_ip else member_ipv6
            member_hwid = member['node_info'][0].get('hwid')
            member_status = self._get_member_status(
                member['node_info'][0]['service_status'])
            member_type = self._get_member_type(discovered_licenses,
                                                member_name, member_hwid)

            require_db_update = False
            if member_type == const.MEMBER_TYPE_GRID_MASTER:
                if gm_member:
                    require_db_update = True
                member_id = gm_member_id
                member_wapi = self._grid_config.grid_master_host
            else:
                # no need to process 'Is Cloud Member' flag for non GM members
                ea_is_cloud_member = utils.get_ea_value(
                    const.EA_IS_CLOUD_MEMBER, member)
                is_cloud_member = (types.Boolean()(ea_is_cloud_member)
                                   if ea_is_cloud_member else False)
                if not is_cloud_member:
                    continue

                db_member = utils.find_one_in_list('member_name', member_name,
                                                   db_members)
                if db_member:
                    require_db_update = True
                    member_id = db_member.member_id
                else:
                    member_id = utils.get_hash(str(grid_id) + member_name)

            member_dhcp_ip, member_dhcp_ipv6 = self._get_dhcp_ips(
                member, dhcp_member_settings)
            member_dns_ip, member_dns_ipv6 = self._get_dns_ips(
                member, dns_member_settings)

            if require_db_update:
                dbi.update_member(session, member_id, grid_id, member_name,
                                  member_ip, member_ipv6, member_type,
                                  member_status, member_dhcp_ip,
                                  member_dhcp_ipv6, member_dns_ip,
                                  member_dns_ipv6, member_wapi)
            else:
                dbi.add_member(session, member_id, grid_id, member_name,
                               member_ip, member_ipv6, member_type,
                               member_status, member_dhcp_ip, member_dhcp_ipv6,
                               member_dns_ip, member_dns_ipv6, member_wapi)

            discovered_member_ids.append(member_id)

        # deleting members are delicate operation so we won't allow it
        # but we will set member status to OFF to unused members.
        db_member_ids = utils.get_values_from_records('member_id', db_members)
        persisted_set = set(db_member_ids)
        discovered_set = set(discovered_member_ids)
        disable_set = persisted_set.difference(discovered_set)
        disabling_member_ids = list(disable_set)
        for member_id in disabling_member_ids:
            dbi.update_member(session,
                              member_id,
                              grid_id,
                              member_status=const.MEMBER_STATUS_OFF)
        session.flush()
Beispiel #42
0
    def test_service_member(self):
        # prepare grid
        self._create_default_grid()

        # prepare grid members
        member_list = [{
            'member_id': 'm1',
            'member_name': 'm1.com',
            'member_ip': '10.10.1.1',
            'member_ipv6': None,
            'member_type': const.MEMBER_TYPE_GRID_MASTER,
            'member_status': 'ON'
        }, {
            'member_id': 'm2',
            'member_name': 'm2.com',
            'member_ip': '10.10.1.2',
            'member_ipv6': 'fd44:acb:5df6:1083::22',
            'member_type': const.MEMBER_TYPE_CP_MEMBER,
            'member_status': 'ON'
        }]
        self._create_members(member_list, self.grid_id)

        db_members = infoblox_db.get_members(self.ctx.session,
                                             grid_id=self.grid_id)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)
        m2_member = utils.find_one_in_list('member_id', 'm2', db_members)

        # create network views
        netview_dict = {'default': gm_member.member_id}
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        netview_default = utils.find_one_in_list('network_view', 'default',
                                                 db_network_views)

        # test addition
        infoblox_db.add_service_member(self.ctx.session, netview_default.id,
                                       gm_member.member_id,
                                       const.SERVICE_TYPE_DHCP)

        infoblox_db.add_service_member(self.ctx.session, netview_default.id,
                                       m2_member.member_id,
                                       const.SERVICE_TYPE_DHCP)

        db_service_members = infoblox_db.get_service_members(
            self.ctx.session, netview_default.id)
        gm_dhcp_member = utils.find_one_in_list('member_id',
                                                gm_member.member_id,
                                                db_service_members)
        self.assertIsNotNone(gm_dhcp_member)
        m2_dhcp_member = utils.find_one_in_list('member_id',
                                                m2_member.member_id,
                                                db_service_members)
        self.assertIsNotNone(m2_dhcp_member)

        # test removal
        infoblox_db.remove_service_member(self.ctx.session, netview_default.id)
        db_service_members = infoblox_db.get_service_members(
            self.ctx.session, netview_default.id)
        gm_dhcp_member = utils.find_one_in_list('member_id',
                                                gm_member.member_id,
                                                db_service_members)
        self.assertIsNone(gm_dhcp_member)

        m2m_dhcp_member = utils.find_one_in_list('member_id',
                                                 m2_member.member_id,
                                                 db_service_members)
        self.assertIsNone(m2m_dhcp_member)
    def _get_member_mapping(self, discovered_networks, discovered_delegations):
        """Returns members that are used for authority and dhcp.

        Authority members own network views because they are either GM who owns
        non delegated network views or Cloud Platform Member(CPM) who owns
        delegated network views.

        DHCP members are the members who serve DHCP protocols.
        """
        gm_row = utils.find_one_in_list('member_type',
                                        const.MEMBER_TYPE_GRID_MASTER,
                                        self.db_members)
        gm_member_id = gm_row.member_id
        mapping_authority_members = []
        mapping_service_members = []

        # first get delegated authority members from Infoblox network views
        for netview in discovered_delegations:
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 self.db_network_views)
            if not netview_row:
                continue
            netview_id = netview_row.id
            authority_member = discovered_delegations[netview]
            mapping_relation = const.MAPPING_RELATION_DELEGATED
            mapping_row_info = (netview_id + DELIMITER +
                                authority_member + DELIMITER +
                                mapping_relation)
            mapping_authority_members.append(mapping_row_info)

        # then get authority and dhcp members from Infoblox networks
        for network in discovered_networks:
            netview = network['network_view']
            netview_row = utils.find_one_in_list('network_view', netview,
                                                 self.db_network_views)
            if not netview_row or not netview_row.participated:
                continue

            netview_id = netview_row.id

            # get authority member
            mapping_relation = const.MAPPING_RELATION_GM_OWNED
            authority_member = gm_member_id
            delegated_member = self._get_delegated_member(network)

            if netview in discovered_delegations:
                authority_member = discovered_delegations[netview]
                mapping_relation = const.MAPPING_RELATION_DELEGATED
            elif delegated_member:
                authority_member = delegated_member.member_id
                mapping_relation = const.MAPPING_RELATION_DELEGATED

            mapping_member_info = (netview_id + DELIMITER +
                                   authority_member + DELIMITER +
                                   mapping_relation)
            if mapping_member_info not in mapping_authority_members:
                mapping_authority_members.append(mapping_member_info)

            # get dhcp member
            dhcp_members = self._get_dhcp_members(network)
            for member in dhcp_members:
                mapping_member_info = (netview_id + DELIMITER +
                                       member.member_id + DELIMITER +
                                       const.SERVICE_TYPE_DHCP)
                if mapping_member_info not in mapping_service_members:
                    mapping_service_members.append(mapping_member_info)

            # get dns member
            dns_members = self._get_dns_members(network)
            for member in dns_members:
                mapping_member_info = (netview_id + DELIMITER +
                                       member.member_id + DELIMITER +
                                       const.SERVICE_TYPE_DNS)
                if mapping_member_info not in mapping_service_members:
                    mapping_service_members.append(mapping_member_info)

        return {'authority_members': mapping_authority_members,
                'service_members': mapping_service_members}
    def _find_mapping(self):
        session = self.context.session
        netview_id = None
        netview_name = None
        netview_shared = False

        # First check if mapping already exists
        network_id = self.subnet.get('network_id')
        subnet_id = self.subnet.get('id')
        netview_mappings = dbi.get_network_view_mappings(
            session, network_id=network_id, subnet_id=subnet_id)
        if netview_mappings:
            netview_id = netview_mappings[0].network_view_id
            netview_row = utils.find_one_in_list(
                'id', netview_id, self.discovered_network_views)
            self.mapping.network_view_id = netview_id
            self.mapping.network_view = netview_row.network_view
            self.mapping.authority_member = self._get_authority_member(
                netview_row.authority_member_id)
            self.mapping.shared = netview_row.shared
            self.mapping.dns_view = self._get_dns_view()
            self._update_service_member_mapping()
            LOG.info(_LI("Network view %(netview)s mapping found for "
                         "network %(network)s and subnet %(subnet)s"),
                     dict(netview=netview_row.network_view, network=network_id,
                          subnet=subnet_id))
            return

        # No mapping so find mapping
        mapping_attrs = self._get_mapping_attributes()
        matching_netviews = []

        # find mapping matches on common cases
        mapping_filters = self._get_mapping_filters(mapping_attrs)
        for mf in mapping_filters:
            if mf.values()[0] is None:
                continue
            matches = utils.find_in_list_by_condition(
                mf, self.discovered_mapping_conditions)
            if matches:
                netview_ids = [m.network_view_id for m in matches]
                matching_netviews += netview_ids

        # find network view id and name pair
        if matching_netviews:
            # get most matched network view id
            netview_id = Counter(matching_netviews).most_common(1)[0][0]
            netview_row = utils.find_one_in_list('id', netview_id,
                                                 self.discovered_network_views)
            netview_name = netview_row.network_view
            netview_shared = netview_row.shared
        else:
            # no matching found; use default network view scope
            netview_scope = self.grid_config.default_network_view_scope
            netview_name = self._get_network_view_by_scope(netview_scope,
                                                           mapping_attrs)
            netview_row = utils.find_one_in_list('network_view', netview_name,
                                                 self.discovered_network_views)
            if netview_row:
                netview_id = netview_row.id
                netview_shared = netview_row.shared

        self.mapping.network_view_id = netview_id
        self.mapping.network_view = netview_name
        if self.mapping.network_view_id:
            self.mapping.authority_member = self._get_authority_member()
            self.mapping.shared = netview_shared
        self.mapping.dns_view = self._get_dns_view()
    def test_mapping_management_mapping_members(self):
        # prepare grid
        self._create_default_grid()

        # prepare grid members
        self._create_simple_members()
        db_members = infoblox_db.get_members(self.ctx.session)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)

        # prepare network views
        netview_dict = {'default': gm_member.member_id}
        self._create_network_views(netview_dict)

        # get network view id
        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        netview_default_row = utils.find_one_in_list('network_view',
                                                     'default',
                                                     db_network_views)
        netview_id = netview_default_row.id

        # should be no mapping members
        db_mapping_members = infoblox_db.get_mapping_members(self.ctx.session)
        self.assertEqual(0, len(db_mapping_members))

        # test mapping member additions
        expected_rows = []
        member_id = db_members[0]['member_id']
        relation = const.MAPPING_RELATION_DELEGATED
        infoblox_db.add_mapping_member(self.ctx.session, netview_id, member_id,
                                       relation)
        expected_rows.append(netview_id + ':' + member_id + ':' + relation)

        member_id = db_members[1]['member_id']
        relation = const.MAPPING_RELATION_DELEGATED
        infoblox_db.add_mapping_member(self.ctx.session, netview_id, member_id,
                                       relation)
        expected_rows.append(netview_id + ':' + member_id + ':' + relation)

        db_mapping_members = infoblox_db.get_mapping_members(self.ctx.session)
        actual_rows = utils.get_composite_values_from_records(
            ['network_view_id', 'member_id', 'mapping_relation'],
            db_mapping_members, ':')
        self.assertEqual(expected_rows, actual_rows)

        # test mapping member update
        member_id = db_members[0]['member_id']
        relation = const.MAPPING_RELATION_GM_OWNED
        infoblox_db.update_mapping_member(self.ctx.session, netview_id,
                                          member_id, relation)
        expected_rows[0] = netview_id + ':' + member_id + ':' + relation

        db_mapping_members = infoblox_db.get_mapping_members(self.ctx.session)
        actual_rows = utils.get_composite_values_from_records(
            ['network_view_id', 'member_id', 'mapping_relation'],
            db_mapping_members, ':')
        self.assertEqual(expected_rows, actual_rows)

        # test mapping member removals
        member_id = db_members[0]['member_id']
        infoblox_db.remove_mapping_member(self.ctx.session, netview_id,
                                          member_id)
        db_mapping_members = infoblox_db.get_mapping_members(
            self.ctx.session, member_id=member_id)
        self.assertEqual([], db_mapping_members)
Beispiel #46
0
    def _find_mapping(self):
        session = self.context.session
        netview_id = None
        netview_name = None
        netview_shared = False

        # First check if mapping already exists
        network_id = self.subnet.get('network_id')
        subnet_id = self.subnet.get('id')
        netview_mappings = dbi.get_network_view_mappings(session,
                                                         network_id=network_id,
                                                         subnet_id=subnet_id)
        if netview_mappings:
            netview_id = netview_mappings[0].network_view_id
            netview_row = utils.find_one_in_list('id', netview_id,
                                                 self.discovered_network_views)
            self.mapping.network_view_id = netview_id
            self.mapping.network_view = netview_row.network_view
            self.mapping.authority_member = self._get_authority_member(
                netview_row.authority_member_id)
            self.mapping.shared = netview_row.shared
            self.mapping.dns_view = self._get_dns_view()
            self._update_service_member_mapping()
            LOG.info(
                _LI("Network view %(netview)s mapping found for "
                    "network %(network)s and subnet %(subnet)s"),
                dict(netview=netview_row.network_view,
                     network=network_id,
                     subnet=subnet_id))
            return

        # No mapping so find mapping
        mapping_attrs = self._get_mapping_attributes()
        matching_netviews = []

        # find mapping matches on common cases
        mapping_filters = self._get_mapping_filters(mapping_attrs)
        for mf in mapping_filters:
            if list(mf.values())[0] is None:
                continue
            matches = utils.find_in_list_by_condition(
                mf, self.discovered_mapping_conditions)
            if matches:
                netview_ids = [m.network_view_id for m in matches]
                matching_netviews += netview_ids

        # find network view id and name pair
        if matching_netviews:
            # get most matched network view id
            netview_id = Counter(matching_netviews).most_common(1)[0][0]
            netview_row = utils.find_one_in_list('id', netview_id,
                                                 self.discovered_network_views)
            netview_name = netview_row.network_view
            netview_shared = netview_row.shared
        else:
            # no matching found; use default network view scope
            netview_scope = self.grid_config.default_network_view_scope
            netview_name = self._get_network_view_by_scope(
                netview_scope, mapping_attrs)
            netview_row = utils.find_one_in_list('network_view', netview_name,
                                                 self.discovered_network_views)
            if netview_row:
                netview_id = netview_row.id
                netview_shared = netview_row.shared

        self.mapping.network_view_id = netview_id
        self.mapping.network_view = netview_name
        if self.mapping.network_view_id:
            self.mapping.authority_member = self._get_authority_member()
            self.mapping.shared = netview_shared
        self.mapping.dns_view = self._get_dns_view()
    def test_get_next_dhcp_member(self):
        # prepare grid
        self._create_default_grid()

        # prepare grid members
        member_list = [{'member_id': 'm1',
                        'member_name': 'm1.com',
                        'member_ip': '10.10.1.1',
                        'member_ipv6': None,
                        'member_type': const.MEMBER_TYPE_GRID_MASTER,
                        'member_status': 'ON'},
                       {'member_id': 'm2',
                        'member_name': 'm2.com',
                        'member_ip': '10.10.1.2',
                        'member_ipv6': 'fd44:acb:5df6:1083::22',
                        'member_type': const.MEMBER_TYPE_CP_MEMBER,
                        'member_status': 'ON'},
                       {'member_id': 'm3',
                        'member_name': 'm3.com',
                        'member_ip': '10.10.1.3',
                        'member_ipv6': None,
                        'member_type': const.MEMBER_TYPE_CP_MEMBER,
                        'member_status': 'ON'},
                       {'member_id': 'm4',
                        'member_name': 'm4.com',
                        'member_ip': '10.10.1.4',
                        'member_ipv6': None,
                        'member_type': const.MEMBER_TYPE_REGULAR_MEMBER,
                        'member_status': 'ON'}]
        self._create_members(member_list, self.grid_id)

        db_members = infoblox_db.get_members(self.ctx.session,
                                             grid_id=self.grid_id)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)
        m2_member = utils.find_one_in_list('member_id', 'm2', db_members)
        m3_member = utils.find_one_in_list('member_id', 'm3', db_members)
        m4_member = utils.find_one_in_list('member_id', 'm4', db_members)

        # create network views
        netview_dict = {'default': gm_member.member_id,
                        'testview': m2_member.member_id}
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        netview_default = utils.find_one_in_list('network_view',
                                                 'default',
                                                 db_network_views)
        netview_testview = utils.find_one_in_list('network_view',
                                                  'testview',
                                                  db_network_views)

        # add mapping members
        # - m1 (gm) is the authority member for 'default' view
        # - m2 is the authority member for 'testview' view as CPM
        infoblox_db.add_mapping_member(self.ctx.session,
                                       netview_default.id,
                                       gm_member.member_id,
                                       const.MAPPING_RELATION_GM_OWNED)
        infoblox_db.add_mapping_member(self.ctx.session,
                                       netview_testview.id,
                                       m2_member.member_id,
                                       const.MAPPING_RELATION_DELEGATED)

        # add service members
        # - m4 is a member that serves DHCP/DNS for a network under
        #   the non-delegated view, 'default'
        # - m2 is the delegated member to the network view, 'testview'
        infoblox_db.add_service_member(self.ctx.session,
                                       netview_default.id,
                                       m4_member.member_id,
                                       const.SERVICE_TYPE_DHCP)
        infoblox_db.add_service_member(self.ctx.session,
                                       netview_default.id,
                                       m4_member.member_id,
                                       const.SERVICE_TYPE_DNS)
        infoblox_db.add_service_member(self.ctx.session,
                                       netview_default.id,
                                       m2_member.member_id,
                                       const.SERVICE_TYPE_DHCP)
        infoblox_db.add_service_member(self.ctx.session,
                                       netview_default.id,
                                       m2_member.member_id,
                                       const.SERVICE_TYPE_DNS)

        dhcp_member = infoblox_db.get_next_dhcp_member(self.ctx.session,
                                                       self.grid_id)

        # only available dhcp member should be 'm3'
        self.assertEqual(m3_member.member_id, dhcp_member.member_id)
Beispiel #48
0
    def test_mapping_management_mapping_members(self):
        # prepare grid
        self._create_default_grid()

        # prepare grid members
        self._create_simple_members()
        db_members = infoblox_db.get_members(self.ctx.session)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)

        # prepare network views
        netview_dict = {'default': gm_member.member_id}
        self._create_network_views(netview_dict)

        # get network view id
        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        netview_default_row = utils.find_one_in_list('network_view', 'default',
                                                     db_network_views)
        netview_id = netview_default_row.id

        # should be no mapping members
        db_mapping_members = infoblox_db.get_mapping_members(self.ctx.session)
        self.assertEqual(0, len(db_mapping_members))

        # test mapping member additions
        expected_rows = []
        member_id = db_members[0]['member_id']
        relation = const.MAPPING_RELATION_DELEGATED
        infoblox_db.add_mapping_member(self.ctx.session, netview_id, member_id,
                                       relation)
        expected_rows.append(netview_id + ':' + member_id + ':' + relation)

        member_id = db_members[1]['member_id']
        relation = const.MAPPING_RELATION_DELEGATED
        infoblox_db.add_mapping_member(self.ctx.session, netview_id, member_id,
                                       relation)
        expected_rows.append(netview_id + ':' + member_id + ':' + relation)

        db_mapping_members = infoblox_db.get_mapping_members(self.ctx.session)
        actual_rows = utils.get_composite_values_from_records(
            ['network_view_id', 'member_id', 'mapping_relation'],
            db_mapping_members, ':')
        self.assertEqual(expected_rows, actual_rows)

        # test mapping member update
        member_id = db_members[0]['member_id']
        relation = const.MAPPING_RELATION_GM_OWNED
        infoblox_db.update_mapping_member(self.ctx.session, netview_id,
                                          member_id, relation)
        expected_rows[0] = netview_id + ':' + member_id + ':' + relation

        db_mapping_members = infoblox_db.get_mapping_members(self.ctx.session)
        actual_rows = utils.get_composite_values_from_records(
            ['network_view_id', 'member_id', 'mapping_relation'],
            db_mapping_members, ':')
        self.assertEqual(expected_rows, actual_rows)

        # test mapping member removals
        member_id = db_members[0]['member_id']
        infoblox_db.remove_mapping_member(self.ctx.session, netview_id,
                                          member_id)
        db_mapping_members = infoblox_db.get_mapping_members(
            self.ctx.session, member_id=member_id)
        self.assertEqual([], db_mapping_members)
    def test_service_member(self):
        # prepare grid
        self._create_default_grid()

        # prepare grid members
        member_list = [{'member_id': 'm1',
                        'member_name': 'm1.com',
                        'member_ip': '10.10.1.1',
                        'member_ipv6': None,
                        'member_type': const.MEMBER_TYPE_GRID_MASTER,
                        'member_status': 'ON'},
                       {'member_id': 'm2',
                        'member_name': 'm2.com',
                        'member_ip': '10.10.1.2',
                        'member_ipv6': 'fd44:acb:5df6:1083::22',
                        'member_type': const.MEMBER_TYPE_CP_MEMBER,
                        'member_status': 'ON'}]
        self._create_members(member_list, self.grid_id)

        db_members = infoblox_db.get_members(self.ctx.session,
                                             grid_id=self.grid_id)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)
        m2_member = utils.find_one_in_list('member_id', 'm2', db_members)

        # create network views
        netview_dict = {'default': gm_member.member_id}
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        netview_default = utils.find_one_in_list('network_view',
                                                 'default',
                                                 db_network_views)

        # test addition
        infoblox_db.add_service_member(self.ctx.session,
                                       netview_default.id,
                                       gm_member.member_id,
                                       const.SERVICE_TYPE_DHCP)

        infoblox_db.add_service_member(self.ctx.session,
                                       netview_default.id,
                                       m2_member.member_id,
                                       const.SERVICE_TYPE_DHCP)

        db_service_members = infoblox_db.get_service_members(
            self.ctx.session, netview_default.id)
        gm_dhcp_member = utils.find_one_in_list('member_id',
                                                gm_member.member_id,
                                                db_service_members)
        self.assertIsNotNone(gm_dhcp_member)
        m2_dhcp_member = utils.find_one_in_list('member_id',
                                                m2_member.member_id,
                                                db_service_members)
        self.assertIsNotNone(m2_dhcp_member)

        # test removal
        infoblox_db.remove_service_member(self.ctx.session, netview_default.id)
        db_service_members = infoblox_db.get_service_members(
            self.ctx.session, netview_default.id)
        gm_dhcp_member = utils.find_one_in_list('member_id',
                                                gm_member.member_id,
                                                db_service_members)
        self.assertIsNone(gm_dhcp_member)

        m2m_dhcp_member = utils.find_one_in_list('member_id',
                                                 m2_member.member_id,
                                                 db_service_members)
        self.assertIsNone(m2m_dhcp_member)
Beispiel #50
0
def sync_neutron_to_infoblox(context, credentials, grid_manager):
    """Sync neutron objects to Infoblox grid

    Prerequisites:
        1. network views to sync must have "Cloud Adapter ID" EA set.
        2. infoblox agent sync should have been processed and updated members
           and network views.
    """
    LOG.info("Starting migration...\n")

    delete_unknown_ips = cfg.CONF.delete_unknown_ips

    grid_config = grid_manager.grid_config
    grid_id = grid_config.grid_id
    session = context.session

    neutron_api = neutron_client.Client(**credentials)
    payload = neutron_api.list_networks()
    networks = payload['networks']
    if not networks:
        LOG.info("No network exists...Exiting...")
        return

    payload = neutron_api.list_subnets()
    subnets = payload['subnets']
    if not subnets:
        LOG.info("No subnet exists...Exiting...")
        return

    payload = neutron_api.list_ports()
    ports = payload['ports']
    nova_api = nova_client.Client(NOVA_API_VERSION,
                                  session=credentials['session'])

    instance_names_by_instance_id = dict()
    instance_names_by_floating_ip = dict()
    for server in nova_api.servers.list(search_opts={'all_tenants': 1}):
        instance_names_by_instance_id[server.id] = server.name
        floating_ips = []
        for net in server.addresses:
            floating_ips += [
                ip['addr'] for ip in server.addresses[net]
                if ip['OS-EXT-IPS:type'] == 'floating'
            ]
        for fip in floating_ips:
            instance_names_by_floating_ip[fip] = server.name

    user_id = neutron_api.httpclient.get_user_id()
    user_tenant_id = neutron_api.httpclient.get_project_id()

    ib_networks = []
    should_exit = False

    # sync subnets
    for subnet in subnets:
        subnet_id = subnet['id']
        subnet_name = subnet['name']
        network_id = subnet['network_id']
        network = utils.find_one_in_list('id', network_id, networks)
        if not network:
            LOG.warning("network (%s) is not found. Skipping subnet (%s)",
                        network_id, subnet_id)
            continue

        network_name = network['name']
        ib_cxt = ib_context.InfobloxContext(context,
                                            user_id,
                                            network,
                                            subnet,
                                            grid_config,
                                            plugin=neutron_api)
        db_mapped_netview = dbi.get_network_view_by_mapping(
            session,
            grid_id=grid_id,
            network_id=network_id,
            subnet_id=subnet_id)
        if db_mapped_netview:
            LOG.info("Mapping found for network (%s), subnet (%s)",
                     network_name, subnet_name)
            if len(db_mapped_netview) > 1:
                LOG.warning("More that one db_mapped_netview returned")
            if delete_unknown_ips:
                ib_network = ib_objects.Network.search(
                    ib_cxt.connector,
                    network_view=db_mapped_netview[0].network_view,
                    cidr=subnet.get('cidr'))
                ib_networks.append(ib_network)
            continue

        ipam_controller = ipam.IpamSyncController(ib_cxt)
        dns_controller = dns.DnsController(ib_cxt)

        rollback_list = []
        try:
            ib_network = ipam_controller.create_subnet(rollback_list)
            if ib_network:
                if delete_unknown_ips:
                    ib_networks.append(ib_network)
                dns_controller.create_dns_zones(rollback_list)
            LOG.info("Created network (%s), subnet (%s)", network_name,
                     subnet_name)
        except Exception as e:
            LOG.error(_LE("Error occurred: %(error)s"), {'error': e})
            for ib_obj in reversed(rollback_list):
                try:
                    ib_obj.delete()
                except ib_exc.InfobloxException as e:
                    LOG.warning(
                        _LW("Unable to delete %(obj)s due to "
                            "error: %(error)s."), {
                                'obj': ib_obj,
                                'error': e
                            })
            should_exit = True
            break

    if should_exit:
        LOG.info("Exiting due to the error in creating subnet...")
        return

    # sync ports
    for port in ports:
        port_id = port['id']
        port_name = port['name']
        port_mac_address = port['mac_address']
        tenant_id = port.get('tenant_id') or user_tenant_id
        network_id = port['network_id']
        device_owner = port['device_owner']
        device_id = port['device_id']

        instance_name = (instance_names_by_instance_id[device_id] if device_id
                         in instance_names_by_instance_id else None)

        network = utils.find_one_in_list('id', network_id, networks)
        if not network:
            LOG.error("network (%s) not found", network_id)
            break

        for ip_set in port.get('fixed_ips'):
            subnet_id = ip_set['subnet_id']
            ip_address = ip_set['ip_address']
            LOG.info("Adding port for %s: %s...", device_owner, ip_address)

            subnet = utils.find_one_in_list('id', subnet_id, subnets)
            if not subnet:
                should_exit = True
                LOG.error("subnet (%s) not found", subnet_id)
                break

            ib_cxt = ib_context.InfobloxContext(context,
                                                user_id,
                                                network,
                                                subnet,
                                                grid_config,
                                                plugin=neutron_api)
            connector = ib_cxt.connector
            netview = ib_cxt.mapping.network_view

            search_fields = {'network_view': netview, 'ip_address': ip_address}
            obj_type = ('ipv4address' if utils.get_ip_version(ip_address) == 4
                        else 'ipv6address')
            ib_address = connector.get_object(obj_type,
                                              search_fields,
                                              return_fields=['objects'],
                                              force_proxy=True)
            if ib_address and ib_address[0]['objects']:
                LOG.info("%s is found...no need to create", ip_address)
                continue

            ipam_controller = ipam.IpamSyncController(ib_cxt)
            dns_controller = dns.DnsController(ib_cxt)

            # for a floating ip port, check for its association.
            # if associated, then port info needs to be the associated port,
            # not the floating ip port because the associated port contains
            # actual attached device info
            is_floating_ip = False
            if ip_address in instance_names_by_floating_ip:
                db_floatingip = dbi.get_floatingip_by_ip_address(
                    session, ip_address)
                db_port = dbi.get_port_by_id(session,
                                             db_floatingip.fixed_port_id)
                port_id = db_port.id
                port_name = db_port.name
                tenant_id = db_port.tenant_id
                device_id = db_port.device_id
                device_owner = db_port.device_owner
                instance_name = instance_names_by_floating_ip[ip_address]
                is_floating_ip = True

            allocated_ip = ipam_controller.allocate_specific_ip(
                ip_address, port_mac_address, port_id, tenant_id, device_id,
                device_owner)
            if allocated_ip and device_owner:
                try:
                    dns_controller.bind_names(allocated_ip, instance_name,
                                              port_id, tenant_id, device_id,
                                              device_owner, is_floating_ip,
                                              port_name)
                except Exception as e:
                    should_exit = True
                    LOG.error("Unable to allocate ip (%s): %s", ip_address, e)
                    ipam_controller.deallocate_ip(allocated_ip)
                    break

            LOG.info("Allocated %s", ip_address)

        if should_exit:
            LOG.info("Existing due to error in port creation...")
            break

    if delete_unknown_ips:
        LOG.info("Start deleting unknown Fixed IP's from Infoblox...")
        for ib_network in ib_networks:

            nw_ea = ib_network.extattrs
            # Skip network if it doesn't have EA or if EA indicates it's
            # shared or external.
            if (not nw_ea or nw_ea.get('Is External')
                    or nw_ea.get('Is Shared')):
                continue

            LOG.info("Searching for Fixed IP: network_view='%s', cidr='%s'" %
                     (ib_network.network_view, ib_network.network))
            fixed_ips = ib_objects.FixedAddress.search_all(
                ib_cxt.connector,
                network_view=ib_network.network_view,
                network=ib_network.network)

            if not fixed_ips:
                LOG.info("No FixedIP found: network_view='%s', cidr='%s'" %
                         (ib_network.network_view, ib_network.network))
                continue

            for fixed_ip in fixed_ips:
                ea = fixed_ip.extattrs
                port_id = None
                if ea:
                    port_id = ea.get('Port ID')

                # Delete Fixed IP if:
                #   - Fixed IP does not have 'Port ID' EA, or
                #   - No port_id in neutron matches 'Port ID' EA value
                if not (port_id
                        and utils.find_one_in_list('id', port_id, ports)):
                    LOG.info("Deleting Fixed IP from Infoblox: '%s'" %
                             fixed_ip)
                    fixed_ip.delete()

    LOG.info("Ending migration...")
Beispiel #51
0
    def test_get_next_dhcp_member(self):
        # prepare grid
        self._create_default_grid()

        # prepare grid members
        member_list = [{
            'member_id': 'm1',
            'member_name': 'm1.com',
            'member_ip': '10.10.1.1',
            'member_ipv6': None,
            'member_type': const.MEMBER_TYPE_GRID_MASTER,
            'member_status': 'ON'
        }, {
            'member_id': 'm2',
            'member_name': 'm2.com',
            'member_ip': '10.10.1.2',
            'member_ipv6': 'fd44:acb:5df6:1083::22',
            'member_type': const.MEMBER_TYPE_CP_MEMBER,
            'member_status': 'ON'
        }, {
            'member_id': 'm3',
            'member_name': 'm3.com',
            'member_ip': '10.10.1.3',
            'member_ipv6': None,
            'member_type': const.MEMBER_TYPE_CP_MEMBER,
            'member_status': 'ON'
        }, {
            'member_id': 'm4',
            'member_name': 'm4.com',
            'member_ip': '10.10.1.4',
            'member_ipv6': None,
            'member_type': const.MEMBER_TYPE_REGULAR_MEMBER,
            'member_status': 'ON'
        }]
        self._create_members(member_list, self.grid_id)

        db_members = infoblox_db.get_members(self.ctx.session,
                                             grid_id=self.grid_id)
        gm_member = utils.find_one_in_list('member_type', 'GM', db_members)
        m2_member = utils.find_one_in_list('member_id', 'm2', db_members)
        m3_member = utils.find_one_in_list('member_id', 'm3', db_members)
        m4_member = utils.find_one_in_list('member_id', 'm4', db_members)

        # create network views
        netview_dict = {
            'default': gm_member.member_id,
            'testview': m2_member.member_id
        }
        self._create_network_views(netview_dict)

        db_network_views = infoblox_db.get_network_views(self.ctx.session)
        netview_default = utils.find_one_in_list('network_view', 'default',
                                                 db_network_views)
        netview_testview = utils.find_one_in_list('network_view', 'testview',
                                                  db_network_views)

        # add mapping members
        # - m1 (gm) is the authority member for 'default' view
        # - m2 is the authority member for 'testview' view as CPM
        infoblox_db.add_mapping_member(self.ctx.session, netview_default.id,
                                       gm_member.member_id,
                                       const.MAPPING_RELATION_GM_OWNED)
        infoblox_db.add_mapping_member(self.ctx.session, netview_testview.id,
                                       m2_member.member_id,
                                       const.MAPPING_RELATION_DELEGATED)

        # add service members
        # - m4 is a member that serves DHCP/DNS for a network under
        #   the non-delegated view, 'default'
        # - m2 is the delegated member to the network view, 'testview'
        infoblox_db.add_service_member(self.ctx.session, netview_default.id,
                                       m4_member.member_id,
                                       const.SERVICE_TYPE_DHCP)
        infoblox_db.add_service_member(self.ctx.session, netview_default.id,
                                       m4_member.member_id,
                                       const.SERVICE_TYPE_DNS)
        infoblox_db.add_service_member(self.ctx.session, netview_default.id,
                                       m2_member.member_id,
                                       const.SERVICE_TYPE_DHCP)
        infoblox_db.add_service_member(self.ctx.session, netview_default.id,
                                       m2_member.member_id,
                                       const.SERVICE_TYPE_DNS)

        dhcp_member = infoblox_db.get_next_dhcp_member(self.ctx.session,
                                                       self.grid_id)

        # only available dhcp member should be 'm3'
        self.assertEqual(m3_member.member_id, dhcp_member.member_id)