From 6f7847f5917a80d224031bb92b63530fe4965734 Mon Sep 17 00:00:00 2001 From: fmenguy Date: Wed, 9 Jan 2019 11:22:50 +0100 Subject: NFVBENCH-120 No admin support patch Change-Id: Iaaf29e4eb439243348e955e796b6f951c184ee19 Signed-off-by: fmenguy --- nfvbench/cfg.default.yaml | 13 +++++++++++-- nfvbench/chaining.py | 34 +++++++++++++++++++++++++++------- nfvbench/credentials.py | 15 +++++++++++++++ 3 files changed, 53 insertions(+), 9 deletions(-) (limited to 'nfvbench') diff --git a/nfvbench/cfg.default.yaml b/nfvbench/cfg.default.yaml index fa3d807..c2fa29e 100755 --- a/nfvbench/cfg.default.yaml +++ b/nfvbench/cfg.default.yaml @@ -25,6 +25,11 @@ # The only case where this field can be empty is when measuring a system that does not run # OpenStack or when OpenStack APIs are not accessible or OpenStack APis use is not # desirable. In that case the EXT service chain must be used. +# +# If openrc is not admin some parameters are mandatory and must be filled with valid values in config file such as : +# - availability_zone +# - hypervisor_hostname +# - vlans openrc_file: # Forwarder to use in nfvbenchvm image. Available options: ['vpp', 'testpmd'] @@ -66,11 +71,15 @@ flavor: # Name of the availability zone to use for the test VMs # Must be one of the zones listed by 'nova availability-zone-list' # availability_zone: 'nova' +# If openrc is not admin set a valid value availability_zone: # To force placement on a given hypervisor, set the name here # (if multiple names are provided, the first will be used) # Leave empty to let openstack pick the hypervisor compute_nodes: +# If openrc is not admin set a valid value for hypervisor hostname +# Example of value: hypervisor_hostname: "server1" +hypervisor_hostname: # Type of service chain to run, possible options are PVP, PVVP and EXT # PVP - port to VM to port @@ -192,7 +201,7 @@ traffic_generator: # # Generator profiles are listed in the following format: # `name`: Traffic generator profile name (use a unique name, no space or special character) - # DFo not change this field + # Do not change this field # `tool`: Traffic generator tool to be used (currently supported is `TRex`). # Do not change this field # `ip`: IP address of the traffic generator. @@ -369,7 +378,7 @@ vxlan: false # is not supported). Use the vtep_vlan option to enable vlan tagging for the VxLAN overlay network. vlan_tagging: true -# Used only in the case of EXT chain and no openstack to specify the VLAN IDs to use. +# Used only in the case of EXT chain and no openstack or not admin access to specify the VLAN IDs to use. # This property is ignored when OpenStakc is used or in the case of l2-loopback. # If OpenStack is used leave the list empty, VLAN IDs are retrieved from OpenStack networks using Neutron API. # If networks are shared across all chains (service_chain_shared_net=true), the list should have exactly 2 values diff --git a/nfvbench/chaining.py b/nfvbench/chaining.py index a97cd0b..1a977da 100644 --- a/nfvbench/chaining.py +++ b/nfvbench/chaining.py @@ -522,7 +522,13 @@ class ChainVnf(object): def get_hostname(self): """Get the hypervisor host name running this VNF instance.""" - return getattr(self.instance, 'OS-EXT-SRV-ATTR:hypervisor_hostname') + if self.manager.is_admin: + hypervisor_hostname = getattr(self.instance, 'OS-EXT-SRV-ATTR:hypervisor_hostname') + else: + hypervisor_hostname = self.manager.config.hypervisor_hostname + if not hypervisor_hostname: + raise ChainException('Hypervisor hostname parameter is mandatory') + return hypervisor_hostname def get_host_ip(self): """Get the IP address of the host where this instance runs. @@ -536,7 +542,12 @@ class ChainVnf(object): def get_hypervisor_name(self): """Get hypervisor name (az:hostname) for this VNF instance.""" if self.instance: - az = getattr(self.instance, 'OS-EXT-AZ:availability_zone') + if self.manager.is_admin: + az = getattr(self.instance, 'OS-EXT-AZ:availability_zone') + else: + az = self.manager.config.availability_zone + if not az: + raise ChainException('Availability zone parameter is mandatory') hostname = self.get_hostname() if az: return az + ':' + hostname @@ -851,6 +862,7 @@ class ChainManager(object): if self.openstack: # openstack only session = chain_runner.cred.get_session() + self.is_admin = chain_runner.cred.is_admin self.nova_client = Client(2, session=session) self.neutron_client = neutronclient.Client('2.0', session=session) self.glance_client = glanceclient.Client('2', session=session) @@ -877,12 +889,14 @@ class ChainManager(object): else: # Make sure all instances are active before proceeding self._ensure_instances_active() + # network API call do not show VLANS ID if not admin read from config + if not self.is_admin: + self._get_config_vlans() except Exception: self.delete() raise else: # no openstack, no need to create chains - if not config.l2_loopback and config.no_arp: self._get_dest_macs_from_config() if config.vlan_tagging: @@ -890,12 +904,18 @@ class ChainManager(object): if len(config.vlans) != 2: raise ChainException('The config vlans property must be a list ' 'with 2 lists of VLAN IDs') - re_vlan = "[0-9]*$" - self.vlans = [self._check_list('vlans[0]', config.vlans[0], re_vlan), - self._check_list('vlans[1]', config.vlans[1], re_vlan)] + self._get_config_vlans() if config.vxlan: raise ChainException('VxLAN is only supported with OpenStack') + def _get_config_vlans(self): + re_vlan = "[0-9]*$" + try: + self.vlans = [self._check_list('vlans[0]', self.config.vlans[0], re_vlan), + self._check_list('vlans[1]', self.config.vlans[1], re_vlan)] + except IndexError: + raise ChainException('vlans parameter is mandatory. Set valid value in config file') + def _get_dest_macs_from_config(self): re_mac = "[0-9a-fA-F]{2}([-:])[0-9a-fA-F]{2}(\\1[0-9a-fA-F]{2}){4}$" tg_config = self.config.traffic_generator @@ -1114,7 +1134,7 @@ class ChainManager(object): port_index: left port is 0, right port is 1 return: a VLAN ID list indexed by the chain index or None if no vlan tagging """ - if self.chains: + if self.chains and self.is_admin: return [self.chains[chain_index].get_vlan(port_index) for chain_index in range(self.chain_count)] # no openstack diff --git a/nfvbench/credentials.py b/nfvbench/credentials.py index 530ad69..b3e4a04 100644 --- a/nfvbench/credentials.py +++ b/nfvbench/credentials.py @@ -21,6 +21,8 @@ import getpass from keystoneauth1.identity import v2 from keystoneauth1.identity import v3 from keystoneauth1 import session +from keystoneclient import client +from keystoneclient import utils from log import LOG @@ -106,6 +108,7 @@ class Credentials(object): self.rc_project_domain_name = None self.rc_project_name = None self.rc_identity_api_version = 2 + self.is_admin = False success = True if openrc_file: @@ -164,3 +167,15 @@ class Credentials(object): 'Please enter your OpenStack Password: ') if not self.rc_password: self.rc_password = "" + + # check if user has admin role in OpenStack project + try: + keystone = client.Client(session=self.get_session()) + user = utils.find_resource(keystone.users, self.rc_username) + project = utils.find_resource(keystone.projects, self.rc_project_name) + roles = keystone.roles.list(user=user.id, project=project.id) + for role in roles: + if role.name == 'admin': + self.is_admin = True + except Exception: + LOG.warning("User is not admin, no permission to list user roles") -- cgit 1.2.3-korg