Exemple #1
0
 def __init__(self, conf):
     super(ContrailInterfaceDriver, self).__init__(conf)
     self._port_dict = {}
     self._client = self._connect_to_api_server()
     self._vrouter_client = ContrailVRouterApi()
     timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
     timer.start(interval=2)
Exemple #2
0
 def __init__(self, get_connection):
     super(VRouterVIFDriver, self).__init__(get_connection)
     self._vrouter_semaphore = eventlet.semaphore.Semaphore()
     self._vrouter_client = ContrailVRouterApi(
         doconnect=True, semaphore=self._vrouter_semaphore)
     timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
     timer.start(interval=2)
 def __init__(self, vm_uuid, nic_left, nic_right, other_nics=None,
              root_helper='sudo', cfg_file=None, update=False,
              pool_id=None, gw_ip=None, namespace_name=None):
     self.vm_uuid = vm_uuid
     if namespace_name is None:
         self.namespace = self.NETNS_PREFIX + self.vm_uuid
     else:
         self.namespace = namespace_name
     if pool_id:
         self.namespace = self.namespace + ":" + pool_id
     self.nic_left = nic_left
     self.nic_right = nic_right
     self.root_helper = root_helper
     self.nics = other_nics or []
     if self.nic_left:
         self.nic_left['name'] = (self.LEFT_DEV_PREFIX +
                              self.nic_left['uuid'])[:self.DEV_NAME_LEN]
         self.nics.append(self.nic_left)
     if self.nic_right:
         self.nic_right['name'] = (self.RIGH_DEV_PREFIX +
                                   self.nic_right['uuid'])[:self.DEV_NAME_LEN]
         self.nics.append(self.nic_right)
     self.ip_ns = ip_lib.IPWrapper(root_helper=self.root_helper,
                                   namespace=self.namespace)
     self.vrouter_client = ContrailVRouterApi()
     self.cfg_file = cfg_file
     self.update = update
     self.gw_ip = gw_ip
 def test_unicode(self):
     self._start_server()
     api = ContrailVRouterApi(server_port=self._port)
     self._try_connect(api)
     response = api.add_port(str(uuid.uuid1()), str(uuid.uuid1()), 'tapX',
                             'aa:bb:cc:ee:ff:00',
                             display_name=u'p\u227do')
     self.assertTrue(response)
def interface_register(vm, vmi, iface_name, project=None):
    api = ContrailVRouterApi()
    mac = vmi.virtual_machine_interface_mac_addresses.mac_address[0]
    if project:
        proj_id = project.uuid
    else:
        proj_id = None
    api.add_port(vm.uuid, vmi.uuid, iface_name, mac, display_name=vm.name, vm_project_id=proj_id)
 def test_unicode(self):
     self._start_server()
     api = ContrailVRouterApi(server_port=self._port)
     self._try_connect(api)
     response = api.add_port(str(uuid.uuid1()),
                             str(uuid.uuid1()),
                             'tapX',
                             'aa:bb:cc:ee:ff:00',
                             display_name=u'p\u227do')
     self.assertTrue(response)
Exemple #7
0
    def __init__(self, **kwargs):
        if self.vnc_handle:
            pass
        else:
            super(ConfigCNI,
                  self).__init__(api_server_host=kwargs['api_server'],
                                 tenant=kwargs['tenant'])

        self.vmi = ConfigVMI()
        self.vm = ConfigVM()
        self.vn = ConfigVN()
        self.vrouter = ContrailVRouterApi()
Exemple #8
0
 def __init__(self, vm_uuid, nic_left, nic_right, root_helper='sudo'):
     self.vm_uuid = vm_uuid
     self.namespace = self.NETNS_PREFIX + self.vm_uuid
     self.nic_left = nic_left
     self.nic_right = nic_right
     self.root_helper = root_helper
     self.nic_left['name'] = (self.LEFT_DEV_PREFIX +
                              self.nic_left['uuid'])[:self.DEV_NAME_LEN]
     self.nic_right['name'] = (self.RIGH_DEV_PREFIX +
                               self.nic_right['uuid'])[:self.DEV_NAME_LEN]
     self.ip_ns = ip_lib.IPWrapper(root_helper=self.root_helper,
                                   namespace=self.namespace)
     self.vrouter_client = ContrailVRouterApi()
Exemple #9
0
    def __init__(self, project, vm_obj, vmi_obj, ifname, **kwargs):
        self.project = project
        self.vm = vm_obj
        self.vmi = vmi_obj
        self.ifname = ifname
        self.vmi_out = kwargs.get('vmi_out', None)
        self.ifname_out = kwargs.get('ifname_out', None)

        vrouter_semaphore = gevent.lock.Semaphore()
        self.vrouter_client = ContrailVRouterApi(doconnect=True,
                                                 semaphore=vrouter_semaphore)
        self.vrouter_client.connect()
        self.vrouter_agent_connection = self.vrouter_client._client
def teardown(pod_namespace, pod_name, docker_id):
    client = ContrailClient()
    manager = LxcManager()
    short_id = docker_id[0:11]

    api = ContrailVRouterApi()

    _, podName = getDockerPod(docker_id)
    vmi = vrouter_interface_by_name(podName)
    if vmi is not None:
        api.delete_port(vmi)

    manager.clear_interfaces(short_id)
    Shell.run('ip netns delete %s' % short_id)
Exemple #11
0
def teardown(pod_namespace, pod_name, docker_id):
    client = ContrailClient()
    manager = LxcManager()
    short_id = docker_id[0:11]

    api = ContrailVRouterApi()

    _, podName = getDockerPod(docker_id)
    vmi = vrouter_interface_by_name(podName)
    if vmi is not None:
        api.delete_port(vmi)

    manager.clear_interfaces(short_id)
    Shell.run('ip netns delete %s' % short_id)
    def create(self, vnName, ipAddress, ipv6Address=None):
        interfaceName = 'veth' + self.vmName
        vm_instance = vnc_api.VirtualMachine(name=self.vmName)
        self.vnc_client.virtual_machine_create(vm_instance)
        vm_interface = vnc_api.VirtualMachineInterface(name=interfaceName,
                                                       parent_obj=vm_instance)
        vn = OpenContrailVN(vnName).VNget()
        vm_interface.set_virtual_network(vn)
        self.vnc_client.virtual_machine_interface_create(vm_interface)
        vm_interface = self.vnc_client.virtual_machine_interface_read(
            id=vm_interface.uuid)
        ipuuid = str(uuid.uuid4())
        ip = vnc_api.InstanceIp(name=ipuuid,
                                instance_ip_address=ipAddress.split('/')[0])
        ip.set_virtual_machine_interface(vm_interface)
        ip.set_virtual_network(vn)
        self.vnc_client.instance_ip_create(ip)

        mac = vm_interface.virtual_machine_interface_mac_addresses.mac_address[
            0]
        vrouterInterface = interfaceName + 'p0'

        if ipv6Address:
            ipv6uuid = str(uuid.uuid4())
            ipv6 = vnc_api.InstanceIp(
                name=ipv6uuid, instance_ip_address=ipv6Address.split('/')[0])
            ipv6.set_instance_ip_family('v6')
            ipv6.uuid = ipv6uuid
            ipv6.set_virtual_machine_interface(vm_interface)
            ipv6.set_virtual_network(vn)
            self.vnc_client.instance_ip_create(ipv6)
            ContrailVRouterApi().add_port(
                vm_instance.uuid,
                vm_interface.uuid,
                vrouterInterface,
                mac,
                display_name=vm_instance.name,
                vm_project_id=self.tenant.uuid,
                port_type='NovaVMPort',
                ip6_address=ipv6Address.split('/')[0])
        else:
            ContrailVRouterApi().add_port(vm_instance.uuid,
                                          vm_interface.uuid,
                                          vrouterInterface,
                                          mac,
                                          display_name=vm_instance.name,
                                          vm_project_id=self.tenant.uuid,
                                          port_type='NovaVMPort')
 def delete(self):
     interfaceName = 'veth' + self.vmName
     try:
         ip = self.vnc_client.instance_ip_read(fq_name_str=interfaceName)
         if ip:
             self.vnc_client.instance_ip_delete(id=ip.uuid)
     except:
         logging.debug('no instance ip')
     try:
         vm_interface = self.vnc_client.virtual_machine_interface_read(
             fq_name=[self.vmName, interfaceName])
         if vm_interface:
             ip_list = vm_interface.get_instance_ip_back_refs()
             if ip_list:
                 for ip in ip_list:
                     ip_obj = self.vnc_client.instance_ip_read(
                         id=ip['uuid'])
                     self.vnc_client.instance_ip_delete(id=ip_obj.uuid)
             ContrailVRouterApi().delete_port(vm_interface.uuid)
             self.vnc_client.virtual_machine_interface_delete(
                 id=vm_interface.uuid)
     except:
         logging.debug('no vm interface')
     try:
         vm = self.vnc_client.virtual_machine_read(fq_name_str=self.vmName)
         if vm:
             self.vnc_client.virtual_machine_delete(id=vm.uuid)
     except:
         logging.debug('no vm')
 def __init__(self, conf):
     super(ContrailInterfaceDriver, self).__init__(conf)
     self._port_dict = {}
     self._client = self._connect_to_api_server()
     self._vrouter_client = ContrailVRouterApi()
     timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
     timer.start(interval=2)
Exemple #15
0
 def createVmi(self, vnName, requestedIp):
     interfaceName = 'veth' + self.vmName
     try:
         ip = self.vnc_client.instance_ip_read(fq_name_str=interfaceName)
         if ip:
             print 'deleting ip instance'
             self.vnc_client.instance_ip_delete(id=ip.uuid)
     except:
         print 'no ip instance'
     try:
         vm_interface = self.vnc_client.virtual_machine_interface_read(
             fq_name=[self.vmName, interfaceName])
         if vm_interface:
             print 'deleting vm interface'
             self.vnc_client.virtual_machine_interface_delete(
                 id=vm_interface.uuid)
     except:
         print 'no vm interface'
     try:
         vm = self.vnc_client.virtual_machine_read(fq_name_str=self.vmName)
         if vm:
             print 'deleting vm'
             self.vnc_client.virtual_machine_delete(id=vm.uuid)
     except:
         print 'no vm'
     vm_instance = vnc_api.VirtualMachine(name=self.vmName)
     self.vnc_client.virtual_machine_create(vm_instance)
     vm_interface = vnc_api.VirtualMachineInterface(name=interfaceName,
                                                    parent_obj=vm_instance)
     vn = OpenContrailVN(vnName).VNget()
     vm_interface.set_virtual_network(vn)
     self.vnc_client.virtual_machine_interface_create(vm_interface)
     vm_interface = self.vnc_client.virtual_machine_interface_read(
         id=vm_interface.uuid)
     ip = vnc_api.InstanceIp(name=interfaceName,
                             instance_ip_address=requestedIp.split('/')[0])
     ip.set_virtual_machine_interface(vm_interface)
     ip.set_virtual_network(vn)
     self.vnc_client.instance_ip_create(ip)
     ip = self.vnc_client.instance_ip_read(id=ip.uuid)
     ipAddress = ip.get_instance_ip_address()
     print 'ipaddress: %s' % ipAddress
     subnet = vn.network_ipam_refs[0]['attr'].ipam_subnets[0]
     gw = subnet.default_gateway
     mac = vm_interface.virtual_machine_interface_mac_addresses.mac_address[
         0]
     vrouterInterface = interfaceName + 'p0'
     ContrailVRouterApi().add_port(vm_instance.uuid,
                                   vm_interface.uuid,
                                   vrouterInterface,
                                   mac,
                                   display_name=vm_instance.name,
                                   vm_project_id=self.tenant.uuid,
                                   port_type='NovaVMPort')
     return {
         'ip': ipAddress,
         'interface': interfaceName,
         'gateway': gw,
         'mac': mac
     }
Exemple #16
0
 def deleteVmi(self):
     interfaceName = 'veth' + self.vmName
     try:
         ip = self.vnc_client.instance_ip_read(fq_name_str=interfaceName)
         if ip:
             print 'deleting ip instance'
             self.vnc_client.instance_ip_delete(id=ip.uuid)
     except:
         print 'no ip instance'
     try:
         vm_interface = self.vnc_client.virtual_machine_interface_read(
             fq_name=[self.vmName, interfaceName])
         if vm_interface:
             print 'deleting vm interface'
             ContrailVRouterApi().delete_port(vm_interface.uuid)
             #vrouter_control.interface_unregister(vm_interface.uuid)
             self.vnc_client.virtual_machine_interface_delete(
                 id=vm_interface.uuid)
     except:
         print 'no vm interface'
     try:
         vm = self.vnc_client.virtual_machine_read(fq_name_str=self.vmName)
         if vm:
             print 'deleting vm'
             self.vnc_client.virtual_machine_delete(id=vm.uuid)
     except:
         print 'no vm'
 def delete(self):
     self.vmName = '7e2b3fa4'
     interfaceName = 'vethca335617'
     try:
         ip = self.vnc_client.instance_ip_read(fq_name_str=interfaceName)
         if ip:
             self.vnc_client.instance_ip_delete(id=ip.uuid)
     except:
         print 'no inst ip'
     try:
         vm_interface = self.vnc_client.virtual_machine_interface_read(
             fq_name_str='default-domain:' + self.tenant.name + ':' +
             interfaceName)
         if vm_interface:
             ip_list = vm_interface.get_instance_ip_back_refs()
             if ip_list:
                 for ip in ip_list:
                     ip_obj = self.vnc_client.instance_ip_read(
                         id=ip['uuid'])
                     self.vnc_client.instance_ip_delete(id=ip_obj.uuid)
             ContrailVRouterApi().delete_port(vm_interface.uuid)
             self.vnc_client.virtual_machine_interface_delete(
                 id=vm_interface.uuid)
     except:
         print 'no vm int'
     try:
         vm = self.vnc_client.virtual_machine_read(fq_name_str=self.vmName)
         if vm:
             self.vnc_client.virtual_machine_delete(id=vm.uuid)
     except:
         print 'no vm'
 def __init__(self, vm_uuid, nic_left, nic_right, other_nics=None,
              root_helper='sudo', cfg_file=None, update=False,
              pool_id=None, gw_ip=None, namespace_name=None):
     self.vm_uuid = vm_uuid
     if namespace_name is None:
         self.namespace = self.NETNS_PREFIX + self.vm_uuid
     else:
         self.namespace = namespace_name
     if pool_id:
         self.namespace = self.namespace + ":" + pool_id
     self.nic_left = nic_left
     self.nic_right = nic_right
     self.root_helper = root_helper
     self.nics = other_nics or []
     if self.nic_left:
         self.nic_left['name'] = (self.LEFT_DEV_PREFIX +
                              self.nic_left['uuid'])[:self.DEV_NAME_LEN]
         self.nics.append(self.nic_left)
     if self.nic_right:
         self.nic_right['name'] = (self.RIGH_DEV_PREFIX +
                                   self.nic_right['uuid'])[:self.DEV_NAME_LEN]
         self.nics.append(self.nic_right)
     self.ip_ns = ip_lib.IPWrapper(root_helper=self.root_helper,
                                   namespace=self.namespace)
     self.vrouter_client = ContrailVRouterApi()
     self.cfg_file = cfg_file
     self.update = update
     self.gw_ip = gw_ip
def main():
	parser = argparse.ArgumentParser()
	# "--mac-address", metadata.MacAddress,
	# 	"--vm", metadata.InstanceId, "--vmi", metadata.NicId,
	# 	"--interface", masterName, "add", c.DockerId)
	parser.add_argument('--mac-address')
	parser.add_argument('--vm')
	parser.add_argument('--vmi')
	parser.add_argument('--interface')
	parser.add_argument('command', choices=['add'])
	parser.add_argument('dockerId')
	args = parser.parse_args()
	if args.command == 'add':
		api = ContrailVRouterApi()
		api.add_port(args.vm, args.vmi, args.interface, args.mac_address, port_type='NovaVMPort', display_name=args.dockerId)
	else:
		print "No command specified"
def interface_register(vm, vmi, iface_name, project=None, vrouter_api=None):
    api = vrouter_api or ContrailVRouterApi()
    mac = vmi.virtual_machine_interface_mac_addresses.mac_address[0]
    if project:
        proj_id = project.uuid
    else:
        proj_id = None
    api.add_port(vm.uuid, vmi.uuid, iface_name, mac, display_name=vm.name,
                 vm_project_id=proj_id)
 def __init__(self, get_connection=None):
     if get_connection:
         super(VRouterVIFDriver, self).__init__(get_connection)
     else:
         # OpenStack Kilo compatibility
         super(VRouterVIFDriver, self).__init__()
     self._vrouter_semaphore = eventlet.semaphore.Semaphore()
     self._vrouter_client = ContrailVRouterApi(doconnect=True, semaphore=self._vrouter_semaphore)
     timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
     timer.start(interval=2)
Exemple #22
0
class NetnsMonitor(object):
    def __init__(self, project, vm_obj, vmi_obj, ifname, **kwargs):
        self.project = project
        self.vm = vm_obj
        self.vmi = vmi_obj
        self.ifname = ifname
        self.vmi_out = kwargs.get('vmi_out', None)
        self.ifname_out = kwargs.get('ifname_out', None)

        vrouter_semaphore = gevent.lock.Semaphore()
        self.vrouter_client = ContrailVRouterApi(doconnect=True,
                                                 semaphore=vrouter_semaphore)
        self.vrouter_client.connect()
        self.vrouter_agent_connection = self.vrouter_client._client

    def keepalive(self):
        self.vrouter_client.periodic_connection_check()
        current_agent_connection = self.vrouter_client._client
        if not current_agent_connection:
            # vrouter agent is down, Try checking...
            return
        if self.vrouter_agent_connection != current_agent_connection:
            # Initial connection object to vrouter agent is different from
            # the current object, vrouter agent is restarted, plug the netns
            # vif's again.
            interface_register(self.vm,
                               self.vmi,
                               self.ifname,
                               project=self.project)
            if self.vmi_out:
                interface_register(self.vm,
                                   self.vmi_out,
                                   self.ifname_out,
                                   project=self.project)
            self.vrouter_agent_connection = current_agent_connection

    def monitor(self):
        while True:
            gevent.sleep(INTERVAL)
            self.keepalive()
    def __init__(self, project, vm_obj, vmi_obj, ifname, **kwargs):
        self.project = project
        self.vm = vm_obj
        self.vmi = vmi_obj
        self.ifname = ifname
        self.vmi_out = kwargs.get('vmi_out', None)
        self.ifname_out = kwargs.get('ifname_out', None)

        vrouter_semaphore = gevent.lock.Semaphore()
        self.vrouter_client = ContrailVRouterApi(doconnect=True,
                                                 semaphore=vrouter_semaphore)
        self.vrouter_client.connect()
        self.vrouter_agent_connection = self.vrouter_client._client
class NetnsMonitor(object):
    def __init__(self, project, vm_obj, vmi_obj, ifname, **kwargs):
        self.project = project
        self.vm = vm_obj
        self.vmi = vmi_obj
        self.ifname = ifname
        self.vmi_out = kwargs.get('vmi_out', None)
        self.ifname_out = kwargs.get('ifname_out', None)

        vrouter_semaphore = gevent.lock.Semaphore()
        self.vrouter_client = ContrailVRouterApi(doconnect=True,
                                                 semaphore=vrouter_semaphore)
        self.vrouter_client.connect()
        self.vrouter_agent_connection = self.vrouter_client._client

    def keepalive(self):
         self.vrouter_client.periodic_connection_check()
         current_agent_connection = self.vrouter_client._client
         if not current_agent_connection:
             # vrouter agent is down, Try checking...
             return
         if self.vrouter_agent_connection != current_agent_connection:
             # Initial connection object to vrouter agent is different from
             # the current object, vrouter agent is restarted, plug the netns
             # vif's again.
             interface_register(self.vm, self.vmi, self.ifname,
                                project=self.project)
             if self.vmi_out:
                 interface_register(self.vm, self.vmi_out, self.ifname_out,
                                    project=self.project)
             self.vrouter_agent_connection = current_agent_connection

    def monitor(self):
        while True:
            gevent.sleep(INTERVAL)
            self.keepalive()
class VRouterVIFDriver(LibvirtBaseVIFDriver):
    """VIF driver for VRouter when running Neutron."""
    
    PORT_TYPE = 'NovaVMPort'

    def __init__(self, get_connection):
        super(VRouterVIFDriver, self).__init__(get_connection)
        self._vrouter_client = ContrailVRouterApi()
        timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
        timer.start(interval=2)

    def _keep_alive(self):
        self._vrouter_client.periodic_connection_check()

    @staticmethod
    def _get_br_name(dev):
        """Returns the bridge name for a tap device.
        This is lxc related stuff. To work around the fact, that libvirt does
        not support direct passthrough of devices to LXC."""
        return 'br%s' % dev[3:]

    def _create_bridge(self, dev, instance):
        """Creating a bridge and returning its name"""
        br_name = self._get_br_name(dev)

        try:
            linux_net.LinuxBridgeInterfaceDriver.ensure_bridge(br_name, dev)
            linux_net._execute('ip', 'link', 'set', br_name, 'promisc', 'on',
                               run_as_root=True)
        except processutils.ProcessExecutionError:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

        return br_name

    def get_config(self, instance, vif, image_meta, inst_type):
        conf = super(VRouterVIFDriver, self).get_config(instance, vif,
                                                        image_meta, inst_type)
        dev = self.get_vif_devname(vif)
        if cfg.CONF.libvirt.virt_type == 'lxc':
            # for lxc we need to pass a bridge to libvirt
            br_name = self._get_br_name(dev)
            designer.set_vif_host_backend_bridge_config(conf, br_name)
        else:
            designer.set_vif_host_backend_ethernet_config(conf, dev)
        designer.set_vif_bandwidth_config(conf, inst_type)

        return conf

    def plug(self, instance, vif):
        dev = self.get_vif_devname(vif)

        try:
            linux_net.create_tap_dev(dev)
        except processutils.ProcessExecutionError:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

        if cfg.CONF.libvirt.virt_type == 'lxc':
            dev = self._create_bridge(dev, instance)

        kwargs = {
            'ip_address': vif['network']['subnets'][0]['ips'][0]['address'],
            'vn_id': vif['network']['id'],
            'display_name': instance['display_name'],
            'hostname': instance['hostname'],
            'host': instance['host'],
            'vm_project_id': instance['project_id'],
            'port_type': self.PORT_TYPE,
        }
        try:
            result = self._vrouter_client.add_port(instance['uuid'],
                                                   vif['id'],
                                                   dev,
                                                   vif['address'],
                                                   **kwargs)
            if not result:
                LOG.exception(_LE("Failed while plugging vif"),
                              instance=instance)
        except TApplicationException:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

    def unplug(self, instance, vif):
        dev = self.get_vif_devname(vif)

        try:
            self._vrouter_client.delete_port(vif['id'])
	    #delegate the deletion of tap device to a deffered thread
            worker_thread = threading.Thread(target=self.delete_device, \
		name='contrailvif', args=(dev,))
	    worker_thread.start()
        except (TApplicationException, processutils.ProcessExecutionError,\
	    RuntimeError):
            LOG.exception(_LE("Failed while unplugging vif"),
                          instance=instance)

    def delete_device(self, dev):
        time.sleep(2)
        LOG.debug(dev)
        if cfg.CONF.libvirt.virt_type == 'lxc':
            linux_net.LinuxBridgeInterfaceDriver.remove_bridge(
                    self._get_br_name(dev))
        linux_net.delete_net_dev(dev)
class VRouterVIFDriver(LibvirtBaseVIFDriver):
    """VIF driver for VRouter when running Neutron."""
    
    PORT_TYPE = 'NovaVMPort'

    def __init__(self, get_connection):
        super(VRouterVIFDriver, self).__init__(get_connection)
        self._vrouter_client = ContrailVRouterApi()
        timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
        timer.start(interval=2)

    def _keep_alive(self):
        self._vrouter_client.periodic_connection_check()

    def get_config(self, instance, vif, image_meta, inst_type):
        conf = super(VRouterVIFDriver, self).get_config(instance, vif,
                                                        image_meta, inst_type)
        dev = self.get_vif_devname(vif)
        designer.set_vif_host_backend_ethernet_config(conf, dev)
        designer.set_vif_bandwidth_config(conf, inst_type)

        return conf

    def plug(self, instance, vif):
        dev = self.get_vif_devname(vif)

        try:
            linux_net.create_tap_dev(dev)
        except processutils.ProcessExecutionError:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

        kwargs = {
            'ip_address': vif['network']['subnets'][0]['ips'][0]['address'],
            'vn_id': vif['network']['id'],
            'display_name': instance['display_name'],
            'hostname': instance['hostname'],
            'host': instance['host'],
            'vm_project_id': instance['project_id'],
            'port_type': self.PORT_TYPE,
        }
        try:
            result = self._vrouter_client.add_port(instance['uuid'],
                                                   vif['id'],
                                                   dev,
                                                   vif['address'],
                                                   **kwargs)
            if not result:
                LOG.exception(_LE("Failed while plugging vif"),
                              instance=instance)
        except TApplicationException:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

    def unplug(self, instance, vif):
        dev = self.get_vif_devname(vif)

        try:
            self._vrouter_client.delete_port(vif['id'])
            linux_net.delete_net_dev(dev)
        except (TApplicationException, processutils.ProcessExecutionError):
            LOG.exception(_LE("Failed while unplugging vif"),
                          instance=instance)
Exemple #27
0
class OpenContrailVIFDriver(object):
    def __init__(self):
        self._vrouter_semaphore = eventlet.semaphore.Semaphore()
        self._vrouter_client = ContrailVRouterApi(
            doconnect=True, semaphore=self._vrouter_semaphore)
        timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
        timer.start(interval=2)

    def _keep_alive(self):
        self._vrouter_client.periodic_connection_check()

    def plug(self, instance, vif):
        vif_type = vif['type']

        LOG.debug('Plug vif_type=%(vif_type)s instance=%(instance)s '
                  'vif=%(vif)s',
                  {'vif_type': vif_type, 'instance': instance,
                   'vif': vif})

        if_local_name = 'veth%s' % vif['id'][:8]
        if_remote_name = 'ns%s' % vif['id'][:8]

        # Device already exists so return.
        if linux_net.device_exists(if_local_name):
            return
        undo_mgr = utils.UndoManager()

        try:
            utils.execute('ip', 'link', 'add', if_local_name, 'type', 'veth',
                          'peer', 'name', if_remote_name, run_as_root=True)
            undo_mgr.undo_with(lambda: utils.execute(
                'ip', 'link', 'delete', if_local_name, run_as_root=True))

            utils.execute('ip', 'link', 'set', if_remote_name, 'address',
                          vif['address'], run_as_root=True)

        except Exception:
            LOG.exception("Failed to configure network")
            msg = _('Failed to setup the network, rolling back')
            undo_mgr.rollback_and_reraise(msg=msg, instance=instance)

    def attach(self, instance, vif, container_id):
        vif_type = vif['type']

        LOG.debug('Attach vif_type=%(vif_type)s instance=%(instance)s '
                  'vif=%(vif)s',
                  {'vif_type': vif_type, 'instance': instance,
                   'vif': vif})

        if_local_name = 'veth%s' % vif['id'][:8]
        if_remote_name = 'ns%s' % vif['id'][:8]

        undo_mgr = utils.UndoManager()
        undo_mgr.undo_with(lambda: utils.execute(
            'ip', 'link', 'delete', if_local_name, run_as_root=True))
        ipv4_address, ipv4_netmask, ipv4_gateway = self._retrieve_ip_address(
            vif, 4)
        ipv6_address, ipv6_netmask, ipv6_gateway = self._retrieve_ip_address(
            vif, 6)
        ipv4_address = ipv4_address or '0.0.0.0'
        params = {
            'ip_address': ipv4_address,
            'vn_id': vif['network']['id'],
            'display_name': instance['display_name'],
            'hostname': instance['hostname'],
            'host': instance['host'],
            'vm_project_id': instance['project_id'],
            'port_type': 'NovaVMPort',
            'ip6_address': ipv6_address,
        }

        try:
            utils.execute('ip', 'link', 'set', if_remote_name, 'netns',
                          container_id, run_as_root=True)

            result = self._vrouter_client.add_port(
                instance['uuid'], vif['id'],
                if_local_name, vif['address'], **params)
            if not result:
                # follow the exception path
                raise RuntimeError('add_port returned %s' % str(result))
            utils.execute('ip', 'link', 'set', if_local_name, 'up',
                          run_as_root=True)
        except Exception:
            LOG.exception("Failed to attach the network")
            msg = _('Failed to attach the network, rolling back')
            undo_mgr.rollback_and_reraise(msg=msg, instance=instance)

        try:
            utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link',
                          'set', if_remote_name, 'address', vif['address'],
                          run_as_root=True)
            if ipv6_address:
                ip = ipv6_address + "/" + ipv6_netmask
                gateway = ipv6_gateway
                utils.execute('ip', 'netns', 'exec', container_id, 'ifconfig',
                              if_remote_name, 'inet6', 'add', ip,
                              run_as_root=True)
                utils.execute('ip', 'netns', 'exec', container_id, 'ip', '-6',
                              'route', 'replace', 'default', 'via', gateway,
                              'dev', if_remote_name, run_as_root=True)
            if ipv4_address != '0.0.0.0':
                ip = ipv4_address + "/" + ipv4_netmask
                gateway = ipv4_gateway
                utils.execute('ip', 'netns', 'exec', container_id, 'ifconfig',
                              if_remote_name, ip, run_as_root=True)
                utils.execute('ip', 'netns', 'exec', container_id, 'ip',
                              'route', 'replace', 'default', 'via', gateway,
                              'dev', if_remote_name, run_as_root=True)
            utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link',
                          'set', if_remote_name, 'up', run_as_root=True)
        except Exception:
            LOG.exception("Failed to attach vif", instance=instance)

    def _retrieve_ip_address(self, vif, version):
        address = None
        netmask = None
        gateway = None
        if 'subnets' in vif['network']:
            subnets = vif['network']['subnets']
            for subnet in subnets:
                ips = subnet['ips'][0]
                if (ips['version'] == version):
                    if ips['address'] is not None:
                        address = ips['address']
                        netmask = subnet['cidr'].split('/')[1]
                        gateway = subnet['gateway']['address']

        return address, netmask, gateway

    def unplug(self, instance, vif):
        vif_type = vif['type']
        if_local_name = 'veth%s' % vif['id'][:8]

        LOG.debug('Unplug vif_type=%(vif_type)s instance=%(instance)s '
                  'vif=%(vif)s',
                  {'vif_type': vif_type, 'instance': instance,
                   'vif': vif})

        try:
            self._vrouter_client.delete_port(vif['id'])
            if linux_net.device_exists(if_local_name):
                utils.execute('ip', 'link', 'delete', if_local_name,
                              run_as_root=True)
        except Exception:
            LOG.exception("Delete port failed", instance=instance)
Exemple #28
0
class NetnsManager(object):
    SNAT_RT_TABLES_ID = 42
    DEV_NAME_LEN = 14
    NETNS_PREFIX = 'vrouter-'
    LEFT_DEV_PREFIX = 'int-'
    RIGH_DEV_PREFIX = 'gw-'
    TAP_PREFIX = 'veth'

    def __init__(self, vm_uuid, nic_left, nic_right, root_helper='sudo'):
        self.vm_uuid = vm_uuid
        self.namespace = self.NETNS_PREFIX + self.vm_uuid
        self.nic_left = nic_left
        self.nic_right = nic_right
        self.root_helper = root_helper
        self.nic_left['name'] = (self.LEFT_DEV_PREFIX +
                                 self.nic_left['uuid'])[:self.DEV_NAME_LEN]
        self.nic_right['name'] = (self.RIGH_DEV_PREFIX +
                                  self.nic_right['uuid'])[:self.DEV_NAME_LEN]
        self.ip_ns = ip_lib.IPWrapper(root_helper=self.root_helper,
                                      namespace=self.namespace)
        self.vrouter_client = ContrailVRouterApi()

    def _get_tap_name(self, uuid_str):
            return (self.TAP_PREFIX + uuid_str)[:self.DEV_NAME_LEN]

    def is_netns_already_exists(self):
        return self.ip_ns.netns.exists(self.namespace)

    def create(self):
        ip = ip_lib.IPWrapper(self.root_helper)
        ip.ensure_namespace(self.namespace)

        if not self.nic_left or not self.nic_right:
            raise ValueError('Need left and right interfaces to create a '
                             'network namespace')
        for nic in [self.nic_left, self.nic_right]:
            self._create_interfaces(ip, nic)

    def set_snat(self):
        if not self.ip_ns.netns.exists(self.namespace):
            raise ValueError('Need to create the network namespace before set '
                             'up the SNAT')

        self.ip_ns.netns.execute(['sysctl', '-w', 'net.ipv4.ip_forward=1'])
        self.ip_ns.netns.execute(['iptables', '-t', 'nat', '-F'])
        self.ip_ns.netns.execute(['iptables', '-t', 'nat', '-A', 'POSTROUTING',
                                  '-s', '0.0.0.0/0', '-o',
                                  self.nic_right['name'], '-j', 'MASQUERADE'])
        self.ip_ns.netns.execute(['ip', 'route', 'replace', 'default', 'dev',
                                  self.nic_right['name']])
        self.ip_ns.netns.execute(['ip', 'route', 'replace', 'default', 'dev',
                                  self.nic_left['name'], 'table',
                                  self.SNAT_RT_TABLES_ID])
        try:
            self.ip_ns.netns.execute(['ip', 'rule', 'del', 'iif',
                                      str(self.nic_right['name']), 'table',
                                      self.SNAT_RT_TABLES_ID])
        except RuntimeError:
            pass
        self.ip_ns.netns.execute(['ip', 'rule', 'add', 'iif',
                                  str(self.nic_right['name']), 'table',
                                  self.SNAT_RT_TABLES_ID])

    def destroy(self):
        if not self.ip_ns.netns.exists(self.namespace):
            raise ValueError('Namespace %s does not exist' % self.namespace)

        for device in self.ip_ns.get_devices(exclude_loopback=True):
            ip_lib.IPDevice(device.name,
                            self.root_helper,
                            self.namespace).link.delete()

        self.ip_ns.netns.delete(self.namespace)

    def plug_namespace_interface(self):
        if not self.nic_left or not self.nic_right:
            raise ValueError('Need left and right interfaces to plug a '
                             'network namespace onto vrouter')
        self._add_port_to_agent(self.nic_left,
                                display_name='NetNS %s left interface' %
                                self.vm_uuid)
        self._add_port_to_agent(self.nic_right,
                                display_name='NetNS %s right interface' %
                                self.vm_uuid)

    def unplug_namespace_interface(self):
        if not self.nic_left or not self.nic_right:
            raise ValueError('Need left and right interfaces to unplug a '
                             'network namespace onto vrouter')
        for nic in [self.nic_left, self.nic_right]:
            self._delete_port_to_agent(nic)

    def _create_interfaces(self, ip, nic):
        if ip_lib.device_exists(nic['name'],
                                self.root_helper,
                                namespace=self.namespace):
            ip_lib.IPDevice(nic['name'],
                            self.root_helper,
                            self.namespace).link.delete()

        root_dev, ns_dev = ip.add_veth(self._get_tap_name(nic['uuid']),
                                       nic['name'],
                                       namespace2=self.namespace)
        if nic['mac']:
            ns_dev.link.set_address(str(nic['mac']))

        ns_dev.link.set_up()
        root_dev.link.set_up()

        if nic['ip']:
            ip = nic['ip']
            ns_dev.addr.flush()
            ns_dev.addr.add(ip.version, str(ip), str(ip.broadcast))
        else:
            #TODO(ethuleau): start DHCP client
            raise NotImplementedError

        # disable reverse path filtering
        self.ip_ns.netns.execute(['sysctl', '-w',
                                  'net.ipv4.conf.%s.rp_filter=2' % nic['name']]
                                 )

    def _add_port_to_agent(self, nic, display_name=None):
        kwargs = {}
        kwargs['ip_address'] = str(nic['ip'].ip)
        if display_name:
            kwargs['display_name'] = display_name

        if not (self.vrouter_client.add_port(self.vm_uuid, nic['uuid'],
                                             self._get_tap_name(nic['uuid']),
                                             str(nic['mac']), **kwargs)):
            raise ValueError('Cannot add interface %s on the vrouter' %
                             nic['uuid'])


    def _delete_port_to_agent(self, nic):
        self.vrouter_client.delete_port(nic['uuid'])
class VRouterApiTest(unittest.TestCase):
    def setUp(self):
        self._api = ContrailVRouterApi()

    def test_create_port(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client
        self._api.add_port(str(uuid.uuid1()), str(uuid.uuid1()), 'tapX',
                           'aa:bb:cc:ee:ff:00')
        self.assertTrue(mock_client.AddPort.called)

    def test_delete_port(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client

        vm_uuid = uuid.uuid1()
        vif_uuid = uuid.uuid1()
        self._api.add_port(str(vm_uuid), str(vif_uuid), 'tapX',
                           'aa:bb:cc:ee:ff:00')
        self.assertTrue(mock_client.AddPort.called)
        self.assertTrue(self._api._ports[vif_uuid])

        self._api.delete_port(str(vif_uuid))
        self.assertTrue(mock_client.DeletePort.called)

    def test_resynchronize(self):
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = None

        vm_uuid = str(uuid.uuid1())
        vif_uuid = str(uuid.uuid1())
        port1 = ttypes.Port(self._api._uuid_string_to_hex(vif_uuid),
                           self._api._uuid_string_to_hex(vm_uuid),
                           'tapX', '0.0.0.0', [0] * 16, 'aa:bb:cc:ee:ff:00')
        self._api.add_port(vm_uuid, vif_uuid, 'tapX', 'aa:bb:cc:ee:ff:00')

        mock_client = mock.Mock()
        self._api._rpc_client_instance.return_value = mock_client
        self._api.periodic_connection_check()
        mock_client.AddPort.assert_called_with([port1])

    def test_resynchronize_multi_ports(self):
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = None

        vm_uuid = str(uuid.uuid1())
        vif_uuid = str(uuid.uuid1())
        port1 = ttypes.Port(self._api._uuid_string_to_hex(vif_uuid),
                            self._api._uuid_string_to_hex(vm_uuid),
                            'tapX', '0.0.0.0', [0] * 16, 'aa:bb:cc:ee:ff:00')
        self._api.add_port(vm_uuid, vif_uuid, 'tapX', 'aa:bb:cc:ee:ff:00')

        vm_uuid = str(uuid.uuid1())
        vif_uuid = str(uuid.uuid1())
        port2 = ttypes.Port(self._api._uuid_string_to_hex(vif_uuid),
                            self._api._uuid_string_to_hex(vm_uuid),
                            'tapY', '0.0.0.0', [0] * 16, '11:22:33:44:55:66')
        self._api.add_port(vm_uuid, vif_uuid, 'tapY', '11:22:33:44:55:66')

        mock_client = mock.Mock()
        self._api._rpc_client_instance.return_value = mock_client
        self._api.connect()
        self._api._resynchronize()
        mock_client.AddPort.assert_called_with([port1, port2])

    def test_additional_arguments(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client
        vif_uuid = uuid.uuid1()
        network_uuid = uuid.uuid1()
        project_id = uuid.uuid1().hex
        self._api.add_port(str(uuid.uuid1()), str(vif_uuid), 'tapX',
                           'aa:bb:cc:ee:ff:00',
                           network_uuid=str(network_uuid),
                           vm_project_id=project_id)
        self.assertTrue(mock_client.AddPort.called)
        port = self._api._ports[vif_uuid]
        self.assertEqual(self._api._uuid_to_hex(network_uuid),
                         port.vn_id)
        self.assertEqual(self._api._uuid_string_to_hex(project_id),
                         port.vm_project_id)
def setup(pod_namespace, pod_name, docker_id):
    """
    project: pod_namespace
    network: pod_name
    netns: docker_id{12}
    """
    client = ContrailClient()

    # Kubelet::createPodInfraContainer ensures that State.Pid is set
    pid = docker_get_pid(docker_id)
    if pid == 0:
        raise Exception('Unable to read State.Pid')

    short_id = docker_id[0:11]

    if not os.path.exists('/var/run/netns'):
        os.mkdir('/var/run/netns')

    Shell.run('ln -sf /proc/%d/ns/net /var/run/netns/%s' % (pid, short_id))

    manager = LxcManager()

    if client._net_mode == 'none':
        instance_ifname = 'veth0'
    else:
        instance_ifname = 'eth0'

    uid, podName = getDockerPod(docker_id)
    podInfo = None
    for i in range(0, 120):
        podInfo = getPodInfo(pod_namespace, podName)
        if 'annotations' in podInfo["metadata"] and \
           'nic_uuid' in podInfo["metadata"]["annotations"]:
            break
        time.sleep(1)
    
    # The lxc_manager uses the mac_address to setup the container interface.
    # Additionally the ip-address, prefixlen and gateway are also used.
    if not 'annotations' in podInfo["metadata"] or not 'nic_uuid' in podInfo["metadata"]["annotations"]:
        logging.error('No annotations in pod %s', podInfo["metadata"]["name"])
        sys.exit(1)


    podAnnotations = podInfo["metadata"]["annotations"]
    nic_uuid = podAnnotations["nic_uuid"]
    mac_address = podAnnotations["mac_address"]
    if client._net_mode == 'none':
        ifname = manager.create_interface(short_id, instance_ifname,
                                          mac_address)
    else:
        ifname = manager.move_interface(short_id, pid, instance_ifname,
                                        mac_address)

    api = ContrailVRouterApi()
    api.add_port(uid, nic_uuid, ifname, mac_address,
                 port_type='NovaVMPort',
                 display_name=podName,
                 hostname=podName+'.'+pod_namespace)

    ip_address = podAnnotations["ip_address"]
    gateway = podAnnotations["gateway"]
    Shell.run('ip netns exec %s ip addr add %s/32 peer %s dev %s' % \
              (short_id, ip_address, gateway, instance_ifname))
    Shell.run('ip netns exec %s ip route add default via %s' % \
              (short_id, gateway))
    Shell.run('ip netns exec %s ip link set %s up' %
              (short_id, instance_ifname))
    # TX checksum is broken on Fedora 21 testbed.
    # This may be an issue with kernel 3.17 or veth-pair code.
    if platform.linux_distribution()[0:2] == ('Fedora', '21'):
        Shell.run('nsenter -n -t %d ethtool -K %s tx off' % (pid, instance_ifname))
Exemple #31
0
def setup(pod_namespace, pod_name, docker_id):
    """
    project: pod_namespace
    network: pod_name
    netns: docker_id{12}
    """
    client = ContrailClient()

    # Kubelet::createPodInfraContainer ensures that State.Pid is set
    pid = docker_get_pid(docker_id)
    if pid == 0:
        raise Exception('Unable to read State.Pid')

    short_id = docker_id[0:11]

    if not os.path.exists('/var/run/netns'):
        os.mkdir('/var/run/netns')

    Shell.run('ln -sf /proc/%d/ns/net /var/run/netns/%s' % (pid, short_id))

    manager = LxcManager()

    if client._net_mode == 'none':
        instance_ifname = 'veth0'
    else:
        instance_ifname = 'eth0'

    uid, podName = getDockerPod(docker_id)

    podInfo = None
    for i in range(0, 120):
        podInfo = getPodInfo(podName)
        if 'annotations' in podInfo["metadata"] and \
           'nic_uuid' in podInfo["metadata"]["annotations"]:
            break
        time.sleep(1)
    
    # The lxc_manager uses the mac_address to setup the container interface.
    # Additionally the ip-address, prefixlen and gateway are also used.
    if not 'annotations' in podInfo["metadata"] or not 'nic_uuid' in podInfo["metadata"]["annotations"]:
        logging.error('No annotations in pod %s', podInfo["metadata"]["name"])
        sys.exit(1)


    podAnnotations = podInfo["metadata"]["annotations"]
    nic_uuid = podAnnotations["nic_uuid"]
    mac_address = podAnnotations["mac_address"]
    if client._net_mode == 'none':
        ifname = manager.create_interface(short_id, instance_ifname,
                                          mac_address)
    else:
        ifname = manager.move_interface(short_id, pid, instance_ifname,
                                        mac_address)

    api = ContrailVRouterApi()
    api.add_port(uid, nic_uuid, ifname, mac_address,
                 port_type='NovaVMPort',
                 display_name=podName,
                 hostname=podName+'.'+pod_namespace)

    ip_address = podAnnotations["ip_address"]
    gateway = podAnnotations["gateway"]
    Shell.run('ip netns exec %s ip addr add %s/32 peer %s dev %s' % \
              (short_id, ip_address, gateway, instance_ifname))
    Shell.run('ip netns exec %s ip route add default via %s' % \
              (short_id, gateway))
    Shell.run('ip netns exec %s ip link set %s up' %
              (short_id, instance_ifname))
Exemple #32
0
class ConfigCNI(ConfigHandle):
    def __init__(self, **kwargs):
        if self.vnc_handle:
            pass
        else:
            super(ConfigCNI,
                  self).__init__(api_server_host=kwargs['api_server'],
                                 tenant=kwargs['tenant'])

        self.vmi = ConfigVMI()
        self.vm = ConfigVM()
        self.vn = ConfigVN()
        self.vrouter = ContrailVRouterApi()

    def create(self, name, vn):
        self.name = name
        cmd = 'docker inspect -f "{{.State.Pid}}" %s' % (name)
        pid = self.shell_cmd(cmd)
        pid = pid.rstrip('\n')
        self.shell_cmd('mkdir -p /var/run/netns')
        self.shell_cmd('sudo ln -sf /proc/%s/ns/net /var/run/netns/%s' %
                       (pid, name))
        vm_name = '{}-{}'.format(socket.gethostname(), name)
        proj_obj = self.get_project(name=self.tenant)
        vn_obj = self.vn.read(name=vn)
        try:
            vm_obj = self.vm.read(vm_name)
        except:
            self.vm.create(vm_name)
        vm_obj = self.vm.read(vm_name)
        ifl = self.get_vethid(name)
        ifl = 1 if not ifl else int(ifl) + 1
        (veth,cni) = ("veth-{}-{}".format(name,str(ifl)),\
                      "cni-{}-{}".format(name,str(ifl)))
        vmi_name = "{}-{}-{}".format(socket.gethostname(), name, ifl)
        try:
            vmi_obj = self.vmi.read(vmi_name)
        except:
            self.vmi.create(vn, vm_name, vmi_name)
            vmi_obj = self.vmi.read(vmi_name)

        if vmi_obj:
            mac = vmi_obj.virtual_machine_interface_mac_addresses.mac_address[
                0]
            self.shell_cmd('sudo ip link add %s type veth peer name %s' \
                               %(cni,veth))
            self.shell_cmd('sudo ifconfig %s hw ether %s'\
                               %(veth,mac))
            self.shell_cmd('sudo ip link set %s netns %s' \
                               %(veth, name))
            self.shell_cmd('sudo ip netns exec %s ip link set %s up' \
                               %(name,veth))
            self.shell_cmd('sudo ip link set %s up' \
                               %(cni))
        self.register_cni(cni, vm_obj, vmi_obj, vn_obj, proj_obj)

    def delete(self, name):
        vm_name = '%s-%s' % (socket.gethostname(), name)
        ifl = self.get_vethid(name)
        vmi_name = '{}-{}-{}'.format(socket.gethostname(), name, ifl)
        if ifl:
            cni = "cni-{}-{}".format(name, str(ifl))
        else:
            print "No more interfaces are left inside the container instance"
            sys.exit(1)
        vmi_obj = self.vmi.read(vmi_name)
        self.unregister_cni(vmi_obj)
        self.vmi.delete(vmi_name)
        self.shell_cmd('sudo ip link delete %s' \
                       %(cni))
        if int(ifl) == 1:
            print "Deleting the VM object"
            self.vm.delete(vm_name)
        return

    def list(self, name):
        import re
        from operator import attrgetter, itemgetter
        vm_name = '%s-%s' % (socket.gethostname(), name)
        vm_obj = self.vm.read(vm_name)
        vm_name = vm_obj.display_name
        try:
            print "{:24}{:24}{:24}{:32}{:24}".\
                    format('Docker Instance','Vrouter Interface',\
                         'Container interface','Virtual Machine Interface','Network Segment')
            print "-" * 124
            vmi_objs = vm_obj.get_virtual_machine_interface_back_refs()
            vmi_objs.sort(key=lambda vmi: vmi['to'][2])

            for p in vmi_objs:
                vmi_obj = self.vnc_handle.virtual_machine_interface_read(
                    fq_name=p['to'])
                vmi_name = vmi_obj.display_name
                ifl = re.search(r'-([0-9]+)$', vmi_name).group(1)
                cni_name = 'cni-{}-{}'.format(name, ifl)
                veth_name = 'veth-{}-{}'.format(name, ifl)
                vn_name = vmi_obj.virtual_network_refs[0]['to'][2]
                print "{:24}{:24}{:24}{:32}{:24}".format(
                    name, veth_name, cni_name, vmi_name, vn_name)
        except:
            return
        return

    def register_cni(self, cni, vm_obj, vmi_obj, vn_obj, proj_obj):
        mac = vmi_obj.virtual_machine_interface_mac_addresses.mac_address[0]
        self.vrouter.add_port(vm_obj.uuid,
                              vmi_obj.uuid,
                              cni,
                              mac,
                              port_type='NovaVMPort',
                              vm_project_id=proj_obj.uuid,
                              vn_id=vn_obj.uuid)
        return

    def unregister_cni(self, vmi_obj):
        self.vrouter.delete_port(vmi_obj.uuid)
        return

    def get_vethid(self, name):
        cmd = "ip netns exec %s ip link | grep veth | \
        awk '{print $2}' | awk -F ':' '{print $1}' | \
        awk -F 'veth-%s-' '{print $2}' | tail -n 1 | \
        awk -F '@' {'print $1}'" % (name, name)
        ifl = self.shell_cmd(cmd)
        return ifl.rstrip('\n')
Exemple #33
0
class VRouterAPIClient(object):
    """ A client for Contrail VRouter Agent REST API. """

    def __init__(self):
        self.vrouter_api = ContrailVRouterApi()
        self.vrouter_host = 'http://localhost'
        self.vrouter_port = '9091'
        self.port_files_path = '/var/lib/contrail/ports/'

    def add_port(self, vmi_model):
        """ Add port to VRouter Agent. """
        try:
            ip_address = vmi_model.ip_address
            if vmi_model.vnc_instance_ip:
                ip_address = vmi_model.vnc_instance_ip.instance_ip_address

            parameters = dict(
                vm_uuid_str=vmi_model.vm_model.uuid,
                vif_uuid_str=vmi_model.uuid,
                interface_name=vmi_model.uuid,
                mac_address=vmi_model.vcenter_port.mac_address,
                ip_address=ip_address,
                vn_id=vmi_model.vn_model.uuid,
                display_name=vmi_model.vm_model.name,
                vlan=vmi_model.vcenter_port.vlan_id,
                rx_vlan=vmi_model.vcenter_port.vlan_id,
                port_type=2,
                # vrouter-port-control accepts only project's uuid without dashes
                vm_project_id=vmi_model.vn_model.vnc_vn.parent_uuid.replace('-', ''),
            )
            self.vrouter_api.add_port(**parameters)
            logger.info('Added port to vRouter with parameters: %s', parameters)
        except Exception as e:
            logger.error('There was a problem with vRouter API Client: %s', e)

    def delete_port(self, vmi_uuid):
        """ Delete port from VRouter Agent. """
        try:
            self.vrouter_api.delete_port(vmi_uuid)
            logger.info('Removed port from vRouter with uuid: %s', vmi_uuid)
        except Exception as e:
            logger.error('There was a problem with vRouter API Client: %s', e)

    def enable_port(self, vmi_uuid):
        try:
            self.vrouter_api.enable_port(vmi_uuid)
            logger.info('Enabled vRouter port with uuid: %s', vmi_uuid)
        except Exception as e:
            logger.error('There was a problem with vRouter API Client: %s', e)

    def disable_port(self, vmi_uuid):
        try:
            self.vrouter_api.disable_port(vmi_uuid)
            logger.info('Disabled vRouter port with uuid: %s', vmi_uuid)
        except Exception as e:
            logger.error('There was a problem with vRouter API Client: %s', e)

    def read_port(self, vmi_uuid):
        try:
            request_url = '{host}:{port}/port/{uuid}'.format(host=self.vrouter_host,
                                                             port=self.vrouter_port,
                                                             uuid=vmi_uuid)
            response = requests.get(request_url)
            if response.status_code == requests.codes.ok:
                port_properties = json.loads(response.content)
                logger.info('Read vRouter port with uuid: %s, port properties: %s', vmi_uuid, port_properties)
                return port_properties
        except Exception as e:
            logger.error('There was a problem with vRouter API Client: %s', e)
        logger.info('Unable to read vRouter port with uuid: %s', vmi_uuid)
        return None

    def get_all_port_uuids(self):
        if not os.path.exists(self.port_files_path):
            return ()
        port_uuids = []
        for file_name in os.listdir(self.port_files_path):
            if os.path.isfile(os.path.join(self.port_files_path, file_name)):
                port_uuids.append(file_name)
        return port_uuids
 def setUp(self):
     self._api = ContrailVRouterApi()
class VRouterApiTest(unittest.TestCase):
    def setUp(self):
        self._api = ContrailVRouterApi()

    def test_create_port(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client
        self._api.add_port(str(uuid.uuid1()), str(uuid.uuid1()), 'tapX',
                           'aa:bb:cc:ee:ff:00')
        self.assertTrue(mock_client.AddPort.called)

    def test_delete_port(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client

        vm_uuid = uuid.uuid1()
        vif_uuid = uuid.uuid1()
        self._api.add_port(str(vm_uuid), str(vif_uuid), 'tapX',
                           'aa:bb:cc:ee:ff:00')
        self.assertTrue(mock_client.AddPort.called)
        self.assertTrue(self._api._ports[vif_uuid])

        self._api.delete_port(str(vif_uuid))
        self.assertTrue(mock_client.DeletePort.called)

    def test_resynchronize(self):
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = None

        vm_uuid = str(uuid.uuid1())
        vif_uuid = str(uuid.uuid1())
        port1 = ttypes.Port(self._api._uuid_string_to_hex(vif_uuid),
                            self._api._uuid_string_to_hex(vm_uuid), 'tapX',
                            '0.0.0.0', [0] * 16, 'aa:bb:cc:ee:ff:00')
        self._api.add_port(vm_uuid, vif_uuid, 'tapX', 'aa:bb:cc:ee:ff:00')

        mock_client = mock.Mock()
        self._api._rpc_client_instance.return_value = mock_client
        self._api.periodic_connection_check()
        mock_client.AddPort.assert_called_with([port1])

    def test_resynchronize_multi_ports(self):
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = None

        vm_uuid = str(uuid.uuid1())
        vif_uuid = str(uuid.uuid1())
        port1 = ttypes.Port(self._api._uuid_string_to_hex(vif_uuid),
                            self._api._uuid_string_to_hex(vm_uuid), 'tapX',
                            '0.0.0.0', [0] * 16, 'aa:bb:cc:ee:ff:00')
        self._api.add_port(vm_uuid, vif_uuid, 'tapX', 'aa:bb:cc:ee:ff:00')

        vm_uuid = str(uuid.uuid1())
        vif_uuid = str(uuid.uuid1())
        port2 = ttypes.Port(self._api._uuid_string_to_hex(vif_uuid),
                            self._api._uuid_string_to_hex(vm_uuid), 'tapY',
                            '0.0.0.0', [0] * 16, '11:22:33:44:55:66')
        self._api.add_port(vm_uuid, vif_uuid, 'tapY', '11:22:33:44:55:66')

        mock_client = mock.Mock()
        self._api._rpc_client_instance.return_value = mock_client
        self._api.connect()
        self._api._resynchronize()
        mock_client.AddPort.assert_called_with([port1, port2])

    def test_additional_arguments(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client
        vif_uuid = uuid.uuid1()
        network_uuid = uuid.uuid1()
        project_id = uuid.uuid1().hex
        self._api.add_port(str(uuid.uuid1()),
                           str(vif_uuid),
                           'tapX',
                           'aa:bb:cc:ee:ff:00',
                           vn_id=str(network_uuid),
                           vm_project_id=project_id)
        self.assertTrue(mock_client.AddPort.called)
        port = self._api._ports[vif_uuid]
        self.assertEqual(self._api._uuid_to_hex(network_uuid), port.vn_id)
        self.assertEqual(self._api._uuid_string_to_hex(project_id),
                         port.vm_project_id)
Exemple #36
0
class VRouterVIFDriver(LibVirtVIFDriver):
    """VIF driver for VRouter when running Neutron."""

    PORT_TYPE = 'NovaVMPort'

    def __init__(self, get_connection):
        super(VRouterVIFDriver, self).__init__(get_connection)
        self._vrouter_semaphore = eventlet.semaphore.Semaphore()
        self._vrouter_client = ContrailVRouterApi(doconnect=True, semaphore=self._vrouter_semaphore)
        timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
        timer.start(interval=2)

    def _keep_alive(self):
        self._vrouter_client.periodic_connection_check()

    @staticmethod
    def _get_br_name(dev):
        """Returns the bridge name for a tap device.
        This is lxc related stuff. To work around the fact, that libvirt does
        not support direct passthrough of devices to LXC."""
        return 'br%s' % dev[3:]

    def _create_bridge(self, dev, instance):
        """Creating a bridge and returning its name"""
        br_name = self._get_br_name(dev)

        try:
            linux_net.LinuxBridgeInterfaceDriver.ensure_bridge(br_name, dev)
            linux_net._execute('ip', 'link', 'set', br_name, 'promisc', 'on',
                               run_as_root=True)
        except processutils.ProcessExecutionError:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

        return br_name

    def get_config(self, instance, vif, image_meta, inst_type, virt_type=None):
        try:
            conf = super(VRouterVIFDriver, self).get_config(instance, vif,
                                                        image_meta, inst_type)
        except TypeError:
            conf = super(VRouterVIFDriver, self).get_base_config(instance, vif,
                                             image_meta, inst_type, virt_type)
        dev = self.get_vif_devname(vif)
        if not virt_type:
            try:
                virt_type = cfg.CONF.libvirt.virt_type
            except cfg.NoSuchOptError:
                virt_type = cfg.CONF.libvirt_type

        if virt_type == 'lxc':
            # for lxc we need to pass a bridge to libvirt
            br_name = self._get_br_name(dev)
            designer.set_vif_host_backend_bridge_config(conf, br_name)
        else:
            if CONF.contrail.use_userspace_vhost:
                dev = path.join(CONF.contrail.userspace_vhost_socket_dir,
                                'uvh_vif_' + dev)
                designer.set_vif_host_backend_vhostuser_config(conf, 'client',
                        dev)
            else:
                designer.set_vif_host_backend_ethernet_config(conf, dev)
        designer.set_vif_bandwidth_config(conf, inst_type)

        return conf

    def plug(self, instance, vif):
        try:
            dev = self.get_vif_devname(vif)

            try:
                if not CONF.contrail.use_userspace_vhost:
                    linux_net.create_tap_dev(dev)
            except processutils.ProcessExecutionError:
                LOG.exception(_LE("Failed while plugging vif"), instance=instance)

            try:
                virt_type = cfg.CONF.libvirt.virt_type
            except cfg.NoSuchOptError:
                virt_type = cfg.CONF.libvirt_type

            if virt_type == 'lxc':
                dev = self._create_bridge(dev, instance)

            ipv4_address = '0.0.0.0'
            ipv6_address = None
            subnets = vif['network']['subnets']
            for subnet in subnets:
                ips = subnet['ips'][0]
                if (ips['version'] == 4):
                    if ips['address'] is not None:
                        ipv4_address = ips['address']
                if (ips['version'] == 6):
                    if ips['address'] is not None:
                        ipv6_address = ips['address']

            kwargs = {
                'ip_address': ipv4_address,
                'vn_id': vif['network']['id'],
                'display_name': instance['display_name'],
                'hostname': instance['hostname'],
                'host': instance['host'],
                'vm_project_id': instance['project_id'],
                'port_type': self.PORT_TYPE,
                'ip6_address': ipv6_address,
            }
            try:
                result = self._vrouter_client.add_port(instance['uuid'],
                                                       vif['id'],
                                                       dev,
                                                       vif['address'],
                                                       **kwargs)
                if not result:
                    LOG.exception(_LE("Failed while plugging vif"),
                                  instance=instance)
            except TApplicationException:
                LOG.exception(_LE("Failed while plugging vif"), instance=instance)

        except Exception as e:
            from pprint import pformat
            LOG.error(_("Error in plug: %s locals: %s instance %s"
                       %(str(e), pformat(locals()),
                         pformat(instance) if isinstance(instance, dict) else pformat(instance.__dict__))))

    def unplug(self, instance, vif):
        try:
            dev = self.get_vif_devname(vif)

            if isinstance(instance, dict):
                task_state = instance['task_state']
            else:
                task_state = instance._task_state

            try:
                self._vrouter_client.delete_port(vif['id'])
                if task_state == 'rebuilding':
                    self.delete_device(dev)
                else:
                    # delegate the deletion of tap device to a deffered thread
                    worker_thread = threading.Thread(
                        target=self.delete_device,
                        name='contrailvif',
                        args=(dev,), kwargs={'timeout': 2})
                    worker_thread.start()
            except (TApplicationException, processutils.ProcessExecutionError,
                    RuntimeError):
                LOG.exception(_LE("Failed while unplugging vif"),
                              instance=instance)
        except Exception as e:
            from pprint import pformat
            LOG.error(_("Error in unplug: %s locals: %s instance %s"
                       %(str(e), pformat(locals()),
                         pformat(instance) if isinstance(instance, dict) else pformat(instance.__dict__))))

    def delete_device(self, dev, timeout=None):
        if timeout is not None:
            time.sleep(timeout)
        LOG.debug(dev)

        try:
            virt_type = cfg.CONF.libvirt.virt_type
        except cfg.NoSuchOptError:
            virt_type = cfg.CONF.libvirt_type

        if virt_type == 'lxc':
            linux_net.LinuxBridgeInterfaceDriver.remove_bridge(
                    self._get_br_name(dev))
        if not CONF.contrail.use_userspace_vhost:
            linux_net.delete_net_dev(dev)
Exemple #37
0
 def __init__(self):
     self.vrouter_api = ContrailVRouterApi()
     self.vrouter_host = 'http://localhost'
     self.vrouter_port = '9091'
     self.port_files_path = '/var/lib/contrail/ports/'
Exemple #38
0
class ContrailInterfaceDriver(interface.LinuxInterfaceDriver):
    """ Opencontrail VIF driver for neutron."""
    @classmethod
    def _parse_class_args(cls, cfg_parser):
        cfg_parser.read(CONTRAIL_CFG_FILE)
        cls._api_server_ip = _read_cfg(cfg_parser, 'APISERVER',
                                       'api_server_ip', '127.0.0.1')
        cls._api_server_port = _read_cfg(cfg_parser, 'APISERVER',
                                         'api_server_port', '8082')
        cls._api_server_use_ssl = _read_cfg(cfg_parser, 'APISERVER', 'use_ssl',
                                            False)
        cls._auth_token_url = _read_cfg(cfg_parser, 'APISERVER',
                                        'auth_token_url', None)

    def __init__(self, conf):
        super(ContrailInterfaceDriver, self).__init__(conf)
        self._port_dict = {}
        self._client = self._connect_to_api_server()
        self._vrouter_client = ContrailVRouterApi()
        timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
        timer.start(interval=2)

    def _connect_to_api_server(self):
        cfg_parser = ConfigParser.ConfigParser()
        ContrailInterfaceDriver._parse_class_args(cfg_parser)
        try:
            client = VncApi(api_server_host=self._api_server_ip,
                            api_server_port=self._api_server_port,
                            api_server_use_ssl=self._api_server_use_ssl,
                            auth_token_url=self._auth_token_url)
            return client
        except:
            pass

    def _keep_alive(self):
        self._vrouter_client.periodic_connection_check()

    def _delete_port(self, port_id):
        self._vrouter_client.delete_port(port_id)

    def _instance_locate(self, port_obj):
        """ lookup the instance associated with the port object.
        Create the vm instance if port object is not associated
        with a vm instance
        """
        if port_obj.get_virtual_machine_refs() is not None:
            try:
                vm_uuid = port_obj.get_virtual_machine_refs()[0]['uuid']
                instance_obj = self._client.virtual_machine_read(id=vm_uuid)
                return instance_obj
            except NoIdError:
                pass

        vm_uuid = str(uuid.uuid4())
        instance_obj = VirtualMachine(vm_uuid)
        instance_obj.uuid = vm_uuid
        self._client.virtual_machine_create(instance_obj)
        port_obj.set_virtual_machine(instance_obj)
        self._client.virtual_machine_interface_update(port_obj)
        return instance_obj

    def _add_port_to_agent(self, port_id, net_id, iface_name, mac_address):
        port_obj = self._client.virtual_machine_interface_read(id=port_id)
        if port_obj is None:
            LOG.debug(_("Invalid port_id : %s"), port_id)
            return

        ips = port_obj.get_instance_ip_back_refs()
        ip_addr = '0.0.0.0'
        # get the ip address of the port if associated
        if ips and len(ips):
            ip_uuid = ips[0]['uuid']
            ip = self._client.instance_ip_read(id=ip_uuid)
            ip_addr = ip.get_instance_ip_address()

        net_obj = self._client.virtual_network_read(id=net_id)
        if net_obj is None:
            LOG.debug(_("Invalid net_id : %s"), net_id)
            return

        # get the instance object the port is attached to
        instance_obj = self._instance_locate(port_obj)

        if instance_obj is None:
            return

        kwargs = {}
        kwargs['ip_address'] = ip_addr
        kwargs['network_uuid'] = net_id
        kwargs['vm_project_uuid'] = net_obj.parent_uuid
        self._vrouter_client.add_port(instance_obj.uuid, port_id, iface_name,
                                      mac_address, **kwargs)

    def plug(self,
             network_id,
             port_id,
             device_name,
             mac_address,
             bridge=None,
             namespace=None,
             prefix=None):
        if not ip_lib.device_exists(device_name, self.root_helper, namespace):
            ip = ip_lib.IPWrapper(self.root_helper)
            tap_name = device_name.replace(prefix or 'veth', 'veth')

            # Create ns_dev in a namespace if one is configured.
            root_dev, ns_dev = ip.add_veth(tap_name,
                                           device_name,
                                           namespace2=namespace)
            ns_dev.link.set_address(mac_address)
            namespace_obj = ip.ensure_namespace(namespace)
            namespace_obj.add_device_to_namespace(ns_dev)
            ns_dev.link.set_up()
            root_dev.link.set_up()

            self._add_port_to_agent(port_id, network_id, tap_name, mac_address)
            self._port_dict[tap_name] = port_id
        else:
            LOG.warn(_("Device %s already exists"), device_name)

    def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
        tap_name = device_name.replace(prefix or 'veth', 'veth')
        if tap_name in self._port_dict:
            self._delete_port(self._port_dict[tap_name])
            del self._port_dict[tap_name]

        device = ip_lib.IPDevice(device_name, self.root_helper, namespace)
        device.link.delete()
        LOG.debug(_("Unplugged interface '%s'"), device_name)
        ip_lib.IPWrapper(self.root_helper,
                         namespace).garbage_collect_namespace()
class VRouterApiTest(unittest.TestCase):
    def setUp(self):
        self._api = ContrailVRouterApi()

    def test_create_port(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client
        self._api.add_port(str(uuid.uuid1()), str(uuid.uuid1()), 'tapX',
                           'aa:bb:cc:ee:ff:00')
        self.assertTrue(mock_client.AddPort.called)

    def test_delete_port(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client

        vm_uuid = uuid.uuid1()
        vif_uuid = uuid.uuid1()
        self._api.add_port(str(vm_uuid), str(vif_uuid), 'tapX',
                           'aa:bb:cc:ee:ff:00')
        self.assertTrue(mock_client.AddPort.called)
        self.assertTrue(self._api._ports[vif_uuid])

        self._api.delete_port(str(vif_uuid))
        self.assertTrue(mock_client.DeletePort.called)

    def test_resynchronize(self):
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = None

        vm_uuid = str(uuid.uuid1())
        vif_uuid = str(uuid.uuid1())
        self._api.add_port(vm_uuid, vif_uuid, 'tapX', 'aa:bb:cc:ee:ff:00')

        mock_client = mock.Mock()
        self._api._rpc_client_instance.return_value = mock_client
        self._api.periodic_connection_check()
        self.assertTrue(mock_client.AddPort.called)

    def test_additional_arguments(self):
        mock_client = mock.Mock()
        self._api._rpc_client_instance = mock.MagicMock(
            name='rpc_client_instance')
        self._api._rpc_client_instance.return_value = mock_client
        vif_uuid = uuid.uuid1()
        network_uuid = uuid.uuid1()
        project_uuid = uuid.uuid1()
        self._api.add_port(str(uuid.uuid1()), str(vif_uuid), 'tapX',
                           'aa:bb:cc:ee:ff:00',
                           network_uuid=str(network_uuid),
                           vm_project_uuid=str(project_uuid))
        self.assertTrue(mock_client.AddPort.called)
        port = self._api._ports[vif_uuid]
        self.assertEqual(self._api._uuid_to_hex(network_uuid),
                         port.vn_id)
        self.assertEqual(self._api._uuid_to_hex(project_uuid),
                         port.vm_project_uuid)
Exemple #40
0
 def __init__(self, vmName):
     super(OpenContrailVirtualMachineInterface, self).__init__()
     self._vrouter_client = ContrailVRouterApi(doconnect=True)
     self.vmName = vmName
class VRouterVIFDriver(LibvirtBaseVIFDriver):
    """VIF driver for VRouter when running Neutron."""

    PORT_TYPE = 'NovaVMPort'

    def __init__(self, get_connection):
        super(VRouterVIFDriver, self).__init__(get_connection)
        self._vrouter_client = ContrailVRouterApi()
        timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
        timer.start(interval=2)

    def _keep_alive(self):
        self._vrouter_client.periodic_connection_check()

    @staticmethod
    def _get_br_name(dev):
        """Returns the bridge name for a tap device.
        This is lxc related stuff. To work around the fact, that libvirt does
        not support direct passthrough of devices to LXC."""
        return 'br%s' % dev[3:]

    def _create_bridge(self, dev, instance):
        """Creating a bridge and returning its name"""
        br_name = self._get_br_name(dev)

        try:
            linux_net.LinuxBridgeInterfaceDriver.ensure_bridge(br_name, dev)
            linux_net._execute('ip',
                               'link',
                               'set',
                               br_name,
                               'promisc',
                               'on',
                               run_as_root=True)
        except processutils.ProcessExecutionError:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

        return br_name

    def get_config(self, instance, vif, image_meta, inst_type):
        conf = super(VRouterVIFDriver,
                     self).get_config(instance, vif, image_meta, inst_type)
        dev = self.get_vif_devname(vif)
        if cfg.CONF.libvirt.virt_type == 'lxc':
            # for lxc we need to pass a bridge to libvirt
            br_name = self._get_br_name(dev)
            designer.set_vif_host_backend_bridge_config(conf, br_name)
        else:
            designer.set_vif_host_backend_ethernet_config(conf, dev)
        designer.set_vif_bandwidth_config(conf, inst_type)

        return conf

    def plug(self, instance, vif):
        dev = self.get_vif_devname(vif)

        try:
            linux_net.create_tap_dev(dev)
        except processutils.ProcessExecutionError:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

        if cfg.CONF.libvirt.virt_type == 'lxc':
            dev = self._create_bridge(dev, instance)

        kwargs = {
            'ip_address': vif['network']['subnets'][0]['ips'][0]['address'],
            'vn_id': vif['network']['id'],
            'display_name': instance['display_name'],
            'hostname': instance['hostname'],
            'host': instance['host'],
            'vm_project_id': instance['project_id'],
            'port_type': self.PORT_TYPE,
        }
        try:
            result = self._vrouter_client.add_port(instance['uuid'], vif['id'],
                                                   dev, vif['address'],
                                                   **kwargs)
            if not result:
                LOG.exception(_LE("Failed while plugging vif"),
                              instance=instance)
        except TApplicationException:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)

    def unplug(self, instance, vif):
        dev = self.get_vif_devname(vif)

        try:
            self._vrouter_client.delete_port(vif['id'])
            #delegate the deletion of tap device to a deffered thread
            worker_thread = threading.Thread(target=self.delete_device, \
  name='contrailvif', args=(dev,))
            worker_thread.start()
        except (TApplicationException, processutils.ProcessExecutionError,\
     RuntimeError):
            LOG.exception(_LE("Failed while unplugging vif"),
                          instance=instance)

    def delete_device(self, dev):
        time.sleep(2)
        LOG.debug(dev)
        if cfg.CONF.libvirt.virt_type == 'lxc':
            linux_net.LinuxBridgeInterfaceDriver.remove_bridge(
                self._get_br_name(dev))
        linux_net.delete_net_dev(dev)
class ContrailInterfaceDriver(interface.LinuxInterfaceDriver):
    """ Opencontrail VIF driver for neutron."""

    @classmethod
    def _parse_class_args(cls, cfg_parser):
        cfg_parser.read(CONTRAIL_CFG_FILE)
        cls._api_server_ip = _read_cfg(cfg_parser, 'APISERVER',
                                       'api_server_ip', '127.0.0.1')
        cls._api_server_port = _read_cfg(cfg_parser, 'APISERVER',
                                         'api_server_port', '8082')
        cls._api_server_use_ssl  = _read_cfg(cfg_parser, 'APISERVER',
                                         'use_ssl', False)

    def __init__(self, conf):
        super(ContrailInterfaceDriver, self).__init__(conf)
        self._port_dict = {}
        self._client = self._connect_to_api_server()
        self._vrouter_client = ContrailVRouterApi()
        timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
        timer.start(interval=2)

    def _connect_to_api_server(self):
        cfg_parser = ConfigParser.ConfigParser()
        ContrailInterfaceDriver._parse_class_args(cfg_parser)
        try:
            client = VncApi(api_server_host=self._api_server_ip,
                            api_server_port=self._api_server_port,
                            api_server_use_ssl=self._api_server_use_ssl)
            return client
        except:
            pass

    def _keep_alive(self):
        self._vrouter_client.periodic_connection_check()

    def _delete_port(self, port_id):
        self._vrouter_client.delete_port(port_id)

    def _instance_locate(self, port_obj):
        """ lookup the instance associated with the port object.
        Create the vm instance if port object is not associated
        with a vm instance
        """
        if port_obj.get_virtual_machine_refs() is not None:
            try:
                vm_uuid = port_obj.get_virtual_machine_refs()[0]['uuid']
                instance_obj = self._client.virtual_machine_read(id=vm_uuid)
                return instance_obj
            except NoIdError:
                pass

        vm_uuid = str(uuid.uuid4())
        instance_obj = VirtualMachine(vm_uuid)
        instance_obj.uuid = vm_uuid
        self._client.virtual_machine_create(instance_obj)
        port_obj.set_virtual_machine(instance_obj)
        self._client.virtual_machine_interface_update(port_obj)
        return instance_obj

    def _add_port_to_agent(self, port_id, net_id, iface_name, mac_address):
        port_obj = self._client.virtual_machine_interface_read(id=port_id)
        if port_obj is None:
            LOG.debug(_("Invalid port_id : %s"), port_id)
            return

        ips = port_obj.get_instance_ip_back_refs()
        ip_addr = '0.0.0.0'
        # get the ip address of the port if associated
        if ips and len(ips):
            ip_uuid = ips[0]['uuid']
            ip = self._client.instance_ip_read(id=ip_uuid)
            ip_addr = ip.get_instance_ip_address()

        net_obj = self._client.virtual_network_read(id=net_id)
        if net_obj is None:
            LOG.debug(_("Invalid net_id : %s"), net_id)
            return

        # get the instance object the port is attached to
        instance_obj = self._instance_locate(port_obj)

        if instance_obj is None:
            return

        kwargs = {}
        kwargs['ip_address'] = ip_addr
        kwargs['network_uuid'] = net_id
        kwargs['vm_project_uuid'] = net_obj.parent_uuid
        self._vrouter_client.add_port(instance_obj.uuid, port_id, iface_name,
                                      mac_address, **kwargs)

    def plug(self, network_id, port_id, device_name, mac_address,
             bridge=None, namespace=None, prefix=None):
        if not ip_lib.device_exists(device_name, self.root_helper, namespace):
            ip = ip_lib.IPWrapper(self.root_helper)
            tap_name = device_name.replace(prefix or 'veth', 'veth')

            # Create ns_dev in a namespace if one is configured.
            root_dev, ns_dev = ip.add_veth(tap_name,
                                           device_name,
                                           namespace2=namespace)
            ns_dev.link.set_address(mac_address)
            namespace_obj = ip.ensure_namespace(namespace)
            namespace_obj.add_device_to_namespace(ns_dev)
            ns_dev.link.set_up()
            root_dev.link.set_up()

            self._add_port_to_agent(port_id, network_id,
                                    tap_name, mac_address)
            self._port_dict[tap_name] = port_id
        else:
            LOG.warn(_("Device %s already exists"), device_name)

    def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
        tap_name = device_name.replace(prefix or 'veth', 'veth')
        if tap_name in self._port_dict:
            self._delete_port(self._port_dict[tap_name])
            del self._port_dict[tap_name]

        device = ip_lib.IPDevice(device_name, self.root_helper, namespace)
        device.link.delete()
        LOG.debug(_("Unplugged interface '%s'"), device_name)
        ip_lib.IPWrapper(
            self.root_helper, namespace).garbage_collect_namespace()
 def __init__(self, get_connection):
     super(VRouterVIFDriver, self).__init__(get_connection)
     self._vrouter_client = ContrailVRouterApi()
     timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
     timer.start(interval=2)
Exemple #44
0
class OpenContrailVIFDriver(object):
    def __init__(self):
        self._vrouter_semaphore = eventlet.semaphore.Semaphore()
        self._vrouter_client = ContrailVRouterApi(
            doconnect=True, semaphore=self._vrouter_semaphore)
        timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
        timer.start(interval=2)

    def _keep_alive(self):
        self._vrouter_client.periodic_connection_check()

    def plug(self, instance, vif):
        vif_type = vif['type']

        LOG.debug(
            'Plug vif_type=%(vif_type)s instance=%(instance)s '
            'vif=%(vif)s', {
                'vif_type': vif_type,
                'instance': instance,
                'vif': vif
            })

        if_local_name = 'veth%s' % vif['id'][:8]
        if_remote_name = 'ns%s' % vif['id'][:8]

        # Device already exists so return.
        if linux_net.device_exists(if_local_name):
            return
        undo_mgr = utils.UndoManager()

        try:
            utils.execute('ip',
                          'link',
                          'add',
                          if_local_name,
                          'type',
                          'veth',
                          'peer',
                          'name',
                          if_remote_name,
                          run_as_root=True)
            undo_mgr.undo_with(lambda: utils.execute(
                'ip', 'link', 'delete', if_local_name, run_as_root=True))

            utils.execute('ip',
                          'link',
                          'set',
                          if_remote_name,
                          'address',
                          vif['address'],
                          run_as_root=True)

        except Exception:
            LOG.exception("Failed to configure network")
            msg = _('Failed to setup the network, rolling back')
            undo_mgr.rollback_and_reraise(msg=msg, instance=instance)

    def attach(self, instance, vif, container_id):
        vif_type = vif['type']

        LOG.debug(
            'Attach vif_type=%(vif_type)s instance=%(instance)s '
            'vif=%(vif)s', {
                'vif_type': vif_type,
                'instance': instance,
                'vif': vif
            })

        if_local_name = 'veth%s' % vif['id'][:8]
        if_remote_name = 'ns%s' % vif['id'][:8]

        undo_mgr = utils.UndoManager()
        undo_mgr.undo_with(lambda: utils.execute(
            'ip', 'link', 'delete', if_local_name, run_as_root=True))
        ipv4_address = '0.0.0.0'
        ipv6_address = None
        if 'subnets' in vif['network']:
            subnets = vif['network']['subnets']
            for subnet in subnets:
                ips = subnet['ips'][0]
                if (ips['version'] == 4):
                    if ips['address'] is not None:
                        ipv4_address = ips['address']
                        ipv4_netmask = subnet['cidr'].split('/')[1]
                        ipv4_gateway = subnet['gateway']['address']
                if (ips['version'] == 6):
                    if ips['address'] is not None:
                        ipv6_address = ips['address']
                        ipv6_netmask = subnet['cidr'].split('/')[1]
                        ipv6_gateway = subnet['gateway']['address']
        params = {
            'ip_address': ipv4_address,
            'vn_id': vif['network']['id'],
            'display_name': instance['display_name'],
            'hostname': instance['hostname'],
            'host': instance['host'],
            'vm_project_id': instance['project_id'],
            'port_type': 'NovaVMPort',
            'ip6_address': ipv6_address,
        }

        try:
            utils.execute('ip',
                          'link',
                          'set',
                          if_remote_name,
                          'netns',
                          container_id,
                          run_as_root=True)

            result = self._vrouter_client.add_port(instance['uuid'], vif['id'],
                                                   if_local_name,
                                                   vif['address'], **params)
            if not result:
                # follow the exception path
                raise RuntimeError('add_port returned %s' % str(result))
            utils.execute('ip',
                          'link',
                          'set',
                          if_local_name,
                          'up',
                          run_as_root=True)
        except Exception:
            LOG.exception("Failed to attach the network")
            msg = _('Failed to attach the network, rolling back')
            undo_mgr.rollback_and_reraise(msg=msg, instance=instance)

        try:
            utils.execute('ip',
                          'netns',
                          'exec',
                          container_id,
                          'ip',
                          'link',
                          'set',
                          if_remote_name,
                          'address',
                          vif['address'],
                          run_as_root=True)
            if ipv6_address:
                ip = ipv6_address + "/" + ipv6_netmask
                gateway = ipv6_gateway
                utils.execute('ip',
                              'netns',
                              'exec',
                              container_id,
                              'ifconfig',
                              if_remote_name,
                              'inet6',
                              'add',
                              ip,
                              run_as_root=True)
                utils.execute('ip',
                              'netns',
                              'exec',
                              container_id,
                              'ip',
                              '-6',
                              'route',
                              'replace',
                              'default',
                              'via',
                              gateway,
                              'dev',
                              if_remote_name,
                              run_as_root=True)
            if ipv4_address != '0.0.0.0':
                ip = ipv4_address + "/" + ipv4_netmask
                gateway = ipv4_gateway
                utils.execute('ip',
                              'netns',
                              'exec',
                              container_id,
                              'ifconfig',
                              if_remote_name,
                              ip,
                              run_as_root=True)
                utils.execute('ip',
                              'netns',
                              'exec',
                              container_id,
                              'ip',
                              'route',
                              'replace',
                              'default',
                              'via',
                              gateway,
                              'dev',
                              if_remote_name,
                              run_as_root=True)
            utils.execute('ip',
                          'netns',
                          'exec',
                          container_id,
                          'ip',
                          'link',
                          'set',
                          if_remote_name,
                          'up',
                          run_as_root=True)
        except Exception:
            LOG.exception(_("Failed to attach vif"), instance=instance)

    def unplug(self, instance, vif):
        vif_type = vif['type']
        if_local_name = 'veth%s' % vif['id'][:8]

        LOG.debug(
            'Unplug vif_type=%(vif_type)s instance=%(instance)s '
            'vif=%(vif)s', {
                'vif_type': vif_type,
                'instance': instance,
                'vif': vif
            })

        try:
            self._vrouter_client.delete_port(vif['id'])
            if linux_net.device_exists(if_local_name):
                utils.execute('ip',
                              'link',
                              'delete',
                              if_local_name,
                              run_as_root=True)
        except Exception:
            LOG.exception(_("Delete port failed"), instance=instance)
Exemple #45
0
class OpenContrailVIFDriver(object):
    def __init__(self):
        self._vrouter_client = ContrailVRouterApi(doconnect=True)

    def plug(self, instance, vif):
        if_local_name = 'veth%s' % vif['id'][:8]
        if_remote_name = 'ns%s' % vif['id'][:8]

        # Device already exists so return.
        if linux_net.device_exists(if_local_name):
            return
        undo_mgr = utils.UndoManager()

        try:
            utils.execute('ip', 'link', 'add', if_local_name, 'type', 'veth',
                          'peer', 'name', if_remote_name, run_as_root=True)
            undo_mgr.undo_with(lambda: utils.execute(
                'ip', 'link', 'delete', if_local_name, run_as_root=True))

            utils.execute('ip', 'link', 'set', if_remote_name, 'address',
                          vif['address'], run_as_root=True)

        except Exception:
            LOG.exception("Failed to configure network")
            msg = _('Failed to setup the network, rolling back')
            undo_mgr.rollback_and_reraise(msg=msg, instance=instance)

    def attach(self, instance, vif, container_id):
        if_local_name = 'veth%s' % vif['id'][:8]
        if_remote_name = 'ns%s' % vif['id'][:8]

        undo_mgr = utils.UndoManager()
        ipv4_address = '0.0.0.0'
        ipv6_address = None
        if 'subnets' in vif['network']:
            subnets = vif['network']['subnets']
            for subnet in subnets:
                ips = subnet['ips'][0]
                if (ips['version'] == 4):
                    if ips['address'] is not None:
                        ipv4_address = ips['address']
                if (ips['version'] == 6):
                    if ips['address'] is not None:
                        ipv6_address = ips['address']
        params = {
            'ip_address': ipv4_address,
            'vn_id': vif['network']['id'],
            'display_name': instance['display_name'],
            'hostname': instance['hostname'],
            'host': instance['host'],
            'vm_project_id': instance['project_id'],
            'port_type': 'NovaVMPort',
            'ip6_address': ipv6_address,
        }

        try:
            utils.execute('ip', 'link', 'set', if_remote_name, 'netns',
                          container_id, run_as_root=True)

            result = self._vrouter_client.add_port(
                instance['uuid'], vif['id'],
                if_local_name, vif['address'], **params)
            if not result:
                # follow the exception path
                raise RuntimeError('add_port returned %s' % str(result))
            utils.execute('ip', 'link', 'set', if_local_name, 'up',
                          run_as_root=True)
        except Exception:
            LOG.exception("Failed to attach the network")
            msg = _('Failed to attach the network, rolling back')
            undo_mgr.rollback_and_reraise(msg=msg, instance=instance)

        # TODO(NetNS): attempt DHCP client; fallback to manual config if the
        # container doesn't have an working dhcpclient
        utils.execute('ip', 'netns', 'exec', container_id, 'dhclient',
                      if_remote_name, run_as_root=True)

    def unplug(self, instance, vif):
        try:
            self._vrouter_client.delete_port(vif['id'])
        except Exception:
            LOG.exception(_("Delete port failed"), instance=instance)

        if_local_name = 'veth%s' % vif['id'][:8]
        utils.execute('ip', 'link', 'delete', if_local_name, run_as_root=True)
 def setUp(self):
     self._api = ContrailVRouterApi()
Exemple #47
0
 def __init__(self):
     self._vrouter_client = ContrailVRouterApi(doconnect=True)
def interface_unregister(vmi_uuid):
    api = ContrailVRouterApi()
    api.delete_port(vmi_uuid)
def interface_register(vm, vmi, iface_name):
    api = ContrailVRouterApi()
    mac = vmi.virtual_machine_interface_mac_addresses.mac_address[0]
    api.add_port(vm.uuid, vmi.uuid, iface_name, mac)
Exemple #50
0
 def __init__(self):
     self._vrouter_semaphore = eventlet.semaphore.Semaphore()
     self._vrouter_client = ContrailVRouterApi(
         doconnect=True, semaphore=self._vrouter_semaphore)
     timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
     timer.start(interval=2)
def interface_unregister(vmi_uuid):
    api = ContrailVRouterApi()
    api.delete_port(vmi_uuid)
 def __init__(self, get_connection):
     super(VRouterVIFDriver, self).__init__(get_connection)
     self._vrouter_client = ContrailVRouterApi()
     timer = loopingcall.FixedIntervalLoopingCall(self._keep_alive)
     timer.start(interval=2)
class NetnsManager(object):
    SNAT_RT_TABLES_ID = 42
    DEV_NAME_LEN = 14
    NETNS_PREFIX = 'vrouter-'
    LEFT_DEV_PREFIX = 'int-'
    RIGH_DEV_PREFIX = 'gw-'
    TAP_PREFIX = 'veth'
    PORT_TYPE = 'NameSpacePort'
    LBAAS_PROCESS = 'haproxy'

    def __init__(self, vm_uuid, nic_left, nic_right, other_nics=None,
                 root_helper='sudo', cfg_file=None, update=False,
                 pool_id=None, gw_ip=None, namespace_name=None):
        self.vm_uuid = vm_uuid
        if namespace_name is None:
            self.namespace = self.NETNS_PREFIX + self.vm_uuid
        else:
            self.namespace = namespace_name
        if pool_id:
            self.namespace = self.namespace + ":" + pool_id
        self.nic_left = nic_left
        self.nic_right = nic_right
        self.root_helper = root_helper
        self.nics = other_nics or []
        if self.nic_left:
            self.nic_left['name'] = (self.LEFT_DEV_PREFIX +
                                 self.nic_left['uuid'])[:self.DEV_NAME_LEN]
            self.nics.append(self.nic_left)
        if self.nic_right:
            self.nic_right['name'] = (self.RIGH_DEV_PREFIX +
                                      self.nic_right['uuid'])[:self.DEV_NAME_LEN]
            self.nics.append(self.nic_right)
        self.ip_ns = ip_lib.IPWrapper(root_helper=self.root_helper,
                                      namespace=self.namespace)
        self.vrouter_client = ContrailVRouterApi()
        self.cfg_file = cfg_file
        self.update = update
        self.gw_ip = gw_ip

    def _get_tap_name(self, uuid_str):
            return (self.TAP_PREFIX + uuid_str)[:self.DEV_NAME_LEN]

    def is_netns_already_exists(self):
        return self.ip_ns.netns.exists(self.namespace)

    def create(self):
        ip = ip_lib.IPWrapper(self.root_helper)
        ip.ensure_namespace(self.namespace)
        for nic in self.nics:
            self._create_interfaces(ip, nic)

    def set_snat(self):
        if not self.ip_ns.netns.exists(self.namespace):
            raise ValueError('Need to create the network namespace before set '
                             'up the SNAT')

        self.ip_ns.netns.execute(['sysctl', '-w', 'net.ipv4.ip_forward=1'])
        self.ip_ns.netns.execute(['iptables', '-t', 'nat', '-F'])
        self.ip_ns.netns.execute(['iptables', '-t', 'nat', '-A', 'POSTROUTING',
                                  '-s', '0.0.0.0/0', '-o',
                                  self.nic_right['name'], '-j', 'MASQUERADE'])
        self.ip_ns.netns.execute(['ip', 'route', 'replace', 'default', 'dev',
                                  self.nic_right['name']])
        self.ip_ns.netns.execute(['ip', 'route', 'replace', 'default', 'dev',
                                  self.nic_left['name'], 'table',
                                  self.SNAT_RT_TABLES_ID])
        try:
            self.ip_ns.netns.execute(['ip', 'rule', 'del', 'iif',
                                      str(self.nic_right['name']), 'table',
                                      self.SNAT_RT_TABLES_ID])
        except RuntimeError:
            pass
        self.ip_ns.netns.execute(['ip', 'rule', 'add', 'iif',
                                  str(self.nic_right['name']), 'table',
                                  self.SNAT_RT_TABLES_ID])

        self.ip_ns.netns.execute(['ip', 'route', 'del', 'default', 'table',
                                 self.SNAT_RT_TABLES_ID])

        self.ip_ns.netns.execute(['ip', 'route', 'add', 'default', 'table',
                                 self.SNAT_RT_TABLES_ID, 'via',  self.gw_ip,
                                 'dev', str(self.nic_left['name'])])

    def _get_lbaas_pid(self):
        cmd = """ps aux | grep  \'%(process)s -f %(file)s\' | grep -v grep 
              """ % {'process':self.LBAAS_PROCESS, 'file':self.cfg_file}
        try:
            if "check_output" not in dir(subprocess):
                s = _check_output(cmd)
            else:
                s = subprocess.check_output(cmd, shell=True)
                
        except subprocess.CalledProcessError:
            return None
        words = s.split()
        pid = int(words[1])
        return pid

    def set_lbaas(self):
        if not self.ip_ns.netns.exists(self.namespace):
            raise ValueError('Need to create the network namespace before set '
                             'up the lbaas')
        pid_file = self.cfg_file + ".pid"
        pid = self._get_lbaas_pid()
        if (self.update is False):
            if pid is not None:
                self.release_lbaas()

            self.ip_ns.netns.execute([self.LBAAS_PROCESS, '-f', self.cfg_file, '-D',
                                    '-p', pid_file])
            self.ip_ns.netns.execute(['route', 'add', 'default', 'gw', self.gw_ip])
        else:
            if pid is not None:
                self.ip_ns.netns.execute([self.LBAAS_PROCESS, '-f', self.cfg_file, '-D', '-p', pid_file, '-sf', pid])
            else:
                self.ip_ns.netns.execute([self.LBAAS_PROCESS, '-f', self.cfg_file, '-D',
                                    '-p', pid_file])
        try:
            self.ip_ns.netns.execute(['route', 'add', 'default', 'gw', self.gw_ip])
        except RuntimeError:
            pass

    def release_lbaas(self):
        if not self.ip_ns.netns.exists(self.namespace):
            raise ValueError('Need to create the network namespace before '
                             'relasing lbaas')
        pid = self._get_lbaas_pid()
        if pid is not None:
            cmd = """kill -9 %(pid)s""" % {'pid':pid}
            try:
                if "check_output" not in dir(subprocess):
                    s = _check_output(cmd)
                else:
                    s = subprocess.check_output(cmd, shell=True)
                print ("Haproxy process with pid %d config file %s killed" %(pid, self.cfg_file), file=sys.stderr)
            except subprocess.CalledProcessError:
                print ("SIGKILL Error for pid %d %s" %(pid, self.cfg_file), file=sys.stderr)
        try:
            self.ip_ns.netns.execute(['route', 'del', 'default'])
        except RuntimeError:
            pass

    def destroy(self):
        if not self.ip_ns.netns.exists(self.namespace):
            raise ValueError('Namespace %s does not exist' % self.namespace)

        for device in self.ip_ns.get_devices(exclude_loopback=True):
            ip_lib.IPDevice(device.name,
                            self.root_helper,
                            self.namespace).link.delete()

        self.ip_ns.netns.delete(self.namespace)

    def plug_namespace_interface(self):
        for nic in self.nics:
            self._add_port_to_agent(nic,
                                    display_name='NetNS %s %s interface'
                                                 % (self.vm_uuid, nic['name']))

    def unplug_namespace_interface(self):
        for nic in self.nics:
            self._delete_port_to_agent(nic)

    def _create_interfaces(self, ip, nic):
        if ip_lib.device_exists(nic['name'],
                                self.root_helper,
                                namespace=self.namespace):
            ip_lib.IPDevice(nic['name'],
                            self.root_helper,
                            self.namespace).link.delete()

        root_dev, ns_dev = ip.add_veth(self._get_tap_name(nic['uuid']),
                                       nic['name'],
                                       namespace2=self.namespace)
        if nic['mac']:
            ns_dev.link.set_address(str(nic['mac']))

        ns_dev.link.set_up()
        root_dev.link.set_up()

        if nic['ip']:
            ip = nic['ip']
            ns_dev.addr.flush()
            ns_dev.addr.add(ip.version, str(ip), str(ip.broadcast))
        else:
            #TODO(ethuleau): start DHCP client
            raise NotImplementedError

        # disable reverse path filtering
        self.ip_ns.netns.execute(['sysctl', '-w',
                                  'net.ipv4.conf.%s.rp_filter=2' % nic['name']]
                                 )

    def _add_port_to_agent(self, nic, display_name=None):
        kwargs = {}
        kwargs['port_type'] = self.PORT_TYPE
        kwargs['ip_address'] = str(nic['ip'].ip)
        if display_name:
            kwargs['display_name'] = display_name

        if not (self.vrouter_client.add_port(self.vm_uuid, nic['uuid'],
                                             self._get_tap_name(nic['uuid']),
                                             str(nic['mac']), **kwargs)):
            raise ValueError('Cannot add interface %s on the vrouter' %
                             nic['uuid'])

    def _delete_port_to_agent(self, nic):
        self.vrouter_client.delete_port(nic['uuid'])