Esempio n. 1
0
    def sync_grid(self):
        """Synchronize an active grid.

        Only one active grid should be kept where grid_status is set to 'ON'.
        """
        session = self._context.session
        grid_connection = self._grid_config.get_grid_connection()
        grid_connection_json = jsonutils.dumps(grid_connection)

        db_grids = dbi.get_grids(session)
        db_grid_ids = utils.get_values_from_records('grid_id', db_grids)

        # update the existing grid or add new grid
        if self._grid_config.grid_id in db_grid_ids:
            dbi.update_grid(session, self._grid_config.grid_id,
                            self._grid_config.grid_name, grid_connection_json,
                            const.GRID_STATUS_ON)
        else:
            dbi.add_grid(session, self._grid_config.grid_id,
                         self._grid_config.grid_name, grid_connection_json,
                         const.GRID_STATUS_ON, utils.get_hash())

        # deleting grids are delicate operation so we won't allow it
        # but we will set grid status to OFF to unused grids.
        persisted_set = set(db_grid_ids)
        disable_set = persisted_set.difference([self._grid_config.grid_id])
        disabling_grid_ids = list(disable_set)
        for grid_id in disabling_grid_ids:
            dbi.update_grid(session,
                            grid_id,
                            grid_status=const.GRID_STATUS_OFF)
        session.flush()
def upgrade():
    op.add_column(
        'infoblox_grids',
        sa.Column('gm_id', sa.String(length=32), nullable=False,
                  default=utils.get_hash()))

    op.drop_constraint(
        constraint_name='uniq_infoblox_grid_members_grid_id_member_name',
        table_name='infoblox_grid_members',
        type_='unique')

    op.add_column(
        'infoblox_grid_members',
        sa.Column('member_dhcp_ip', sa.String(length=15), nullable=True))
    op.add_column(
        'infoblox_grid_members',
        sa.Column('member_dhcp_ipv6', sa.String(length=64), nullable=True))
    op.add_column(
        'infoblox_grid_members',
        sa.Column('member_dns_ip', sa.String(length=15), nullable=True))
    op.add_column(
        'infoblox_grid_members',
        sa.Column('member_dns_ipv6', sa.String(length=64), nullable=True))
    op.add_column(
        'infoblox_grid_members',
        sa.Column('member_wapi', sa.String(length=255), nullable=True))

    update_gm_ids()
Esempio n. 3
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()
Esempio n. 4
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()
Esempio n. 5
0
    def test_sync_member_with_cloud_support_with_member_licenses(self):
        member_mgr = member.GridMemberManager(self.test_grid_config)
        member_mgr.sync_grid()

        member_json = self.connector_fixture.get_object(
            base.FixtureResourceMap.FAKE_MEMBERS_WITH_CLOUD)
        license_json = self.connector_fixture.get_object(
            base.FixtureResourceMap.FAKE_MEMBER_LICENSES)
        self._mock_member_mgr(member_mgr,
                              discover_members=member_json,
                              discover_member_licenses=license_json)

        member_mgr.sync_members()

        # member_type is computed base on member licenses. To prove correctness
        # of member types, we need to first figure out which member has
        # 'CLOUD_API' license. A member with 'CLOUD_API' is CPM; otherwise
        # 'REGULAR'. Grid master member is 'GM'
        cloud_member_list = []
        cloud_lecensed_members = utils.find_in_list('type', ['CLOUD_API'],
                                                    license_json)
        member_hwids = utils.get_values_from_records('hwid',
                                                     cloud_lecensed_members)
        for m in member_json:
            member_id_arg = str(self.test_grid_config.grid_id) + m['host_name']
            member_id = utils.get_hash(member_id_arg)
            member_hwid = m['node_info'][0].get('hwid')
            if member_hwid in member_hwids:
                cloud_member_list.append(member_id)

        # now we know member licenses so get members in db
        members = dbi.get_members(self.ctx.session)
        self.assertEqual(len(member_json), len(members))
        # verify member types
        for m in members:
            if self.test_grid_config.grid_master_host == m['member_ip']:
                self.assertEqual('GM', m['member_type'])
            else:
                if m['member_id'] in cloud_member_list:
                    self.assertEqual('CPM', m['member_type'])
                else:
                    self.assertEqual('REGULAR', m['member_type'])
    def test_sync_member_with_cloud_support_with_member_licenses(self):
        member_mgr = member.GridMemberManager(self.test_grid_config)
        member_mgr.sync_grid()

        member_json = self.connector_fixture.get_object(
            base.FixtureResourceMap.FAKE_MEMBERS_WITH_CLOUD)
        license_json = self.connector_fixture.get_object(
            base.FixtureResourceMap.FAKE_MEMBER_LICENSES)
        self._mock_member_mgr(member_mgr, discover_members=member_json,
                              discover_member_licenses=license_json)

        member_mgr.sync_members()

        # member_type is computed base on member licenses. To prove correctness
        # of member types, we need to first figure out which member has
        # 'CLOUD_API' license. A member with 'CLOUD_API' is CPM; otherwise
        # 'REGULAR'. Grid master member is 'GM'
        cloud_member_list = []
        cloud_lecensed_members = utils.find_in_list('type', ['CLOUD_API'],
                                                    license_json)
        member_hwids = utils.get_values_from_records('hwid',
                                                     cloud_lecensed_members)
        for m in member_json:
            member_id_arg = str(self.test_grid_config.grid_id) + m['host_name']
            member_id = utils.get_hash(member_id_arg)
            member_hwid = m['node_info'][0].get('hwid')
            if member_hwid in member_hwids:
                cloud_member_list.append(member_id)

        # now we know member licenses so get members in db
        members = dbi.get_members(self.ctx.session)
        self.assertEqual(len(member_json), len(members))
        # verify member types
        for m in members:
            if self.test_grid_config.grid_master_host == m['member_ip']:
                self.assertEqual('GM', m['member_type'])
            else:
                if m['member_id'] in cloud_member_list:
                    self.assertEqual('CPM', m['member_type'])
                else:
                    self.assertEqual('REGULAR', m['member_type'])
Esempio n. 7
0
    def test_get_hash(self):
        hash_str = utils.get_hash("")
        self.assertEqual(32, len(hash_str))

        hash_str = utils.get_hash(None)
        self.assertEqual(32, len(hash_str))

        hash_str = utils.get_hash([])
        self.assertEqual(32, len(hash_str))

        hash_str = utils.get_hash()
        self.assertEqual(32, len(hash_str))

        hash_str = utils.get_hash(['abc'])
        self.assertEqual(32, len(hash_str))

        hash_str = utils.get_hash('I need a hash string!!!')
        self.assertEqual(32, len(hash_str))
Esempio n. 8
0
    def sync_grid(self):
        """Synchronize an active grid.

        Only one active grid should be kept where grid_status is set to 'ON'.
        """
        session = self._context.session
        grid_connection = self._grid_config.get_grid_connection()
        grid_connection_json = jsonutils.dumps(grid_connection)

        db_grids = dbi.get_grids(session)
        db_grid_ids = utils.get_values_from_records('grid_id', db_grids)

        # update the existing grid or add new grid
        if self._grid_config.grid_id in db_grid_ids:
            dbi.update_grid(session,
                            self._grid_config.grid_id,
                            self._grid_config.grid_name,
                            grid_connection_json,
                            const.GRID_STATUS_ON)
        else:
            dbi.add_grid(session,
                         self._grid_config.grid_id,
                         self._grid_config.grid_name,
                         grid_connection_json,
                         const.GRID_STATUS_ON,
                         utils.get_hash())

        # deleting grids are delicate operation so we won't allow it
        # but we will set grid status to OFF to unused grids.
        persisted_set = set(db_grid_ids)
        disable_set = persisted_set.difference([self._grid_config.grid_id])
        disabling_grid_ids = list(disable_set)
        for grid_id in disabling_grid_ids:
            dbi.update_grid(session,
                            grid_id,
                            grid_status=const.GRID_STATUS_OFF)
        session.flush()
from alembic import op
import sqlalchemy as sa
from sqlalchemy import update

from networking_infoblox.neutron.common import utils


# simple models for infoblox_grids and infoblox_grid_members with only the
# fields needed for the migration
infoblox_grids = sa.Table(
    'infoblox_grids',
    sa.MetaData(),
    sa.Column('grid_id', sa.Integer(), nullable=False),
    sa.Column('grid_status', sa.String(length=6), nullable=False),
    sa.Column('gm_id', sa.String(length=32), nullable=False,
              default=utils.get_hash()))

infoblox_grid_members = sa.Table(
    'infoblox_grid_members',
    sa.MetaData(),
    sa.Column('member_id', sa.String(length=32), nullable=False),
    sa.Column('grid_id', sa.Integer(), nullable=False),
    sa.Column('member_ip', sa.String(length=15), nullable=True),
    sa.Column('member_ipv6', sa.String(length=64), nullable=True),
    sa.Column('member_type', sa.String(length=6), nullable=False))


def upgrade():
    op.add_column(
        'infoblox_grids',
        sa.Column('gm_id', sa.String(length=32), nullable=False,
Esempio n. 10
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()
Esempio n. 11
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()