Ejemplo n.º 1
0
 def add_dhcp_options(self,
                      subnet_id,
                      port_id=None,
                      may_exist=True,
                      **columns):
     return cmd.AddDHCPOptionsCommand(self,
                                      subnet_id,
                                      port_id=port_id,
                                      may_exist=may_exist,
                                      **columns)
Ejemplo n.º 2
0
 def _test_dhcp_options_add(self, may_exist=True):
     fake_ext_ids = {'subnet_id': 'fake-subnet-id-' + str(may_exist)}
     fake_dhcp_options = fakes.FakeOvsdbRow.create_one_ovsdb_row(
         attrs={'external_ids': fake_ext_ids})
     self.transaction.insert.return_value = fake_dhcp_options
     cmd = commands.AddDHCPOptionsCommand(
         self.ovn_api, fake_ext_ids['subnet_id'], may_exist=may_exist,
         external_ids=fake_ext_ids)
     cmd.run_idl(self.transaction)
     self.transaction.insert.assert_called_once_with(
         self.ovn_api.dhcp_options_table)
     self.assertEqual(fake_ext_ids, fake_dhcp_options.external_ids)
Ejemplo n.º 3
0
 def test_dhcp_options_exists(self):
     fake_ext_ids = {'subnet_id': 'fake-subnet-id',
                     'port_id': 'fake-port-id'}
     fake_dhcp_options = fakes.FakeOvsdbRow.create_one_ovsdb_row(
         attrs={'external_ids': fake_ext_ids})
     self.ovn_api.dhcp_options_table.rows[fake_dhcp_options.uuid] = \
         fake_dhcp_options
     cmd = commands.AddDHCPOptionsCommand(
         self.ovn_api, fake_ext_ids['subnet_id'], fake_ext_ids['port_id'],
         may_exist=True, external_ids=fake_ext_ids)
     cmd.run_idl(self.transaction)
     self.transaction.insert.assert_not_called()
     self.assertEqual(fake_ext_ids, fake_dhcp_options.external_ids)
Ejemplo n.º 4
0
    def test_port_dhcp_opts_add_and_remove_extra_dhcp_opts(self):
        """Orphaned DHCP_Options row.

        In this test case a port is created with extra DHCP options.
        Since it has extra DHCP options a new row in the DHCP_Options is
        created for this port.
        Next the port is updated to delete the extra DHCP options.
        After the update, the Logical_Switch_Port.dhcpv4_options for this port
        should refer to the subnet DHCP_Options and the DHCP_Options row
        created for this port earlier should be deleted.
        """
        n1 = self._make_network(self.fmt, 'n1', True)
        res = self._create_subnet(self.fmt, n1['network']['id'], '10.0.0.0/24')
        subnet = self.deserialize(self.fmt, res)['subnet']

        res = self._create_subnet(self.fmt, n1['network']['id'], 'aef0::/64',
                                  ip_version=6)
        subnet_v6 = self.deserialize(self.fmt, res)['subnet']

        n_utils.get_random_mac = self.orig_get_random_mac
        expected_dhcp_options_rows = {
            subnet['id']: {
                'cidr': '10.0.0.0/24',
                'external_ids': {'subnet_id': subnet['id']},
                'options': {'server_id': '10.0.0.1',
                            'server_mac': '01:02:03:04:05:06',
                            'lease_time': str(12 * 60 * 60),
                            'mtu': str(n1['network']['mtu']),
                            'router': subnet['gateway_ip']}},
            subnet_v6['id']: {
                'cidr': 'aef0::/64',
                'external_ids': {'subnet_id': subnet_v6['id']},
                'options': {'server_id': '01:02:03:04:05:06'}}}

        data = {
            'port': {'network_id': n1['network']['id'],
                     'tenant_id': self._tenant_id,
                     'device_owner': 'compute:None',
                     'extra_dhcp_opts': [{'ip_version': 4, 'opt_name': 'mtu',
                                          'opt_value': '1100'},
                                         {'ip_version': 4,
                                          'opt_name': 'ntp-server',
                                          'opt_value': '8.8.8.8'},
                                         {'ip_version': 6,
                                          'opt_name': 'dns-server',
                                          'opt_value': 'aef0::100'}]}}
        port_req = self.new_create_request('ports', data, self.fmt)
        port_res = port_req.get_response(self.api)
        p1 = self.deserialize(self.fmt, port_res)['port']

        expected_dhcp_options_rows['v4-' + p1['id']] = {
            'cidr': '10.0.0.0/24',
            'external_ids': {'subnet_id': subnet['id'],
                             'port_id': p1['id']},
            'options': {'server_id': '10.0.0.1',
                        'server_mac': '01:02:03:04:05:06',
                        'lease_time': str(12 * 60 * 60),
                        'mtu': '1100',
                        'router': subnet['gateway_ip'],
                        'ntp_server': '8.8.8.8'}}

        expected_dhcp_options_rows['v6-' + p1['id']] = {
            'cidr': 'aef0::/64',
            'external_ids': {'subnet_id': subnet_v6['id'],
                             'port_id': p1['id']},
            'options': {'server_id': '01:02:03:04:05:06',
                        'dns_server': 'aef0::100'}}

        self._verify_dhcp_option_rows(expected_dhcp_options_rows)
        # The Logical_Switch_Port.dhcp(v4/v6)_options should refer to the
        # the port DHCP options.
        self._verify_dhcp_option_row_for_port(
            p1['id'], expected_dhcp_options_rows['v4-' + p1['id']],
            expected_dhcp_options_rows['v6-' + p1['id']])

        # Now update the port to delete the extra DHCP options
        data = {'port': {'extra_dhcp_opts': [{'ip_version': 4,
                                              'opt_name': 'mtu',
                                              'opt_value': None},
                                             {'ip_version': 4,
                                              'opt_name': 'ntp-server',
                                              'opt_value': None}]}}
        port_req = self.new_update_request('ports', data, p1['id'])
        port_req.get_response(self.api)

        # DHCP_Options row created for the port earlier should have been
        # deleted.
        del expected_dhcp_options_rows['v4-' + p1['id']]
        self._verify_dhcp_option_rows(expected_dhcp_options_rows)
        # The Logical_Switch_Port.dhcpv4_options for this port should refer to
        # the subnet DHCP options.
        self._verify_dhcp_option_row_for_port(
            p1['id'], expected_dhcp_options_rows[subnet['id']],
            expected_dhcp_options_rows['v6-' + p1['id']])

        # update the port again with extra DHCP options.
        data = {'port': {'extra_dhcp_opts': [{'ip_version': 4,
                                              'opt_name': 'mtu',
                                              'opt_value': '1200'},
                                             {'ip_version': 4,
                                              'opt_name': 'tftp-server',
                                              'opt_value': '8.8.8.8'}]}}

        port_req = self.new_update_request('ports', data, p1['id'])
        port_req.get_response(self.api)

        expected_dhcp_options_rows['v4-' + p1['id']] = {
            'cidr': '10.0.0.0/24',
            'external_ids': {'subnet_id': subnet['id'],
                             'port_id': p1['id']},
            'options': {'server_id': '10.0.0.1',
                        'server_mac': '01:02:03:04:05:06',
                        'lease_time': str(12 * 60 * 60),
                        'mtu': '1200',
                        'router': subnet['gateway_ip'],
                        'tftp_server': '8.8.8.8'}}
        self._verify_dhcp_option_rows(expected_dhcp_options_rows)
        self._verify_dhcp_option_row_for_port(
            p1['id'], expected_dhcp_options_rows['v4-' + p1['id']],
            expected_dhcp_options_rows['v6-' + p1['id']])

        # Disable DHCPv4 for this port. The DHCP_Options row created for this
        # port should be get deleted.
        data = {'port': {'extra_dhcp_opts': [{'ip_version': 4,
                                              'opt_name': 'dhcp_disabled',
                                              'opt_value': 'true'}]}}
        port_req = self.new_update_request('ports', data, p1['id'])
        port_req.get_response(self.api)

        del expected_dhcp_options_rows['v4-' + p1['id']]
        self._verify_dhcp_option_rows(expected_dhcp_options_rows)
        # The Logical_Switch_Port.dhcpv4_options for this port should be
        # empty.
        self._verify_dhcp_option_row_for_port(
            p1['id'], {}, expected_dhcp_options_rows['v6-' + p1['id']])

        # Disable DHCPv6 for this port. The DHCP_Options row created for this
        # port should be get deleted.
        data = {'port': {'extra_dhcp_opts': [{'ip_version': 6,
                                              'opt_name': 'dhcp_disabled',
                                              'opt_value': 'true'}]}}
        port_req = self.new_update_request('ports', data, p1['id'])
        port_req.get_response(self.api)

        del expected_dhcp_options_rows['v6-' + p1['id']]
        self._verify_dhcp_option_rows(expected_dhcp_options_rows)
        # The Logical_Switch_Port.dhcpv4_options for this port should be
        # empty.
        self._verify_dhcp_option_row_for_port(p1['id'], {})

        # Add orphaned DHCP_Options row for this port.
        with self.nb_idl_transaction(self.fake_api, check_error=True) as txn:
            txn.add(cmd.AddDHCPOptionsCommand(
                self.fake_api, subnet['id'],
                port_id=p1['id'],
                cidr='10.0.0.0/24',
                options={'server_id': '10.0.0.1',
                         'server_mac': '01:02:03:04:05:06',
                         'lease_time': str(12 * 60 * 60),
                         'mtu': '1200',
                         'router': subnet['gateway_ip'],
                         'tftp_server': '8.8.8.8'},
                external_ids={'subnet_id': subnet['id'],
                              'port_id': p1['id']}))
        # Port deletion will have a final checking to make sure no orphaned
        # DHCP_Options related to port left behind.
        port_req = self.new_delete_request('ports', p1['id'])
        port_req.get_response(self.api)
        self._verify_dhcp_option_rows(expected_dhcp_options_rows)
Ejemplo n.º 5
0
    def _modify_resources_in_nb_db(self):
        fake_api = mock.MagicMock()
        fake_api.idl = self.monitor_nb_db_idl
        fake_api._tables = self.monitor_nb_db_idl.tables

        with self.nb_idl_transaction(fake_api, check_error=True) as txn:
            for lswitch_name in self.create_lswitches:
                external_ids = {
                    ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: lswitch_name
                }
                txn.add(
                    cmd.AddLSwitchCommand(fake_api,
                                          lswitch_name,
                                          True,
                                          external_ids=external_ids))

            for lswitch_name in self.delete_lswitches:
                txn.add(cmd.DelLSwitchCommand(fake_api, lswitch_name, True))

            for lport_name, lswitch_name in self.create_lswitch_ports:
                external_ids = {ovn_const.OVN_PORT_NAME_EXT_ID_KEY: lport_name}
                txn.add(
                    cmd.AddLSwitchPortCommand(fake_api,
                                              lport_name,
                                              lswitch_name,
                                              True,
                                              external_ids=external_ids))

            for lport_name, lswitch_name in self.delete_lswitch_ports:
                txn.add(
                    cmd.DelLSwitchPortCommand(fake_api, lport_name,
                                              lswitch_name, True))

            for lrouter_name in self.create_lrouters:
                external_ids = {
                    ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: lrouter_name
                }
                txn.add(
                    cmd.AddLRouterCommand(fake_api,
                                          lrouter_name,
                                          True,
                                          external_ids=external_ids))

            for lrouter_name in self.delete_lrouters:
                txn.add(cmd.DelLRouterCommand(fake_api, lrouter_name, True))

            for lrport, lrouter_name in self.create_lrouter_ports:
                txn.add(
                    cmd.AddLRouterPortCommand(fake_api, lrport, lrouter_name))

            for lrport, lrouter_name, networks in self.update_lrouter_ports:
                txn.add(
                    cmd.UpdateLRouterPortCommand(fake_api, lrport,
                                                 lrouter_name, True,
                                                 **{'networks': [networks]}))

            for lrport, lrouter_name in self.delete_lrouter_ports:
                txn.add(
                    cmd.DelLRouterPortCommand(fake_api, lrport, lrouter_name,
                                              True))

            for lrouter_name, ip_prefix, nexthop in self.create_lrouter_routes:
                txn.add(
                    cmd.AddStaticRouteCommand(fake_api,
                                              lrouter_name,
                                              ip_prefix=ip_prefix,
                                              nexthop=nexthop))

            for lrouter_name, ip_prefix, nexthop in self.delete_lrouter_routes:
                txn.add(
                    cmd.DelStaticRouteCommand(fake_api, lrouter_name,
                                              ip_prefix, nexthop, True))

            for acl in self.create_acls:
                txn.add(cmd.AddACLCommand(fake_api, **acl))

            for lport_name, lswitch_name in self.delete_acls:
                txn.add(
                    cmd.DelACLCommand(fake_api, lswitch_name, lport_name,
                                      True))

            for name, ip_version in self.create_address_sets:
                ovn_name = utils.ovn_addrset_name(name, ip_version)
                external_ids = {ovn_const.OVN_SG_NAME_EXT_ID_KEY: name}
                txn.add(
                    cmd.AddAddrSetCommand(fake_api,
                                          ovn_name,
                                          True,
                                          external_ids=external_ids))

            for name, ip_version in self.delete_address_sets:
                ovn_name = utils.ovn_addrset_name(name, ip_version)
                txn.add(cmd.DelAddrSetCommand(fake_api, ovn_name, True))

            for name, ip_version, ip_adds, ip_dels in self.update_address_sets:
                ovn_name = utils.ovn_addrset_name(name, ip_version)
                txn.add(
                    cmd.UpdateAddrSetCommand(fake_api, ovn_name, ip_adds,
                                             ip_dels, True))

            for lport_name in self.reset_lport_dhcpv4_options:
                txn.add(
                    cmd.SetLSwitchPortCommand(fake_api,
                                              lport_name,
                                              True,
                                              dhcpv4_options=[]))

            for dhcp_opts in self.stale_lport_dhcpv4_options:
                txn.add(
                    cmd.AddDHCPOptionsCommand(
                        fake_api,
                        dhcp_opts['subnet_id'],
                        port_id=dhcp_opts['port_id'],
                        cidr=dhcp_opts['cidr'],
                        options=dhcp_opts['options'],
                        external_ids=dhcp_opts['external_ids']))

            for row_uuid in self.missed_dhcpv4_options:
                txn.add(cmd.DelDHCPOptionsCommand(fake_api, row_uuid))

            for dhcp_opts in self.dirty_dhcpv4_options:
                txn.add(
                    cmd.AddDHCPOptionsCommand(fake_api,
                                              dhcp_opts['subnet_id'],
                                              port_id=dhcp_opts.get('port_id'),
                                              external_ids={
                                                  'subnet_id':
                                                  dhcp_opts['subnet_id'],
                                                  'port_id':
                                                  dhcp_opts.get('port_id')
                                              },
                                              options={'foo': 'bar'}))

            for port_id in self.lport_dhcpv4_disabled:
                txn.add(
                    cmd.SetLSwitchPortCommand(
                        fake_api,
                        port_id,
                        True,
                        dhcpv4_options=[self.lport_dhcpv4_disabled[port_id]]))

        with self.nb_idl_transaction(fake_api, check_error=True) as txn:
            for dhcp_opts in self.stale_lport_dhcpv4_options:
                if dhcp_opts['port_id'] in self.orphaned_lport_dhcpv4_options:
                    continue
                uuid = self.mech_driver._nb_ovn.get_port_dhcp_options(
                    dhcp_opts['subnet_id'], dhcp_opts['port_id'])['uuid']
                txn.add(
                    cmd.SetLSwitchPortCommand(fake_api,
                                              lport_name,
                                              True,
                                              dhcpv4_options=[uuid]))