aboutsummaryrefslogtreecommitdiffstats
path: root/sfc/lib/openstack_utils.py
diff options
context:
space:
mode:
authorManuel Buil <mbuil@suse.com>2017-12-14 12:13:19 +0100
committerManuel Buil <mbuil@suse.com>2017-12-21 17:28:32 +0100
commitdeca6d35cd4ba0c6444b92d15b07ade1169d0ef3 (patch)
tree36abacae739f5c6bb494c2502b6ad3e37446d676 /sfc/lib/openstack_utils.py
parent163aacce943bf07a5603587b9ae681ff9bf4605b (diff)
Migrate to SNAPs openstack library
Functest is deprecating its openstack library which we were using extensively We need then to move to an alternative and the best appears to be SNAPs Change-Id: Icaa0b9f1ec580545b9d0faa88be2080a310deaf7 Signed-off-by: Manuel Buil<mbuil@suse.com>
Diffstat (limited to 'sfc/lib/openstack_utils.py')
-rw-r--r--sfc/lib/openstack_utils.py363
1 files changed, 187 insertions, 176 deletions
diff --git a/sfc/lib/openstack_utils.py b/sfc/lib/openstack_utils.py
index 2d4ecff3..f55f62e8 100644
--- a/sfc/lib/openstack_utils.py
+++ b/sfc/lib/openstack_utils.py
@@ -3,200 +3,207 @@ import os
import time
import json
import yaml
-import functest.utils.openstack_utils as os_utils
from tackerclient.tacker import client as tackerclient
from functest.utils.constants import CONST
+from snaps.openstack.tests import openstack_tests
-logger = logging.getLogger(__name__)
-DEFAULT_TACKER_API_VERSION = '1.0'
+from snaps.openstack.create_image import OpenStackImage
+from snaps.config.image import ImageConfig
+from snaps.config.flavor import FlavorConfig
+from snaps.openstack.create_flavor import OpenStackFlavor
-def get_av_zones():
- '''
- Return the availability zone each host belongs to
- '''
- nova_client = os_utils.get_nova_client()
- hosts = os_utils.get_hypervisors(nova_client)
- return ['nova::{0}'.format(host) for host in hosts]
+from snaps.config.network import NetworkConfig, SubnetConfig, PortConfig
+from snaps.openstack.create_network import OpenStackNetwork
+from snaps.config.router import RouterConfig
+from snaps.openstack.create_router import OpenStackRouter
-def get_compute_client():
- '''
- Return the compute where the client sits
- '''
- nova_client = os_utils.get_nova_client()
- hosts = os_utils.get_hypervisors(nova_client)
- for compute in hosts:
- vms = nova_client.servers.list(search_opts={'host': compute})
- for vm in vms:
- if "client" in vm.name:
- return compute
- return False
-
-
-def setup_neutron(neutron_client, net, subnet, router, subnet_cidr):
- n_dict = os_utils.create_network_full(neutron_client,
- net,
- subnet,
- router,
- subnet_cidr)
- if not n_dict:
- logger.error("failed to create neutron network")
- return False
-
- return n_dict["net_id"]
-
-
-def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
- port_range_min=None, port_range_max=None):
- # We create a security group in 2 steps
- # 1 - we check the format and set the json body accordingly
- # 2 - we call neturon client to create the security group
-
- # Format check
- json_body = {'security_group_rule': {'direction': direction,
- 'security_group_id': sg_id,
- 'protocol': protocol}}
- # parameters may be
- # - both None => we do nothing
- # - both Not None => we add them to the json description
- # but one cannot be None is the other is not None
- if (port_range_min is not None and port_range_max is not None):
- # add port_range in json description
- json_body['security_group_rule']['port_range_min'] = port_range_min
- json_body['security_group_rule']['port_range_max'] = port_range_max
- logger.debug("Security_group format set (port range included)")
- else:
- # either both port range are set to None => do nothing
- # or one is set but not the other => log it and return False
- if port_range_min is None and port_range_max is None:
- logger.debug("Security_group format set (no port range mentioned)")
- else:
- logger.error("Bad security group format."
- "One of the port range is not properly set:"
- "range min: {},"
- "range max: {}".format(port_range_min,
- port_range_max))
- return False
-
- # Create security group using neutron client
- try:
- neutron_client.create_security_group_rule(json_body)
- return True
- except:
- return False
-
-
-def setup_ingress_egress_secgroup(neutron_client, protocol,
- min_port=None, max_port=None):
- secgroups = os_utils.get_security_groups(neutron_client)
- for sg in secgroups:
- # TODO: the version of the create_secgroup_rule function in
- # functest swallows the exception thrown when a secgroup rule
- # already exists and prints a ton of noise in the test output.
- # Instead of making changes in functest code this late in the
- # release cycle, we keep our own version without the exception
- # logging. We must find a way to properly cleanup sec group
- # rules using "functest openstack clean" or pretty printing the
- # specific exception in the next release
- create_secgroup_rule(neutron_client, sg['id'],
- 'ingress', protocol,
- port_range_min=min_port,
- port_range_max=max_port)
- create_secgroup_rule(neutron_client, sg['id'],
- 'egress', protocol,
- port_range_min=min_port,
- port_range_max=max_port)
-
-
-def create_security_groups(neutron_client, secgroup_name, secgroup_descr):
- sg_id = os_utils.create_security_group_full(neutron_client,
- secgroup_name, secgroup_descr)
- setup_ingress_egress_secgroup(neutron_client, "icmp")
- setup_ingress_egress_secgroup(neutron_client, "tcp", 22, 22)
- setup_ingress_egress_secgroup(neutron_client, "tcp", 80, 80)
- setup_ingress_egress_secgroup(neutron_client, "udp", 67, 68)
- return sg_id
-
-
-def create_instance(nova_client, name, flavor, image_id, network_id, sg_id,
- secgroup_name=None, fixed_ip=None,
- av_zone='', userdata=None, files=None):
- logger.info("Creating instance '%s'..." % name)
- logger.debug(
- "Configuration:\n name=%s \n flavor=%s \n image=%s \n"
- " network=%s\n secgroup=%s \n hypervisor=%s \n"
- " fixed_ip=%s\n files=%s\n userdata=\n%s\n"
- % (name, flavor, image_id, network_id, sg_id,
- av_zone, fixed_ip, files, userdata))
- instance = os_utils.create_instance_and_wait_for_active(
- flavor,
- image_id,
- network_id,
- name,
- config_drive=True,
- userdata=userdata,
- av_zone=av_zone,
- fixed_ip=fixed_ip,
- files=files)
-
- if instance is None:
- logger.error("Error while booting instance.")
- return None
+from snaps.config.security_group import (
+ Protocol, SecurityGroupRuleConfig, Direction, SecurityGroupConfig)
- if secgroup_name:
- logger.debug("Adding '%s' to security group '%s'..."
- % (name, secgroup_name))
- else:
- logger.debug("Adding '%s' to security group '%s'..."
- % (name, sg_id))
- os_utils.add_secgroup_to_instance(nova_client, instance.id, sg_id)
+from snaps.openstack.create_security_group import OpenStackSecurityGroup
- return instance
+import snaps.openstack.create_instance as cr_inst
+from snaps.config.vm_inst import VmInstanceConfig, FloatingIpConfig
+from snaps.openstack.utils import (
+ nova_utils, neutron_utils, glance_utils, heat_utils, keystone_utils)
-def assign_floating_ip(nova_client, neutron_client, instance_id):
- instance = nova_client.servers.get(instance_id)
- floating_ip = os_utils.create_floating_ip(neutron_client)['fip_addr']
- instance.add_floating_ip(floating_ip)
- logger.info("Assigned floating ip [%s] to instance [%s]"
- % (floating_ip, instance.name))
+logger = logging.getLogger(__name__)
+DEFAULT_TACKER_API_VERSION = '1.0'
- return floating_ip
+class OpenStackSFC:
-def get_nova_id(tacker_client, resource, vnf_id=None, vnf_name=None):
- vnf = get_vnf(tacker_client, vnf_id, vnf_name)
- try:
- if vnf is None:
- raise Exception("VNF not found")
- heat = os_utils.get_heat_client()
- resource = heat.resources.get(vnf['instance_id'], resource)
- return resource.attributes['id']
- except:
- logger.error("Cannot get nova ID for VNF (id='%s', name='%s')"
- % (vnf_id, vnf_name))
- return None
+ def __init__(self):
+ self.os_creds = openstack_tests.get_credentials(
+ os_env_file=CONST.__getattribute__('openstack_creds'))
+ self.creators = []
+ self.nova = nova_utils.nova_client(self.os_creds)
+ self.neutron = neutron_utils.neutron_client(self.os_creds)
+ self.glance = glance_utils.glance_client(self.os_creds)
+ self.heat = heat_utils.heat_client(self.os_creds)
+ def register_glance_image(self, name, url, img_format, public):
+ image_settings = ImageConfig(name=name, img_format=img_format, url=url,
+ public=public, image_user='admin')
-def get_neutron_interfaces(vm):
- '''
- Get the interfaces of an instance
- '''
- nova_client = os_utils.get_nova_client()
- interfaces = nova_client.servers.interface_list(vm.id)
- return interfaces
+ # TODO Remove this when tacker is part of SNAPS
+ self.image_settings = image_settings
+ image_creator = OpenStackImage(self.os_creds, image_settings)
+ image_creator.create()
-def get_client_port_id(vm):
- '''
- Get the neutron port id of the client
- '''
- interfaces = get_neutron_interfaces(vm)
- if len(interfaces) > 1:
- raise Exception("Client has more than one interface. Not expected!")
- return interfaces[0].id
+ self.creators.append(image_creator)
+ return image_creator
+
+ def create_flavor(self, name, ram, disk, vcpus):
+ flavor_settings = FlavorConfig(name=name, ram=ram, disk=disk,
+ vcpus=vcpus)
+ flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
+ flavor = flavor_creator.create()
+
+ self.creators.append(flavor_creator)
+ return flavor
+
+ def create_network_infrastructure(self, net_name, subnet_name, subnet_cidr,
+ router_name):
+ # Network and subnet
+ subnet_settings = SubnetConfig(name=subnet_name, cidr=subnet_cidr)
+ network_settings = NetworkConfig(name=net_name,
+ subnet_settings=[subnet_settings])
+ network_creator = OpenStackNetwork(self.os_creds, network_settings)
+ network = network_creator.create()
+
+ self.creators.append(network_creator)
+
+ # Router
+ ext_network_name = CONST.__getattribute__('EXTERNAL_NETWORK')
+
+ router_settings = RouterConfig(name=router_name,
+ external_gateway=ext_network_name,
+ internal_subnets=[subnet_name])
+
+ router_creator = OpenStackRouter(self.os_creds, router_settings)
+ router = router_creator.create()
+
+ self.creators.append(router_creator)
+
+ return network, router
+
+ def create_security_group(self, sec_grp_name):
+ rule_ping = SecurityGroupRuleConfig(sec_grp_name=sec_grp_name,
+ direction=Direction.ingress,
+ protocol=Protocol.icmp)
+
+ rule_ssh = SecurityGroupRuleConfig(sec_grp_name=sec_grp_name,
+ direction=Direction.ingress,
+ protocol=Protocol.tcp,
+ port_range_min=22,
+ port_range_max=22)
+
+ rule_http = SecurityGroupRuleConfig(sec_grp_name=sec_grp_name,
+ direction=Direction.ingress,
+ protocol=Protocol.tcp,
+ port_range_min=80,
+ port_range_max=80)
+
+ rules = [rule_ping, rule_ssh, rule_http]
+
+ secgroup_settings = SecurityGroupConfig(name=sec_grp_name,
+ rule_settings=rules)
+
+ sec_group_creator = OpenStackSecurityGroup(self.os_creds,
+ secgroup_settings)
+ sec_group = sec_group_creator.create()
+
+ self.creators.append(sec_group_creator)
+
+ return sec_group
+
+ def create_instance(self, vm_name, flavor_name, image_creator, network,
+ secgrp, av_zone):
+
+ port_settings = PortConfig(name=vm_name + '-port',
+ network_name=network.name)
+
+ instance_settings = VmInstanceConfig(
+ name=vm_name, flavor=flavor_name,
+ security_group_names=str(secgrp.name),
+ port_settings=[port_settings],
+ availability_zone=av_zone)
+
+ instance_creator = cr_inst.OpenStackVmInstance(
+ self.os_creds,
+ instance_settings,
+ image_creator.image_settings)
+
+ instance = instance_creator.create()
+
+ self.creators.append(instance_creator)
+ return instance, instance_creator
+
+ def get_av_zones(self):
+ '''
+ Return the availability zone each host belongs to
+ '''
+ hosts = nova_utils.get_hypervisor_hosts(self.nova)
+ return ['nova::{0}'.format(host) for host in hosts]
+
+ def get_compute_client(self):
+ '''
+ Return the compute where the client sits
+ '''
+ compute = nova_utils.get_server(self.nova, server_name='client')
+ return compute
+
+ def assign_floating_ip(self, router, vm, vm_creator):
+ '''
+ Assign a floating ips to all the VMs
+ '''
+ name = vm.name + "-float"
+ port_name = vm.ports[0].name
+ float_ip = FloatingIpConfig(name=name,
+ port_name=port_name,
+ router_name=router.name)
+ ip = vm_creator.add_floating_ip(float_ip)
+
+ return ip.ip
+
+ # We need this function because tacker VMs cannot be created through SNAPs
+ def assign_floating_ip_vnfs(self, router):
+ '''
+ Assign a floating ips to all the SFs
+ '''
+ stacks = self.heat.stacks.list()
+ fips = []
+ for stack in stacks:
+ servers = heat_utils.get_stack_servers(self.heat,
+ self.nova,
+ self.neutron,
+ stack)
+ sf_creator = cr_inst.generate_creator(self.os_creds,
+ servers[0],
+ self.image_settings)
+ port_name = servers[0].ports[0].name
+ name = servers[0].name + "-float"
+ float_ip = FloatingIpConfig(name=name,
+ port_name=port_name,
+ router_name=router.name)
+ ip = sf_creator.add_floating_ip(float_ip)
+ fips.append(ip.ip)
+
+ return fips
+
+ def get_client_port_id(self, vm):
+ '''
+ Get the neutron port id of the client
+ '''
+ port_id = neutron_utils.get_port(self.neutron,
+ port_name=vm.name + "-port")
+ return port_id
# TACKER SECTION #
@@ -210,7 +217,11 @@ def get_tacker_client_version():
def get_tacker_client(other_creds={}):
- sess = os_utils.get_session(other_creds)
+ creds_override = None
+ os_creds = openstack_tests.get_credentials(
+ os_env_file=CONST.__getattribute__('openstack_creds'),
+ overrides=creds_override)
+ sess = keystone_utils.keystone_session(os_creds)
return tackerclient.Client(get_tacker_client_version(), session=sess)