Contrail VIF Driver changes for Nova-Compute
Add OpenContrail vif handling method for Creation/Deletion/Get of interfaces in Nova VIF driver. In this commit, we will also add new Vif Model - VIF_TYPE_VROUTER. implements: blueprint opencontrail-nova-vif-driver-plugin Change-Id: I202fdefb474319f8efbb0449d3fcb48b8a2ece13
This commit is contained in:
parent
466179093e
commit
bb612777bf
|
@ -83,6 +83,9 @@ tunctl: CommandFilter, tunctl, root
|
|||
# nova/network/linux_net.py: 'ovs-vsctl', ....
|
||||
ovs-vsctl: CommandFilter, ovs-vsctl, root
|
||||
|
||||
# nova/virt/libvirt/vif.py: 'vrouter-port-control', ...
|
||||
vrouter-port-control: CommandFilter, vrouter-port-control, root
|
||||
|
||||
# nova/network/linux_net.py: 'ovs-ofctl', ....
|
||||
ovs-ofctl: CommandFilter, ovs-ofctl, root
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ VIF_TYPE_HW_VEB = 'hw_veb'
|
|||
VIF_TYPE_MLNX_DIRECT = 'mlnx_direct'
|
||||
VIF_TYPE_MIDONET = 'midonet'
|
||||
VIF_TYPE_VHOSTUSER = 'vhostuser'
|
||||
VIF_TYPE_VROUTER = 'vrouter'
|
||||
VIF_TYPE_OTHER = 'other'
|
||||
|
||||
# Constants for dictionary keys in the 'vif_details' field in the VIF
|
||||
|
|
|
@ -235,6 +235,19 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
|||
subnets=[subnet_bridge_4],
|
||||
interface='eth0')
|
||||
|
||||
network_vrouter = network_model.Network(id='network-id-xxx-yyy-zzz',
|
||||
label=None,
|
||||
bridge=None,
|
||||
subnets=[subnet_bridge_4,
|
||||
subnet_bridge_6],
|
||||
interface='eth0')
|
||||
|
||||
vif_vrouter = network_model.VIF(id='vif-xxx-yyy-zzz',
|
||||
address='ca:fe:de:ad:be:ef',
|
||||
network=network_vrouter,
|
||||
type=network_model.VIF_TYPE_VROUTER,
|
||||
devname='tap-xxx-yyy-zzz')
|
||||
|
||||
vif_mlnx = network_model.VIF(id='vif-xxx-yyy-zzz',
|
||||
address='ca:fe:de:ad:be:ef',
|
||||
network=network_mlnx,
|
||||
|
@ -807,6 +820,43 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
|||
self.vif_mlnx)
|
||||
self.assertEqual(0, execute.call_count)
|
||||
|
||||
def test_unplug_vrouter_with_details(self):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
with mock.patch.object(utils, 'execute') as execute:
|
||||
d.unplug_vrouter(None, self.vif_vrouter)
|
||||
execute.assert_called_once_with(
|
||||
'vrouter-port-control',
|
||||
'--oper=delete --uuid=vif-xxx-yyy-zzz',
|
||||
run_as_root=True)
|
||||
|
||||
def test_plug_vrouter_with_details(self):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
instance = mock.Mock()
|
||||
instance.name = 'instance-name'
|
||||
instance.uuid = '46a4308b-e75a-4f90-a34a-650c86ca18b2'
|
||||
instance.project_id = 'b168ea26fa0c49c1a84e1566d9565fa5'
|
||||
instance.display_name = 'instance1'
|
||||
with mock.patch.object(utils, 'execute') as execute:
|
||||
d.plug_vrouter(instance, self.vif_vrouter)
|
||||
execute.assert_has_calls([
|
||||
mock.call('ip', 'tuntap', 'add', 'tap-xxx-yyy-zzz', 'mode',
|
||||
'tap', run_as_root=True, check_exit_code=[0, 2, 254]),
|
||||
mock.call('ip', 'link', 'set', 'tap-xxx-yyy-zzz', 'up',
|
||||
run_as_root=True, check_exit_code=[0, 2, 254]),
|
||||
mock.call('vrouter-port-control',
|
||||
'--oper=add --uuid=vif-xxx-yyy-zzz '
|
||||
'--instance_uuid=46a4308b-e75a-4f90-a34a-650c86ca18b2 '
|
||||
'--vn_uuid=network-id-xxx-yyy-zzz '
|
||||
'--vm_project_uuid=b168ea26fa0c49c1a84e1566d9565fa5 '
|
||||
'--ip_address=0.0.0.0 '
|
||||
'--ipv6_address=None '
|
||||
'--vm_name=instance1 '
|
||||
'--mac=ca:fe:de:ad:be:ef '
|
||||
'--tap_name=tap-xxx-yyy-zzz '
|
||||
'--port_type=NovaVMPort '
|
||||
'--tx_vlan_id=-1 '
|
||||
'--rx_vlan_id=-1', run_as_root=True)])
|
||||
|
||||
def test_ivs_ethernet_driver(self):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
self._check_ivs_ethernet_driver(d,
|
||||
|
|
|
@ -348,6 +348,16 @@ class LibvirtGenericVIFDriver(object):
|
|||
os.path.join(path, vif['id']))
|
||||
return conf
|
||||
|
||||
def get_config_vrouter(self, instance, vif, image_meta,
|
||||
inst_type, virt_type):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
inst_type, virt_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 get_config(self, instance, vif, image_meta,
|
||||
inst_type, virt_type):
|
||||
vif_type = vif['type']
|
||||
|
@ -532,6 +542,46 @@ class LibvirtGenericVIFDriver(object):
|
|||
def plug_vhostuser(self, instance, vif):
|
||||
pass
|
||||
|
||||
def plug_vrouter(self, instance, vif):
|
||||
"""Plug into Contrail's network port
|
||||
|
||||
Bind the vif to a Contrail virtual port.
|
||||
"""
|
||||
dev = self.get_vif_devname(vif)
|
||||
ip_addr = '0.0.0.0'
|
||||
ip6_addr = None
|
||||
subnets = vif['network']['subnets']
|
||||
for subnet in subnets:
|
||||
if not subnet['ips']:
|
||||
continue
|
||||
ips = subnet['ips'][0]
|
||||
if not ips['address']:
|
||||
continue
|
||||
if (ips['version'] == 4):
|
||||
if ips['address'] is not None:
|
||||
ip_addr = ips['address']
|
||||
if (ips['version'] == 6):
|
||||
if ips['address'] is not None:
|
||||
ip6_addr = ips['address']
|
||||
|
||||
ptype = 'NovaVMPort'
|
||||
if (cfg.CONF.libvirt.virt_type == 'lxc'):
|
||||
ptype = 'NameSpacePort'
|
||||
|
||||
cmd_args = ("--oper=add --uuid=%s --instance_uuid=%s --vn_uuid=%s "
|
||||
"--vm_project_uuid=%s --ip_address=%s --ipv6_address=%s"
|
||||
" --vm_name=%s --mac=%s --tap_name=%s --port_type=%s "
|
||||
"--tx_vlan_id=%d --rx_vlan_id=%d" % (vif['id'],
|
||||
instance.uuid, vif['network']['id'],
|
||||
instance.project_id, ip_addr, ip6_addr,
|
||||
instance.display_name, vif['address'],
|
||||
vif['devname'], ptype, -1, -1))
|
||||
try:
|
||||
linux_net.create_tap_dev(dev)
|
||||
utils.execute('vrouter-port-control', cmd_args, run_as_root=True)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(_LE("Failed while plugging vif"), instance=instance)
|
||||
|
||||
def plug(self, instance, vif):
|
||||
vif_type = vif['type']
|
||||
|
||||
|
@ -688,6 +738,20 @@ class LibvirtGenericVIFDriver(object):
|
|||
def unplug_vhostuser(self, instance, vif):
|
||||
pass
|
||||
|
||||
def unplug_vrouter(self, instance, vif):
|
||||
"""Unplug Contrail's network port
|
||||
|
||||
Unbind the vif from a Contrail virtual port.
|
||||
"""
|
||||
dev = self.get_vif_devname(vif)
|
||||
cmd_args = ("--oper=delete --uuid=%s" % (vif['id']))
|
||||
try:
|
||||
utils.execute('vrouter-port-control', cmd_args, run_as_root=True)
|
||||
linux_net.delete_net_dev(dev)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(
|
||||
_LE("Failed while unplugging vif"), instance=instance)
|
||||
|
||||
def unplug(self, instance, vif):
|
||||
vif_type = vif['type']
|
||||
|
||||
|
|
Loading…
Reference in New Issue