def test_create_loadbalancer(self): """Create load balancer.""" # Prepare payload instances # First we allow communication to port 80 by adding a security group # rule project_id = openstack_utils.get_project_id(self.keystone_client, 'admin', domain_name='admin_domain') openstack_utils.add_neutron_secgroup_rules(self.neutron_client, project_id, [{ 'protocol': 'tcp', 'port_range_min': '80', 'port_range_max': '80', 'direction': 'ingress' }]) # Then we request two Ubuntu instances with the Apache web server # installed instance_1, instance_2 = self.launch_guests( userdata='#cloud-config\npackages:\n - apache2\n') # Get IP of the prepared payload instances payload_ips = [] for server in (instance_1, instance_2): payload_ips.append(server.networks['private'][0]) self.assertTrue(len(payload_ips) > 0) resp = self.neutron_client.list_networks(name='private') subnet_id = resp['networks'][0]['subnets'][0] if openstack_utils.dvr_enabled(): resp = self.neutron_client.list_networks( name='private_lb_fip_network') vip_subnet_id = resp['networks'][0]['subnets'][0] else: vip_subnet_id = subnet_id for provider in self.get_lb_providers(self.octavia_client).keys(): logging.info( 'Creating loadbalancer with provider {}'.format(provider)) lb = self._create_lb_resources(self.octavia_client, provider, vip_subnet_id, subnet_id, payload_ips) self.loadbalancers.append(lb) lb_fp = openstack_utils.create_floating_ip( self.neutron_client, 'ext_net', port={'id': lb['vip_port_id']}) snippet = 'This is the default welcome page' assert snippet in self._get_payload(lb_fp['floating_ip_address']) logging.info('Found "{}" in page retrieved through load balancer ' ' (provider="{}") at "http://{}/"'.format( snippet, provider, lb_fp['floating_ip_address'])) # If we get here, it means the tests passed self.run_resource_cleanup = True
def test_create_floating_ip(self): self.patch_object(openstack_utils, "get_net_uuid") self.get_net_uuid.return_value = self.net_uuid # Already exists floatingip = openstack_utils.create_floating_ip(self.neutronclient, self.ext_net, port=self.port["port"]) self.assertEqual(floatingip, self.floatingip["floatingip"]) self.neutronclient.create_floatingip.assert_not_called() # Does not yet exist self.neutronclient.list_floatingips.return_value = {"floatingips": []} self.floatingip["floatingip"].pop("id") floatingip = openstack_utils.create_floating_ip(self.neutronclient, self.private_net, port=self.port["port"]) self.assertEqual(floatingip, self.floatingip["floatingip"]) self.neutronclient.create_floatingip.assert_called_once_with( self.floatingip)
def test_create_loadbalancer(self): """Create load balancer.""" nova_client = openstack_utils.get_nova_session_client( self.keystone_session) # Get IP of the prepared payload instances payload_ips = [] for server in nova_client.servers.list(): payload_ips.append(server.networks['private'][0]) self.assertTrue(len(payload_ips) > 0) resp = self.neutron_client.list_networks(name='private') subnet_id = resp['networks'][0]['subnets'][0] if openstack_utils.dvr_enabled(): resp = self.neutron_client.list_networks( name='private_lb_fip_network') vip_subnet_id = resp['networks'][0]['subnets'][0] else: vip_subnet_id = subnet_id for provider in self.get_lb_providers(self.octavia_client).keys(): logging.info( 'Creating loadbalancer with provider {}'.format(provider)) lb = self._create_lb_resources(self.octavia_client, provider, vip_subnet_id, subnet_id, payload_ips) self.loadbalancers.append(lb) lb_fp = openstack_utils.create_floating_ip( self.neutron_client, 'ext_net', port={'id': lb['vip_port_id']}) snippet = 'This is the default welcome page' assert snippet in self._get_payload(lb_fp['floating_ip_address']) logging.info('Found "{}" in page retrieved through load balancer ' ' (provider="{}") at "http://{}/"'.format( snippet, provider, lb_fp['floating_ip_address'])) # If we get here, it means the tests passed self.run_tearDown = True
def test_create_loadbalancer(self): """Create load balancer.""" keystone_session = openstack_utils.get_overcloud_keystone_session() neutron_client = openstack_utils.get_neutron_session_client( keystone_session) nova_client = openstack_utils.get_nova_session_client(keystone_session) # Get IP of the prepared payload instances payload_ips = [] for server in nova_client.servers.list(): payload_ips.append(server.networks['private'][0]) self.assertTrue(len(payload_ips) > 0) resp = neutron_client.list_networks(name='private') subnet_id = resp['networks'][0]['subnets'][0] if openstack_utils.dvr_enabled(): resp = neutron_client.list_networks(name='private_lb_fip_network') vip_subnet_id = resp['networks'][0]['subnets'][0] else: vip_subnet_id = subnet_id octavia_client = openstack_utils.get_octavia_session_client( keystone_session) result = octavia_client.load_balancer_create( json={ 'loadbalancer': { 'description': 'Created by Zaza', 'admin_state_up': True, 'vip_subnet_id': vip_subnet_id, 'name': 'zaza-lb-0', } }) lb_id = result['loadbalancer']['id'] lb_vip_port_id = result['loadbalancer']['vip_port_id'] @tenacity.retry(wait=tenacity.wait_fixed(1), reraise=True, stop=tenacity.stop_after_delay(900)) def wait_for_lb_resource(octavia_show_func, resource_id, operating_status=None): resp = octavia_show_func(resource_id) logging.info(resp['provisioning_status']) assert resp['provisioning_status'] == 'ACTIVE', ( 'load balancer resource has not reached ' 'expected provisioning status: {}'.format(resp)) if operating_status: logging.info(resp['operating_status']) assert resp['operating_status'] == operating_status, ( 'load balancer resource has not reached ' 'expected operating status: {}'.format(resp)) return resp logging.info('Awaiting loadbalancer to reach provisioning_status ' '"ACTIVE"') resp = wait_for_lb_resource(octavia_client.load_balancer_show, lb_id) logging.info(resp) result = octavia_client.listener_create( json={ 'listener': { 'loadbalancer_id': lb_id, 'name': 'listener1', 'protocol': 'HTTP', 'protocol_port': 80 }, }) listener_id = result['listener']['id'] logging.info('Awaiting listener to reach provisioning_status ' '"ACTIVE"') resp = wait_for_lb_resource(octavia_client.listener_show, listener_id) logging.info(resp) result = octavia_client.pool_create( json={ 'pool': { 'listener_id': listener_id, 'name': 'pool1', 'lb_algorithm': 'ROUND_ROBIN', 'protocol': 'HTTP', }, }) pool_id = result['pool']['id'] logging.info('Awaiting pool to reach provisioning_status ' '"ACTIVE"') resp = wait_for_lb_resource(octavia_client.pool_show, pool_id) logging.info(resp) result = octavia_client.health_monitor_create( json={ 'healthmonitor': { 'pool_id': pool_id, 'delay': 5, 'max_retries': 4, 'timeout': 10, 'type': 'HTTP', 'url_path': '/', }, }) healthmonitor_id = result['healthmonitor']['id'] logging.info('Awaiting healthmonitor to reach provisioning_status ' '"ACTIVE"') resp = wait_for_lb_resource(octavia_client.health_monitor_show, healthmonitor_id) logging.info(resp) for ip in payload_ips: result = octavia_client.member_create(pool_id=pool_id, json={ 'member': { 'subnet_id': subnet_id, 'address': ip, 'protocol_port': 80, }, }) member_id = result['member']['id'] logging.info('Awaiting member to reach provisioning_status ' '"ACTIVE"') resp = wait_for_lb_resource(lambda x: octavia_client.member_show( pool_id=pool_id, member_id=x), member_id, operating_status='ONLINE') logging.info(resp) lb_fp = openstack_utils.create_floating_ip(neutron_client, 'ext_net', port={'id': lb_vip_port_id}) @tenacity.retry(wait=tenacity.wait_fixed(1), reraise=True, stop=tenacity.stop_after_delay(900)) def get_payload(): return subprocess.check_output([ 'wget', '-O', '-', 'http://{}/'.format( lb_fp['floating_ip_address']) ], universal_newlines=True) snippet = 'This is the default welcome page' assert snippet in get_payload() logging.info('Found "{}" in page retrieved through load balancer at ' '"http://{}/"'.format(snippet, lb_fp['floating_ip_address']))
def launch_instance(instance_key, use_boot_volume=False, vm_name=None, private_network_name=None, image_name=None, flavor_name=None, external_network_name=None, meta=None, userdata=None): """Launch an instance. :param instance_key: Key to collect associated config data with. :type instance_key: str :param use_boot_volume: Whether to boot guest from a shared volume. :type use_boot_volume: boolean :param vm_name: Name to give guest. :type vm_name: str :param private_network_name: Name of private network to attach guest to. :type private_network_name: str :param image_name: Image name to use with guest. :type image_name: str :param flavor_name: Flavor name to use with guest. :type flavor_name: str :param external_network_name: External network to create floating ip from for guest. :type external_network_name: str :param meta: A dict of arbitrary key/value metadata to store for this server. Both keys and values must be <=255 characters. :type meta: dict :param userdata: Configuration to use upon launch, used by cloud-init. :type userdata: str :returns: the created instance :rtype: novaclient.Server """ keystone_session = openstack_utils.get_overcloud_keystone_session() nova_client = openstack_utils.get_nova_session_client(keystone_session) neutron_client = openstack_utils.get_neutron_session_client( keystone_session) # Collect resource information. vm_name = vm_name or time.strftime("%Y%m%d%H%M%S") image_name = image_name or boot_tests[instance_key]['image_name'] image = nova_client.glance.find_image(image_name) flavor_name = flavor_name or boot_tests[instance_key]['flavor_name'] flavor = nova_client.flavors.find(name=flavor_name) private_network_name = private_network_name or "private" net = neutron_client.find_resource("network", private_network_name) nics = [{'net-id': net.get('id')}] meta = meta or {} external_network_name = external_network_name or "ext_net" if use_boot_volume: bdmv2 = [{ 'boot_index': '0', 'uuid': image.id, 'source_type': 'image', 'volume_size': flavor.disk, 'destination_type': 'volume', 'delete_on_termination': True }] image = None else: bdmv2 = None # Launch instance. logging.info('Launching instance {}'.format(vm_name)) instance = nova_client.servers.create(name=vm_name, image=image, block_device_mapping_v2=bdmv2, flavor=flavor, key_name=nova_utils.KEYPAIR_NAME, meta=meta, nics=nics, userdata=userdata) # Test Instance is ready. logging.info('Checking instance is active') openstack_utils.resource_reaches_status(nova_client.servers, instance.id, expected_status='ACTIVE', stop_after_attempt=16) logging.info('Checking cloud init is complete') openstack_utils.cloud_init_complete(nova_client, instance.id, boot_tests[instance_key]['bootstring']) port = openstack_utils.get_ports_from_device_id(neutron_client, instance.id)[0] logging.info('Assigning floating ip.') ip = openstack_utils.create_floating_ip(neutron_client, external_network_name, port=port)['floating_ip_address'] logging.info('Assigned floating IP {} to {}'.format(ip, vm_name)) try: openstack_utils.ping_response(ip) except subprocess.CalledProcessError as e: logging.error('Pinging {} failed with {}'.format(ip, e.returncode)) logging.error('stdout: {}'.format(e.stdout)) logging.error('stderr: {}'.format(e.stderr)) raise # Check ssh'ing to instance. logging.info('Testing ssh access.') openstack_utils.ssh_test(username=boot_tests[instance_key]['username'], ip=ip, vm_name=vm_name, password=boot_tests[instance_key].get('password'), privkey=openstack_utils.get_private_key( nova_utils.KEYPAIR_NAME)) return instance
def setup_bgp_speaker(peer_application_name, keystone_session=None): """Perform BGP Speaker setup. :param peer_application_name: String name of BGP peer application :type peer_application_name: string :param keystone_session: Keystone session object for overcloud :type keystone_session: keystoneauth1.session.Session object :returns: None :rtype: None """ # Get ASNs from deployment dr_relation = juju_utils.get_relation_from_unit( 'neutron-dynamic-routing', peer_application_name, 'bgpclient') peer_asn = dr_relation.get('asn') logging.debug('peer ASn: "{}"'.format(peer_asn)) peer_relation = juju_utils.get_relation_from_unit( peer_application_name, 'neutron-dynamic-routing', 'bgp-speaker') dr_asn = peer_relation.get('asn') logging.debug('our ASn: "{}"'.format(dr_asn)) # If a session has not been provided, acquire one if not keystone_session: keystone_session = openstack_utils.get_overcloud_keystone_session() # Get authenticated clients neutron_client = openstack_utils.get_neutron_session_client( keystone_session) # Create BGP speaker logging.info("Setting up BGP speaker") bgp_speaker = openstack_utils.create_bgp_speaker( neutron_client, local_as=dr_asn) # Add networks to bgp speaker logging.info("Advertising BGP routes") openstack_utils.add_network_to_bgp_speaker( neutron_client, bgp_speaker, EXT_NET) openstack_utils.add_network_to_bgp_speaker( neutron_client, bgp_speaker, PRIVATE_NET) logging.debug("Advertised routes: {}" .format( neutron_client.list_route_advertised_from_bgp_speaker( bgp_speaker["id"]))) # Create peer logging.info("Setting up BGP peer") bgp_peer = openstack_utils.create_bgp_peer(neutron_client, peer_application_name, remote_as=peer_asn) # Add peer to bgp speaker logging.info("Adding BGP peer to BGP speaker") openstack_utils.add_peer_to_bgp_speaker( neutron_client, bgp_speaker, bgp_peer) # Create Floating IP to advertise logging.info("Creating floating IP to advertise") port = openstack_utils.create_port(neutron_client, FIP_TEST, PRIVATE_NET) floating_ip = openstack_utils.create_floating_ip(neutron_client, EXT_NET, port=port) logging.info( "Advertised floating IP: {}".format( floating_ip["floating_ip_address"])) # NOTE(fnordahl): As a workaround for LP: #1784083 remove BGP speaker from # dragent and add it back. logging.info( "Waiting for Neutron agent 'neutron-bgp-dragent' to appear...") keystone_session = openstack_utils.get_overcloud_keystone_session() neutron_client = openstack_utils.get_neutron_session_client( keystone_session) agents = openstack_utils.neutron_agent_appears(neutron_client, 'neutron-bgp-dragent') agent_id = None for agent in agents.get('agents', []): agent_id = agent.get('id', None) if agent_id is not None: break logging.info( 'Waiting for BGP speaker to appear on agent "{}"...'.format(agent_id)) bgp_speakers = openstack_utils.neutron_bgp_speaker_appears_on_agent( neutron_client, agent_id) logging.info( "Removing and adding back bgp-speakers to agent (LP: #1784083)...") while True: try: for bgp_speaker in bgp_speakers.get('bgp_speakers', []): bgp_speaker_id = bgp_speaker.get('id', None) logging.info('removing "{}" from "{}"' ''.format(bgp_speaker_id, agent_id)) neutron_client.remove_bgp_speaker_from_dragent( agent_id, bgp_speaker_id) except neutronclient.common.exceptions.NotFound as e: logging.info('Exception: "{}"'.format(e)) break neutron_client.add_bgp_speaker_to_dragent( agent_id, {'bgp_speaker_id': bgp_speaker_id})
def setup_bgp_speaker(peer_application_name, keystone_session=None): """Perform BGP Speaker setup. :param peer_application_name: String name of BGP peer application :type peer_application_name: string :param keystone_session: Keystone session object for overcloud :type keystone_session: keystoneauth1.session.Session object :returns: None :rtype: None """ # Get ASNs from deployment dr_relation = juju_utils.get_relation_from_unit('neutron-dynamic-routing', peer_application_name, 'bgpclient') peer_asn = dr_relation.get('asn') logging.debug('peer ASn: "{}"'.format(peer_asn)) peer_relation = juju_utils.get_relation_from_unit( peer_application_name, 'neutron-dynamic-routing', 'bgp-speaker') dr_asn = peer_relation.get('asn') logging.debug('our ASn: "{}"'.format(dr_asn)) # If a session has not been provided, acquire one if not keystone_session: keystone_session = openstack_utils.get_overcloud_keystone_session() # Get authenticated clients neutron_client = openstack_utils.get_neutron_session_client( keystone_session) # Create BGP speaker logging.info("Setting up BGP speaker") bgp_speaker = openstack_utils.create_bgp_speaker(neutron_client, local_as=dr_asn) # Add networks to bgp speaker logging.info("Advertising BGP routes") openstack_utils.add_network_to_bgp_speaker(neutron_client, bgp_speaker, EXT_NET) openstack_utils.add_network_to_bgp_speaker(neutron_client, bgp_speaker, PRIVATE_NET) logging.debug("Advertised routes: {}".format( neutron_client.list_route_advertised_from_bgp_speaker( bgp_speaker["id"]))) # Create peer logging.info("Setting up BGP peer") bgp_peer = openstack_utils.create_bgp_peer(neutron_client, peer_application_name, remote_as=peer_asn) # Add peer to bgp speaker logging.info("Adding BGP peer to BGP speaker") openstack_utils.add_peer_to_bgp_speaker(neutron_client, bgp_speaker, bgp_peer) # Create Floating IP to advertise logging.info("Creating floating IP to advertise") port = openstack_utils.create_port(neutron_client, FIP_TEST, PRIVATE_NET) floating_ip = openstack_utils.create_floating_ip(neutron_client, EXT_NET, port=port) logging.info("Advertised floating IP: {}".format( floating_ip["floating_ip_address"]))