def validate_instance_can_reach_router(self, instance, verify): """ Validate that an instance can reach it's primary gateway. We make the assumption that the router's IP is 192.168.0.1 as that's the network that is setup in neutron.setup.basic_overcloud_network which is used in all Zaza Neutron validations. :param instance: The instance to check networking from :type instance: nova_client.Server """ address = floating_ips_from_instance(instance)[0] username = guest.boot_tests['bionic']['username'] password = guest.boot_tests['bionic'].get('password') privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) openstack_utils.ssh_command(username, address, 'instance', 'ping -c 1 192.168.0.1', password=password, privkey=privkey, verify=verify) pass
def validate_instance_can_reach_other(self, instance_1, instance_2, verify): """ Validate that an instance can reach a fixed and floating of another. :param instance_1: The instance to check networking from :type instance_1: nova_client.Server :param instance_2: The instance to check networking from :type instance_2: nova_client.Server """ floating_1 = floating_ips_from_instance(instance_1)[0] floating_2 = floating_ips_from_instance(instance_2)[0] address_2 = fixed_ips_from_instance(instance_2)[0] username = guest.boot_tests['bionic']['username'] password = guest.boot_tests['bionic'].get('password') privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) openstack_utils.ssh_command( username, floating_1, 'instance-1', 'ping -c 1 {}'.format(address_2), password=password, privkey=privkey, verify=verify) openstack_utils.ssh_command( username, floating_1, 'instance-1', 'ping -c 1 {}'.format(floating_2), password=password, privkey=privkey, verify=verify)
def _check_tpm_device(self, instance, *devices): """Check that the instance has TPM devices available. :param instance: the instance to determine if TPM devices are available :type instance: nova_client.Server instance :param devices: the devices to look for that are present in the guest :type devices: list of strings :return: True if the instance has TPM devices, False otherwise :rtype: bool """ fip = neutron_tests.floating_ips_from_instance(instance)[0] username = guest.boot_tests['focal']['username'] password = guest.boot_tests['focal'].get('password') privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) def check_tpm(stdin, stdout, stderr): devs = [line.strip() for line in stdout.readlines()] for expected in devices: self.assertIn(expected, devs) logging.info('Validating TPM devices are present') openstack_utils.ssh_command(username, ip=fip, vm_name=instance.name, command='sudo ls -1 /dev/tpm*', password=password, privkey=privkey, verify=check_tpm)
def test_manila_share(self): """Test that a Manila share can be accessed on two instances. 1. Create a share 2. Spawn two servers 3. Mount it on both 4. Write a file on one 5. Read it on the other 6. Profit """ # Create a share share = self.manila_client.shares.create( share_type=self.share_type_name, name=self.share_name, share_proto=self.share_protocol, share_network=self.share_network, size=1) # Spawn Servers instance_1 = self.launch_guest( guest_name='ins-1', userdata=self.INSTANCE_USERDATA, instance_key=self.INSTANCE_KEY) instance_2 = self.launch_guest( guest_name='ins-2', userdata=self.INSTANCE_USERDATA, instance_key=self.INSTANCE_KEY) fip_1 = neutron_tests.floating_ips_from_instance(instance_1)[0] fip_2 = neutron_tests.floating_ips_from_instance(instance_2)[0] # Wait for the created share to become available before it gets used. openstack_utils.resource_reaches_status( self.manila_client.shares, share.id, wait_iteration_max_time=120, stop_after_attempt=2, expected_status="available", msg="Waiting for a share to become available") # Grant access to the Manila share for both Nova instances. share.allow(access_type='ip', access=fip_1, access_level='rw') share.allow(access_type='ip', access=fip_2, access_level='rw') ssh_user_name = guest.boot_tests[self.INSTANCE_KEY]['username'] privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) share_path = share.export_locations[0] # Write a testing file on instance #1 self._mount_share_on_instance( fip_1, ssh_user_name, privkey, share_path) self._write_testing_file_on_instance( fip_1, ssh_user_name, privkey) # Validate the testing file from instance #2 self._mount_share_on_instance( fip_2, ssh_user_name, privkey, share_path) self._validate_testing_file_from_instance( fip_2, ssh_user_name, privkey)
def test_get_private_key(self): self.patch_object(openstack_utils.os.path, "isfile", return_value=True) m = mock.mock_open(read_data='myprivkey') with mock.patch('zaza.openstack.utilities.openstack.open', m, create=True): self.assertEqual(openstack_utils.get_private_key('mykeys'), 'myprivkey')
def test_cephfs_share(self): """Test that CephFS shares can be accessed on two instances. 1. Spawn two servers 2. mount it on both 3. write a file on one 4. read it on the other 5. profit """ keyring = model.run_on_leader( 'ceph-mon', 'cat /etc/ceph/ceph.client.admin.keyring')['Stdout'] conf = model.run_on_leader('ceph-mon', 'cat /etc/ceph/ceph.conf')['Stdout'] # Spawn Servers instance_1, instance_2 = self.launch_guests( userdata=self.INSTANCE_USERDATA.format(_indent(conf, 8), _indent(keyring, 8))) # Write a file on instance_1 def verify_setup(stdin, stdout, stderr): status = stdout.channel.recv_exit_status() self.assertEqual(status, 0) fip_1 = neutron_tests.floating_ips_from_instance(instance_1)[0] fip_2 = neutron_tests.floating_ips_from_instance(instance_2)[0] username = guest.boot_tests['bionic']['username'] password = guest.boot_tests['bionic'].get('password') privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) for attempt in Retrying(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10)): with attempt: openstack_utils.ssh_command( username, fip_1, 'instance-1', 'sudo mount -a && ' 'echo "test" | sudo tee /mnt/cephfs/test', password=password, privkey=privkey, verify=verify_setup) def verify(stdin, stdout, stderr): status = stdout.channel.recv_exit_status() self.assertEqual(status, 0) out = "" for line in iter(stdout.readline, ""): out += line self.assertEqual(out, "test\n") openstack_utils.ssh_command(username, fip_2, 'instance-2', 'sudo mount -a && ' 'sudo cat /mnt/cephfs/test', password=password, privkey=privkey, verify=verify)
def validate_instance_can_reach_other(self, instance_1, instance_2, verify, mtu=None): """ Validate that an instance can reach a fixed and floating of another. :param instance_1: The instance to check networking from :type instance_1: nova_client.Server :param instance_2: The instance to check networking from :type instance_2: nova_client.Server :param verify: callback to verify result :type verify: callable :param mtu: Check that we can send non-fragmented packets of given size :type mtu: Optional[int] """ floating_1 = floating_ips_from_instance(instance_1)[0] floating_2 = floating_ips_from_instance(instance_2)[0] address_2 = fixed_ips_from_instance(instance_2)[0] username = guest.boot_tests['bionic']['username'] password = guest.boot_tests['bionic'].get('password') privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) cmds = [ 'ping -c 1', ] if mtu: # the on-wire packet will be 28 bytes larger than the value # provided to ping(8) -s parameter packetsize = mtu - 28 cmds.append('ping -M do -s {} -c 1'.format(packetsize)) for cmd in cmds: openstack_utils.ssh_command(username, floating_1, 'instance-1', '{} {}'.format(cmd, address_2), password=password, privkey=privkey, verify=verify) openstack_utils.ssh_command(username, floating_1, 'instance-1', '{} {}'.format(cmd, floating_2), password=password, privkey=privkey, verify=verify)
def validate_instance_can_reach_router(self, instance, verify, mtu=None): """ Validate that an instance can reach it's primary gateway. We make the assumption that the router's IP is 192.168.0.1 as that's the network that is setup in neutron.setup.basic_overcloud_network which is used in all Zaza Neutron validations. :param instance: The instance to check networking from :type instance: nova_client.Server :param verify: callback to verify result :type verify: callable :param mtu: Check that we can send non-fragmented packets of given size :type mtu: Optional[int] """ address = floating_ips_from_instance(instance)[0] username = guest.boot_tests['bionic']['username'] password = guest.boot_tests['bionic'].get('password') privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) cmds = [ 'ping -c 1', ] if mtu: # the on-wire packet will be 28 bytes larger than the value # provided to ping(8) -s parameter packetsize = mtu - 28 cmds.append('ping -M do -s {} -c 1'.format(packetsize)) for cmd in cmds: openstack_utils.ssh_command(username, address, 'instance', '{} 192.168.0.1'.format(cmd), password=password, privkey=privkey, verify=verify)
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 test_get_private_key_file_missing(self): self.patch_object(openstack_utils.os.path, "isfile", return_value=False) self.assertIsNone(openstack_utils.get_private_key('mykeys'))
def test_manila_share(self): """Test that Manila + Ganesha shares can be accessed on two instances. 1. create a share 2. Spawn two servers 3. mount it on both 4. write a file on one 5. read it on the other 6. profit """ # Create a share share = self.manila_client.shares.create( share_type='cephfsnfstype', name='cephnfsshare1', share_proto="nfs", size=1) # Spawn Servers instance_1 = guest.launch_instance( glance_setup.LTS_IMAGE_NAME, vm_name='{}-ins-1'.format(self.RESOURCE_PREFIX), userdata=self.INSTANCE_USERDATA) instance_2 = guest.launch_instance( glance_setup.LTS_IMAGE_NAME, vm_name='{}-ins-2'.format(self.RESOURCE_PREFIX), userdata=self.INSTANCE_USERDATA) fip_1 = neutron_tests.floating_ips_from_instance(instance_1)[0] fip_2 = neutron_tests.floating_ips_from_instance(instance_2)[0] # Wait for the created share to become available before it gets used. openstack_utils.resource_reaches_status( self.manila_client.shares, share.id, wait_iteration_max_time=120, stop_after_attempt=2, expected_status="available", msg="Waiting for a share to become available") share.allow(access_type='ip', access=fip_1, access_level='rw') share.allow(access_type='ip', access=fip_2, access_level='rw') # Mount Share username = guest.boot_tests['bionic']['username'] password = guest.boot_tests['bionic'].get('password') privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) # Write a file on instance_1 def verify_setup(stdin, stdout, stderr): status = stdout.channel.recv_exit_status() self.assertEqual(status, 0) mount_path = share.export_locations[0] for attempt in Retrying( stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10)): with attempt: openstack_utils.ssh_command( username, fip_1, 'instance-1', 'sudo mkdir -p /mnt/ceph && ' 'sudo mount -t nfs -o nfsvers=4.1,proto=tcp ' '{} /mnt/ceph && ' 'echo "test" | sudo tee /mnt/ceph/test'.format( mount_path), password=password, privkey=privkey, verify=verify_setup) for attempt in Retrying( stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10)): with attempt: # Setup that file on instance_2 openstack_utils.ssh_command( username, fip_2, 'instance-2', 'sudo mkdir -p /mnt/ceph && ' 'sudo /bin/mount -t nfs -o nfsvers=4.1,proto=tcp ' '{} /mnt/ceph' .format(mount_path), password=password, privkey=privkey, verify=verify_setup) def verify(stdin, stdout, stderr): status = stdout.channel.recv_exit_status() self.assertEqual(status, 0) out = "" for line in iter(stdout.readline, ""): out += line self.assertEqual(out, "test\n") openstack_utils.ssh_command( username, fip_2, 'instance-2', 'sudo cat /mnt/ceph/test', password=password, privkey=privkey, verify=verify)
def test_manila_share(self): """Test that Manila + Ganesha shares can be accessed on two instances. 1. create a share 2. Spawn two servers 3. mount it on both 4. write a file on one 5. read it on the other 6. profit """ # Create Share share = self.manila_client.shares.create(share_type='cephfsnfstype', name='cephnfsshare1', share_proto="nfs", size=1) # Spawn Servers guest.launch_instance(glance_setup.LTS_IMAGE_NAME, vm_name='{}-ins-1'.format(self.RESOURCE_PREFIX)) guest.launch_instance(glance_setup.LTS_IMAGE_NAME, vm_name='{}-ins-2'.format(self.RESOURCE_PREFIX)) instance_1 = self.nova_client.servers.find( name='{}-ins-1'.format(self.RESOURCE_PREFIX)) fip_1 = neutron_tests.floating_ips_from_instance(instance_1)[0] instance_2 = self.nova_client.servers.find( name='{}-ins-2'.format(self.RESOURCE_PREFIX)) fip_2 = neutron_tests.floating_ips_from_instance(instance_2)[0] share.allow(access_type='ip', access=fip_1, access_level='rw') share.allow(access_type='ip', access=fip_2, access_level='rw') # Mount Share username = guest.boot_tests['bionic']['username'] password = guest.boot_tests['bionic'].get('password') privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) mount_path = share.export_locations[0] # Write a file on instance_1 def verify_setup(stdin, stdout, stderr): status = stdout.channel.recv_exit_status() self.assertEqual(status, 0) openstack_utils.ssh_command( username, fip_1, 'instance-1', 'sudo apt install -yq nfs-common && ' 'sudo mkdir -p /mnt/ceph && ' 'sudo mount -t nfs -o nfsvers=4.1,proto=tcp {} /mnt/ceph && ' 'echo "test" | sudo tee /mnt/ceph/test'.format(mount_path), password=password, privkey=privkey, verify=verify_setup) openstack_utils.ssh_command( username, fip_2, 'instance-2', 'sudo apt install -yq nfs-common && ' 'sudo /bin/mkdir -p /mnt/ceph && ' 'sudo /bin/mount -t nfs -o nfsvers=4.1,proto=tcp {} /mnt/ceph'. format(mount_path), password=password, privkey=privkey, verify=verify_setup) def verify(stdin, stdout, stderr): status = stdout.channel.recv_exit_status() out = "" print("[{}] Stdout:".format(status)) for line in iter(stdout.readline, ""): out += line self.assertEqual(out, "test\n") # Read that file on instance_2 openstack_utils.ssh_command( username, fip_2, 'instance-2', 'sudo cat /mnt/ceph/test'.format(mount_path), password=password, privkey=privkey, verify=verify)