summaryrefslogtreecommitdiffstats
path: root/nfvbench/chaining.py
diff options
context:
space:
mode:
Diffstat (limited to 'nfvbench/chaining.py')
-rw-r--r--nfvbench/chaining.py112
1 files changed, 89 insertions, 23 deletions
diff --git a/nfvbench/chaining.py b/nfvbench/chaining.py
index 49d23b7..d035a40 100644
--- a/nfvbench/chaining.py
+++ b/nfvbench/chaining.py
@@ -135,6 +135,7 @@ class ChainVnfPort(object):
self.manager = vnf.manager
self.reuse = False
self.port = None
+ self.floating_ip = None
if vnf.instance:
# VNF instance is reused, we need to find an existing port that matches this instance
# and network
@@ -182,18 +183,35 @@ class ChainVnfPort(object):
"""Get the IP address for this port."""
return self.port['fixed_ips'][0]['ip_address']
+ def set_floating_ip(self, chain_network):
+ # create and add floating ip to port
+ try:
+ self.floating_ip = self.manager.neutron_client.create_floatingip({
+ 'floatingip': {
+ 'floating_network_id': chain_network.get_uuid(),
+ 'port_id': self.port['id'],
+ 'description': 'nfvbench floating ip for port:' + self.port['name'],
+ }})['floatingip']
+ LOG.info('Floating IP %s created and associated on port %s',
+ self.floating_ip['floating_ip_address'], self.name)
+ return self.floating_ip['floating_ip_address']
+ except Exception:
+ LOG.info('Failed to created and associated floating ip on port %s (ignored)', self.name)
+ return self.port['fixed_ips'][0]['ip_address']
+
def delete(self):
"""Delete this port instance."""
if self.reuse or not self.port:
return
- retry = 0
- while retry < self.manager.config.generic_retry_count:
+ for _ in range(0, self.manager.config.generic_retry_count):
try:
self.manager.neutron_client.delete_port(self.port['id'])
LOG.info("Deleted port %s", self.name)
+ if self.floating_ip:
+ self.manager.neutron_client.delete_floatingip(self.floating_ip['id'])
+ LOG.info("Deleted floating IP %s", self.floating_ip['description'])
return
except Exception:
- retry += 1
time.sleep(self.manager.config.generic_poll_sec)
LOG.error('Unable to delete port: %s', self.name)
@@ -358,17 +376,15 @@ class ChainNetwork(object):
def delete(self):
"""Delete this network."""
if not self.reuse and self.network:
- retry = 0
- while retry < self.manager.config.generic_retry_count:
+ for retry in range(0, self.manager.config.generic_retry_count):
try:
self.manager.neutron_client.delete_network(self.network['id'])
LOG.info("Deleted network: %s", self.name)
return
except Exception:
- retry += 1
LOG.info('Error deleting network %s (retry %d/%d)...',
self.name,
- retry,
+ retry + 1,
self.manager.config.generic_retry_count)
time.sleep(self.manager.config.generic_poll_sec)
LOG.error('Unable to delete network: %s', self.name)
@@ -397,6 +413,7 @@ class ChainVnf(object):
# For example if 7 idle interfaces are requested, the corresp. ports will be
# at index 2 to 8
self.ports = []
+ self.management_port = None
self.routers = []
self.status = None
self.instance = None
@@ -429,10 +446,12 @@ class ChainVnf(object):
tg_mac2 = self.routers[RIGHT].ports[1]['mac_address'] # router edge mac right
# edge cidr mask left
vnf_gateway1_cidr = \
- self.ports[LEFT].get_ip() + self.manager.config.edge_networks.left.cidr[-3:]
+ self.ports[LEFT].get_ip() + self.__get_network_mask(
+ self.manager.config.edge_networks.left.cidr)
# edge cidr mask right
vnf_gateway2_cidr = \
- self.ports[RIGHT].get_ip() + self.manager.config.edge_networks.right.cidr[-3:]
+ self.ports[RIGHT].get_ip() + self.__get_network_mask(
+ self.manager.config.edge_networks.right.cidr)
if config.vm_forwarder != 'vpp':
raise ChainException(
'L3 router mode imply to set VPP as VM forwarder.'
@@ -444,9 +463,11 @@ class ChainVnf(object):
tg_mac2 = remote_mac_pair[1]
g1cidr = devices[LEFT].get_gw_ip(
- self.chain.chain_id) + self.manager.config.internal_networks.left.cidr[-3:]
+ self.chain.chain_id) + self.__get_network_mask(
+ self.manager.config.internal_networks.left.cidr)
g2cidr = devices[RIGHT].get_gw_ip(
- self.chain.chain_id) + self.manager.config.internal_networks.right.cidr[-3:]
+ self.chain.chain_id) + self.__get_network_mask(
+ self.manager.config.internal_networks.right.cidr)
vnf_gateway1_cidr = g1cidr
vnf_gateway2_cidr = g2cidr
@@ -465,10 +486,27 @@ class ChainVnf(object):
'vnf_gateway2_cidr': vnf_gateway2_cidr,
'tg_mac1': tg_mac1,
'tg_mac2': tg_mac2,
- 'vif_mq_size': config.vif_multiqueue_size
+ 'vif_mq_size': config.vif_multiqueue_size,
+ 'num_mbufs': config.num_mbufs
}
+ if self.manager.config.use_management_port:
+ mgmt_ip = self.management_port.port['fixed_ips'][0]['ip_address']
+ mgmt_mask = self.__get_network_mask(self.manager.config.management_network.cidr)
+ vm_config['intf_mgmt_cidr'] = mgmt_ip + mgmt_mask
+ vm_config['intf_mgmt_ip_gw'] = self.manager.config.management_network.gateway
+ vm_config['intf_mac_mgmt'] = self.management_port.port['mac_address']
+ else:
+ # Interface management config left empty to avoid error in VM spawn
+ # if nfvbench config has values for management network but use_management_port=false
+ vm_config['intf_mgmt_cidr'] = ''
+ vm_config['intf_mgmt_ip_gw'] = ''
+ vm_config['intf_mac_mgmt'] = ''
return content.format(**vm_config)
+ @staticmethod
+ def __get_network_mask(network):
+ return '/' + network.split('/')[1]
+
def _get_vnic_type(self, port_index):
"""Get the right vnic type for given port indexself.
@@ -575,17 +613,28 @@ class ChainVnf(object):
self.instance = instance
LOG.info('Reusing existing instance %s on %s',
self.name, self.get_hypervisor_name())
+ # create management port if needed
+ if self.manager.config.use_management_port:
+ self.management_port = ChainVnfPort(self.name + '-mgmt', self,
+ self.manager.management_network, 'normal')
+ ip = self.management_port.port['fixed_ips'][0]['ip_address']
+ if self.manager.config.use_floating_ip:
+ ip = self.management_port.set_floating_ip(self.manager.floating_ip_network)
+ LOG.info("Management interface will be active using IP: %s, "
+ "and you can connect over SSH with login: nfvbench and password: nfvbench", ip)
# create or reuse/discover 2 ports per instance
if self.manager.config.l3_router:
- self.ports = [ChainVnfPort(self.name + '-' + str(index),
- self,
- networks[index + 2],
- self._get_vnic_type(index)) for index in [0, 1]]
+ for index in [0, 1]:
+ self.ports.append(ChainVnfPort(self.name + '-' + str(index),
+ self,
+ networks[index + 2],
+ self._get_vnic_type(index)))
else:
- self.ports = [ChainVnfPort(self.name + '-' + str(index),
- self,
- networks[index],
- self._get_vnic_type(index)) for index in [0, 1]]
+ for index in [0, 1]:
+ self.ports.append(ChainVnfPort(self.name + '-' + str(index),
+ self,
+ networks[index],
+ self._get_vnic_type(index)))
# create idle networks and ports only if instance is not reused
# if reused, we do not care about idle networks/ports
@@ -627,8 +676,10 @@ class ChainVnf(object):
def create_vnf(self, remote_mac_pair):
"""Create the VNF instance if it does not already exist."""
if self.instance is None:
- port_ids = [{'port-id': vnf_port.port['id']}
- for vnf_port in self.ports]
+ port_ids = []
+ if self.manager.config.use_management_port:
+ port_ids.append({'port-id': self.management_port.port['id']})
+ port_ids.extend([{'port-id': vnf_port.port['id']} for vnf_port in self.ports])
# add idle ports
for idle_port in self.idle_ports:
port_ids.append({'port-id': idle_port.port['id']})
@@ -736,6 +787,8 @@ class ChainVnf(object):
if self.instance:
self.manager.comp.delete_server(self.instance)
LOG.info("Deleted instance %s", self.name)
+ if self.manager.config.use_management_port:
+ self.management_port.delete()
for port in self.ports:
port.delete()
for port in self.idle_ports:
@@ -1052,6 +1105,16 @@ class ChainManager(object):
self.flavor = ChainFlavor(config.flavor_type, config.flavor, self.comp)
# Get list of all existing instances to check if some instances can be reused
self.existing_instances = self.comp.get_server_list()
+ # If management port is requested for VMs, create management network (shared)
+ if self.config.use_management_port:
+ self.management_network = ChainNetwork(self, self.config.management_network,
+ None, False)
+ # If floating IP is used for management, create and share
+ # across chains the floating network
+ if self.config.use_floating_ip:
+ self.floating_ip_network = ChainNetwork(self,
+ self.config.floating_network,
+ None, False)
else:
# For EXT chains, the external_networks left and right fields in the config
# must be either a prefix string or a list of at least chain-count strings
@@ -1419,7 +1482,6 @@ class ChainManager(object):
if hypervisor:
LOG.info('Found hypervisor for EXT chain: %s', hypervisor.hypervisor_hostname)
return[':' + hypervisor.hypervisor_hostname]
-
# no openstack = no chains
return []
@@ -1429,5 +1491,9 @@ class ChainManager(object):
chain.delete()
for network in self.networks:
network.delete()
+ if self.config.use_management_port and hasattr(self, 'management_network'):
+ self.management_network.delete()
+ if self.config.use_floating_ip and hasattr(self, 'floating_ip_network'):
+ self.floating_ip_network.delete()
if self.flavor:
self.flavor.delete()