Ejemplo n.º 1
0
    def execute(self,
                loadbalancer,
                amphora,
                availability_zone,
                vrrp_port=None):
        LOG.debug("Calculating network delta for amphora id: %s",
                  amphora.get(constants.ID))

        if vrrp_port is None:
            vrrp_port = self.network_driver.get_port(
                amphora[constants.VRRP_PORT_ID])
            vrrp_port_network_id = vrrp_port.network_id
        else:
            vrrp_port_network_id = vrrp_port[constants.NETWORK_ID]

        # Figure out what networks we want
        # seed with lb network(s)
        if availability_zone:
            management_nets = (
                [availability_zone.get(constants.MANAGEMENT_NETWORK)]
                or CONF.controller_worker.amp_boot_network_list)
        else:
            management_nets = CONF.controller_worker.amp_boot_network_list
        desired_network_ids = {vrrp_port_network_id}.union(management_nets)
        db_lb = self.loadbalancer_repo.get(
            db_apis.get_session(), id=loadbalancer[constants.LOADBALANCER_ID])
        for pool in db_lb.pools:
            member_networks = [
                self.network_driver.get_subnet(member.subnet_id).network_id
                for member in pool.members if member.subnet_id
            ]
            desired_network_ids.update(member_networks)

        nics = self.network_driver.get_plugged_networks(
            amphora[constants.COMPUTE_ID])
        # assume we don't have two nics in the same network
        actual_network_nics = dict((nic.network_id, nic) for nic in nics)

        del_ids = set(actual_network_nics) - desired_network_ids
        delete_nics = list(
            n_data_models.Interface(network_id=net_id) for net_id in del_ids)

        add_ids = desired_network_ids - set(actual_network_nics)
        add_nics = list(
            n_data_models.Interface(network_id=net_id) for net_id in add_ids)
        delta = n_data_models.Delta(amphora_id=amphora[constants.ID],
                                    compute_id=amphora[constants.COMPUTE_ID],
                                    add_nics=add_nics,
                                    delete_nics=delete_nics)
        return delta.to_dict(recurse=True)
Ejemplo n.º 2
0
    def execute(self, loadbalancer, amphora):
        LOG.debug("Calculating network delta for amphora id: %s", amphora.id)

        # Figure out what networks we want
        # seed with lb network(s)
        vrrp_port = self.network_driver.get_port(amphora.vrrp_port_id)
        desired_network_ids = {vrrp_port.network_id}.union(
            CONF.controller_worker.amp_boot_network_list)

        for pool in loadbalancer.pools:
            member_networks = [
                self.network_driver.get_subnet(member.subnet_id).network_id
                for member in pool.members if member.subnet_id
            ]
            desired_network_ids.update(member_networks)

        nics = self.network_driver.get_plugged_networks(amphora.compute_id)
        # assume we don't have two nics in the same network
        actual_network_nics = dict((nic.network_id, nic) for nic in nics)

        del_ids = set(actual_network_nics) - desired_network_ids
        delete_nics = list(actual_network_nics[net_id] for net_id in del_ids)

        add_ids = desired_network_ids - set(actual_network_nics)
        add_nics = list(
            n_data_models.Interface(network_id=net_id) for net_id in add_ids)
        delta = n_data_models.Delta(amphora_id=amphora.id,
                                    compute_id=amphora.compute_id,
                                    add_nics=add_nics,
                                    delete_nics=delete_nics)
        return delta
Ejemplo n.º 3
0
    def plug_port(self, amphora, port):
        try:
            interface = self.nova_client.servers.interface_attach(
                server=amphora.compute_id,
                net_id=None,
                fixed_ip=None,
                port_id=port.id)
            plugged_interface = self._nova_interface_to_octavia_interface(
                amphora.compute_id, interface)
        except nova_client_exceptions.NotFound as e:
            if 'Instance' in str(e):
                raise base.AmphoraNotFound(str(e))
            elif 'Network' in str(e):
                raise base.NetworkNotFound(str(e))
            else:
                raise base.PlugNetworkException(str(e))
        except nova_client_exceptions.Conflict:
            LOG.info('Port %(portid)s is already plugged, '
                     'skipping', {'portid': port.id})
            plugged_interface = n_data_models.Interface(
                compute_id=amphora.compute_id,
                network_id=port.network_id,
                port_id=port.id,
                fixed_ips=port.fixed_ips)
        except Exception:
            message = _('Error plugging amphora (compute_id: '
                        '{compute_id}) into port '
                        '{port_id}.').format(compute_id=amphora.compute_id,
                                             port_id=port.id)
            LOG.exception(message)
            raise base.PlugNetworkException(message)

        return plugged_interface
Ejemplo n.º 4
0
 def _port_to_octavia_interface(self, compute_id, port):
     fixed_ips = [utils.convert_fixed_ip_dict_to_model(fixed_ip)
                  for fixed_ip in port.get('fixed_ips', [])]
     return network_models.Interface(compute_id=compute_id,
                                     network_id=port['network_id'],
                                     port_id=port['id'],
                                     fixed_ips=fixed_ips)
Ejemplo n.º 5
0
 def _nova_interface_to_octavia_interface(self, compute_id, nova_interface):
     fixed_ips = [utils.convert_fixed_ip_dict_to_model(fixed_ip)
                  for fixed_ip in nova_interface.fixed_ips]
     return network_models.Interface(compute_id=compute_id,
                                     network_id=nova_interface.net_id,
                                     port_id=nova_interface.port_id,
                                     fixed_ips=fixed_ips)
 def test_get_interfaces_to_unplug(self):
     if1 = network_models.Interface()
     if1.network_id = 'if1-net'
     if1.port_id = 'if1-port'
     if1.fixed_ips = [network_models.FixedIP(ip_address='10.0.0.1')]
     if2 = network_models.Interface()
     if2.network_id = 'if2-net'
     if2.port_id = 'if2-port'
     if2.fixed_ips = [network_models.FixedIP(ip_address='11.0.0.1')]
     interfaces = [if1, if2]
     unpluggers = self.driver._get_interfaces_to_unplug(
         interfaces, 'if1-net')
     self.assertEqual([if1], unpluggers)
     unpluggers = self.driver._get_interfaces_to_unplug(
         interfaces, 'if1-net', ip_address='10.0.0.1')
     self.assertEqual([if1], unpluggers)
     unpluggers = self.driver._get_interfaces_to_unplug(
         interfaces, 'if1-net', ip_address='11.0.0.1')
     self.assertEqual([], unpluggers)
     unpluggers = self.driver._get_interfaces_to_unplug(
         interfaces, 'if3-net')
     self.assertEqual([], unpluggers)
Ejemplo n.º 7
0
 def plug_network(self, compute_id, network_id, ip_address=None):
     LOG.debug(
         "Network %s no-op, plug_network compute_id %s, network_id "
         "%s, ip_address %s", self.__class__.__name__, compute_id,
         network_id, ip_address)
     self.networkconfigconfig[(compute_id, network_id,
                               ip_address)] = (compute_id, network_id,
                                               ip_address, 'plug_network')
     return network_models.Interface(id=uuidutils.generate_uuid(),
                                     compute_id=compute_id,
                                     network_id=network_id,
                                     fixed_ips=[],
                                     port_id=uuidutils.generate_uuid())
Ejemplo n.º 8
0
 def attach_network_or_port(self, compute_id, network_id, ip_address=None,
                            port_id=None):
     LOG.debug("Compute %s no-op, attach_network_or_port compute_id %s,"
               "network_id %s, ip_address %s, port_id %s",
               self.__class__.__name__, compute_id,
               network_id, ip_address, port_id)
     self.computeconfig[(compute_id, network_id, ip_address, port_id)] = (
         compute_id, network_id, ip_address, port_id,
         'attach_network_or_port')
     return network_models.Interface(
         id=uuidutils.generate_uuid(),
         compute_id=compute_id,
         network_id=network_id,
         fixed_ips=[],
         port_id=uuidutils.generate_uuid()
     )
Ejemplo n.º 9
0
    def execute(self, loadbalancers_list, amphora, member_list):
        LOG.debug("Calculating network delta for amphora id: %s", amphora.id)
        # Figure out what networks we want
        # seed with lb network(s)

        desired_network_ids = set(
            CONF.a10_controller_worker.amp_boot_network_list[:])
        member_networks = []
        for loadbalancer in loadbalancers_list:
            for pool in loadbalancer.pools:
                member_networks = [
                    self.network_driver.get_subnet(member.subnet_id).network_id
                    for member in pool.members
                    if member.subnet_id and member in member_list
                ]
                desired_network_ids.update(member_networks)

        loadbalancer_networks = [
            self.network_driver.get_subnet(
                loadbalancer.vip.subnet_id).network_id
            for loadbalancer in loadbalancers_list
            if loadbalancer.vip.subnet_id
        ]
        desired_network_ids.update(loadbalancer_networks)
        LOG.debug("[NetIF] desired_network_ids.update{0}".format(
            desired_network_ids))

        nics = self.network_driver.get_plugged_networks(amphora.compute_id)
        # assume we don't have two nics in the same network
        actual_network_nics = dict((nic.network_id, nic) for nic in nics)
        LOG.debug(
            "[NetIF] actual_network_nics {0}".format(actual_network_nics))

        del_ids = set(actual_network_nics) - desired_network_ids
        delete_nics = list(actual_network_nics[net_id] for net_id in del_ids)

        add_ids = desired_network_ids - set(actual_network_nics)
        add_nics = list(
            n_data_models.Interface(network_id=net_id) for net_id in add_ids)
        delta = n_data_models.Delta(amphora_id=amphora.id,
                                    compute_id=amphora.compute_id,
                                    add_nics=add_nics,
                                    delete_nics=delete_nics)
        return delta
Ejemplo n.º 10
0
    def execute(self,
                loadbalancer,
                amphora,
                availability_zone,
                vrrp_port=None):
        LOG.debug("Calculating network delta for amphora id: %s", amphora.id)

        if vrrp_port is None:
            vrrp_port = self.network_driver.get_port(amphora.vrrp_port_id)
        if availability_zone:
            management_nets = (
                [availability_zone.get(constants.MANAGEMENT_NETWORK)]
                or CONF.controller_worker.amp_boot_network_list)
        else:
            management_nets = CONF.controller_worker.amp_boot_network_list
        desired_network_ids = {vrrp_port.network_id}.union(management_nets)

        for pool in loadbalancer.pools:
            member_networks = [
                self.network_driver.get_subnet(member.subnet_id).network_id
                for member in pool.members if member.subnet_id
            ]
            desired_network_ids.update(member_networks)

        nics = self.network_driver.get_plugged_networks(amphora.compute_id)
        # assume we don't have two nics in the same network
        actual_network_nics = dict((nic.network_id, nic) for nic in nics)

        del_ids = set(actual_network_nics) - desired_network_ids
        delete_nics = list(actual_network_nics[net_id] for net_id in del_ids)

        add_ids = desired_network_ids - set(actual_network_nics)
        add_nics = list(
            n_data_models.Interface(network_id=net_id) for net_id in add_ids)
        delta = n_data_models.Delta(amphora_id=amphora.id,
                                    compute_id=amphora.compute_id,
                                    add_nics=add_nics,
                                    delete_nics=delete_nics)
        return delta
Ejemplo n.º 11
0
    def execute(self, loadbalancer, amphora):
        LOG.debug("Calculating network delta for amphora id: %s", amphora.id)

        # Figure out what networks we want
        # seed with lb network(s)
        subnet = self.network_driver.get_subnet(loadbalancer.vip.subnet_id)
        desired_network_ids = {
            CONF.controller_worker.amp_network, subnet.network_id
        }

        if not loadbalancer.listeners:
            return None

        for listener in loadbalancer.listeners:
            if (not listener.default_pool) or (
                    not listener.default_pool.members):
                continue
            member_networks = [
                self.network_driver.get_subnet(member.subnet_id).network_id
                for member in listener.default_pool.members if member.subnet_id
            ]
            desired_network_ids.update(member_networks)

        nics = self.network_driver.get_plugged_networks(amphora.compute_id)
        # assume we don't have two nics in the same network
        actual_network_nics = dict((nic.network_id, nic) for nic in nics)

        del_ids = set(actual_network_nics) - desired_network_ids
        delete_nics = list(actual_network_nics[net_id] for net_id in del_ids)

        add_ids = desired_network_ids - set(actual_network_nics)
        add_nics = list(
            n_data_models.Interface(network_id=net_id) for net_id in add_ids)
        delta = n_data_models.Delta(amphora_id=amphora.id,
                                    compute_id=amphora.compute_id,
                                    add_nics=add_nics,
                                    delete_nics=delete_nics)
        return delta
Ejemplo n.º 12
0
 def _interface(port_id):
     return [data_models.Interface(port_id=port_id)]
Ejemplo n.º 13
0
 def _interface(network_id):
     return [data_models.Interface(network_id=network_id)]
Ejemplo n.º 14
0
    def test_handle_network_delta(self, mock_get_net_driver):
        mock_net_driver = mock.MagicMock()
        self.db_amphora_mock.to_dict.return_value = {
            constants.ID: AMPHORA_ID, constants.COMPUTE_ID: COMPUTE_ID}
        mock_get_net_driver.return_value = mock_net_driver

        nic1 = data_models.Interface()
        nic1.network_id = uuidutils.generate_uuid()
        nic2 = data_models.Interface()
        nic2.network_id = uuidutils.generate_uuid()
        interface1 = mock.MagicMock()
        interface1.port_id = uuidutils.generate_uuid()
        port1 = mock.MagicMock()
        port1.network_id = uuidutils.generate_uuid()
        fixed_ip = mock.MagicMock()
        fixed_ip.subnet_id = uuidutils.generate_uuid()
        port1.fixed_ips = [fixed_ip]
        subnet = mock.MagicMock()
        network = mock.MagicMock()

        delta = data_models.Delta(amphora_id=self.db_amphora_mock.id,
                                  compute_id=self.db_amphora_mock.compute_id,
                                  add_nics=[nic1],
                                  delete_nics=[nic2, nic2, nic2]
                                  ).to_dict(recurse=True)

        mock_net_driver.plug_network.return_value = interface1
        mock_net_driver.get_port.return_value = port1
        mock_net_driver.get_network.return_value = network
        mock_net_driver.get_subnet.return_value = subnet

        mock_net_driver.unplug_network.side_effect = [
            None, net_base.NetworkNotFound, Exception]

        handle_net_delta_obj = network_tasks.HandleNetworkDelta()
        result = handle_net_delta_obj.execute(self.amphora_mock,
                                              delta)

        mock_net_driver.plug_network.assert_called_once_with(
            self.db_amphora_mock.compute_id, nic1.network_id)
        mock_net_driver.get_port.assert_called_once_with(interface1.port_id)
        mock_net_driver.get_network.assert_called_once_with(port1.network_id)
        mock_net_driver.get_subnet.assert_called_once_with(fixed_ip.subnet_id)

        self.assertEqual({self.db_amphora_mock.id: [port1.to_dict()]}, result)

        mock_net_driver.unplug_network.assert_called_with(
            self.db_amphora_mock.compute_id, nic2.network_id)

        # Revert
        delta2 = data_models.Delta(amphora_id=self.db_amphora_mock.id,
                                   compute_id=self.db_amphora_mock.compute_id,
                                   add_nics=[nic1, nic1],
                                   delete_nics=[nic2, nic2, nic2]
                                   ).to_dict(recurse=True)

        mock_net_driver.unplug_network.reset_mock()
        handle_net_delta_obj.revert(
            failure.Failure.from_exception(Exception('boom')), None, None)
        mock_net_driver.unplug_network.assert_not_called()

        mock_net_driver.unplug_network.reset_mock()
        handle_net_delta_obj.revert(None, None, None)
        mock_net_driver.unplug_network.assert_not_called()

        mock_net_driver.unplug_network.reset_mock()
        handle_net_delta_obj.revert(None, None, delta2)
Ejemplo n.º 15
0
    def test_calculate_delta(self, mock_get_session, mock_get_lb,
                             mock_get_net_driver):
        mock_driver = mock.MagicMock()
        mock_get_lb.return_value = self.db_load_balancer_mock

        self.db_amphora_mock.to_dict.return_value = {
            constants.ID: AMPHORA_ID, constants.COMPUTE_ID: COMPUTE_ID,
            constants.VRRP_PORT_ID: PORT_ID}
        mock_get_net_driver.return_value = mock_driver
        mock_driver.get_plugged_networks.return_value = [
            data_models.Interface(network_id='netid')]
        mock_driver.get_port.return_value = data_models.Port(
            network_id='netid')
        EMPTY = {}
        empty_deltas = {self.db_amphora_mock.id: data_models.Delta(
            amphora_id=AMPHORA_ID,
            compute_id=COMPUTE_ID,
            add_nics=[],
            delete_nics=[]).to_dict(recurse=True)}

        calc_delta = network_tasks.CalculateDelta()

        self.assertEqual(EMPTY,
                         calc_delta.execute(self.load_balancer_mock, {}))

        # Test with one amp and no pools, nothing plugged
        # Delta should be empty
        mock_driver.reset_mock()

        self.db_amphora_mock.load_balancer = self.db_load_balancer_mock
        self.db_load_balancer_mock.amphorae = [self.db_amphora_mock]
        self.db_load_balancer_mock.pools = []
        self.assertEqual(empty_deltas,
                         calc_delta.execute(self.load_balancer_mock, {}))
        mock_driver.get_plugged_networks.assert_called_once_with(COMPUTE_ID)

        # Pool mock should be configured explicitly for each test
        pool_mock = mock.MagicMock()
        self.db_load_balancer_mock.pools = [pool_mock]

        # Test with one amp and one pool but no members, nothing plugged
        # Delta should be empty
        pool_mock.members = []
        self.assertEqual(empty_deltas,
                         calc_delta.execute(self.load_balancer_mock, {}))

        # Test with one amp and one pool and one member, nothing plugged
        # Delta should be one additional subnet to plug
        mock_driver.reset_mock()
        member_mock = mock.MagicMock()
        member_mock.subnet_id = 1
        pool_mock.members = [member_mock]
        mock_driver.get_subnet.return_value = data_models.Subnet(id=2,
                                                                 network_id=3)

        ndm = data_models.Delta(amphora_id=self.db_amphora_mock.id,
                                compute_id=self.db_amphora_mock.compute_id,
                                add_nics=[
                                    data_models.Interface(network_id=3)],
                                delete_nics=[]).to_dict(recurse=True)
        self.assertEqual({self.db_amphora_mock.id: ndm},
                         calc_delta.execute(self.load_balancer_mock, {}))

        vrrp_port_call = mock.call(PORT_ID)
        mock_driver.get_port.assert_has_calls([vrrp_port_call])
        self.assertEqual(1, mock_driver.get_port.call_count)

        member_subnet_call = mock.call(member_mock.subnet_id)
        mock_driver.get_subnet.assert_has_calls([member_subnet_call])
        self.assertEqual(1, mock_driver.get_subnet.call_count)

        # Test with one amp and one pool and one member, already plugged
        # Delta should be empty
        mock_driver.reset_mock()
        member_mock = mock.MagicMock()
        member_mock.subnet_id = 1
        pool_mock.members = [member_mock]
        mock_driver.get_plugged_networks.return_value = [
            data_models.Interface(network_id=3),
            data_models.Interface(network_id='netid')]

        self.assertEqual(empty_deltas,
                         calc_delta.execute(self.load_balancer_mock, {}))

        # Test with one amp and one pool and one member, wrong network plugged
        # Delta should be one network to add and one to remove
        mock_driver.reset_mock()
        member_mock = mock.MagicMock()
        member_mock.subnet_id = 1
        pool_mock.members = [member_mock]
        mock_driver.get_plugged_networks.return_value = [
            data_models.Interface(network_id=2),
            data_models.Interface(network_id='netid')]

        ndm = data_models.Delta(amphora_id=self.db_amphora_mock.id,
                                compute_id=self.db_amphora_mock.compute_id,
                                add_nics=[
                                    data_models.Interface(network_id=3)],
                                delete_nics=[
                                    data_models.Interface(network_id=2)]
                                ).to_dict(recurse=True)
        self.assertEqual({self.db_amphora_mock.id: ndm},
                         calc_delta.execute(self.load_balancer_mock, {}))

        # Test with one amp and one pool and no members, one network plugged
        # Delta should be one network to remove
        mock_driver.reset_mock()
        pool_mock.members = []
        mock_driver.get_plugged_networks.return_value = [
            data_models.Interface(network_id=2),
            data_models.Interface(network_id='netid')
        ]

        ndm = data_models.Delta(amphora_id=self.db_amphora_mock.id,
                                compute_id=self.db_amphora_mock.compute_id,
                                add_nics=[],
                                delete_nics=[
                                    data_models.Interface(network_id=2)]
                                ).to_dict(recurse=True)
        self.assertEqual({self.db_amphora_mock.id: ndm},
                         calc_delta.execute(self.load_balancer_mock, {}))
Ejemplo n.º 16
0
PORT_ID = uuidutils.generate_uuid()
SUBNET_ID = uuidutils.generate_uuid()
NETWORK_ID = uuidutils.generate_uuid()
IP_ADDRESS = "172.24.41.1"
VIP = o_data_models.Vip(port_id=t_constants.MOCK_PORT_ID,
                        subnet_id=t_constants.MOCK_SUBNET_ID,
                        qos_policy_id=t_constants.MOCK_QOS_POLICY_ID1)
VIP2 = o_data_models.Vip(port_id=t_constants.MOCK_PORT_ID2,
                         subnet_id=t_constants.MOCK_SUBNET_ID2,
                         qos_policy_id=t_constants.MOCK_QOS_POLICY_ID2)
LB = o_data_models.LoadBalancer(vip=VIP)
LB2 = o_data_models.LoadBalancer(vip=VIP2)
FIRST_IP = {"ip_address": IP_ADDRESS, "subnet_id": SUBNET_ID}
FIXED_IPS = [FIRST_IP]
INTERFACE = data_models.Interface(id=uuidutils.generate_uuid(),
                                  compute_id=COMPUTE_ID, fixed_ips=FIXED_IPS,
                                  port_id=PORT_ID)
AMPS_DATA = [o_data_models.Amphora(id=t_constants.MOCK_AMP_ID1,
                                   vrrp_port_id=t_constants.MOCK_VRRP_PORT_ID1,
                                   vrrp_ip=t_constants.MOCK_VRRP_IP1),
             o_data_models.Amphora(id=t_constants.MOCK_AMP_ID2,
                                   vrrp_port_id=t_constants.MOCK_VRRP_PORT_ID2,
                                   vrrp_ip=t_constants.MOCK_VRRP_IP2)
             ]
UPDATE_DICT = {constants.TOPOLOGY: None}
_session_mock = mock.MagicMock()


class TestException(Exception):

    def __init__(self, value):