def _get_verifier(self, context, image_id, trusted_certs): verifier = None # Use the default certs if the user didn't provide any (and there are # default certs configured). if (not trusted_certs and CONF.glance.enable_certificate_validation and CONF.glance.default_trusted_certificate_ids): trusted_certs = objects.TrustedCerts( ids=CONF.glance.default_trusted_certificate_ids) # Verify image signature if feature is enabled or trusted # certificates were provided if trusted_certs or CONF.glance.verify_glance_signatures: image_meta_dict = self.show(context, image_id, include_locations=False) image_meta = objects.ImageMeta.from_dict(image_meta_dict) img_signature = image_meta.properties.get('img_signature') img_sig_hash_method = image_meta.properties.get( 'img_signature_hash_method') img_sig_cert_uuid = image_meta.properties.get( 'img_signature_certificate_uuid') img_sig_key_type = image_meta.properties.get( 'img_signature_key_type') try: verifier = signature_utils.get_verifier( context=context, img_signature_certificate_uuid=img_sig_cert_uuid, img_signature_hash_method=img_sig_hash_method, img_signature=img_signature, img_signature_key_type=img_sig_key_type, ) except cursive_exception.SignatureVerificationError: with excutils.save_and_reraise_exception(): LOG.error( 'Image signature verification failed ' 'for image: %s', image_id) # Validate image signature certificate if trusted certificates # were provided # NOTE(jackie-truong): Certificate validation will occur if # trusted_certs are provided, even if the certificate validation # feature is disabled. This is to provide safety for the user. # We may want to consider making this a "soft" check in the future. if trusted_certs: _verify_certs(context, img_sig_cert_uuid, trusted_certs) elif CONF.glance.enable_certificate_validation: msg = ('Image signature certificate validation enabled, ' 'but no trusted certificate IDs were provided. ' 'Unable to validate the certificate used to ' 'verify the image signature.') LOG.warning(msg) raise exception.CertificateValidationFailed(msg) else: LOG.debug('Certificate validation was not performed. A list ' 'of trusted image certificate IDs must be provided ' 'in order to validate an image certificate.') return verifier
def test_fetch_image(self, mock_images): context = 'opaque context' target = '/tmp/targetfile' image_id = '4' trusted_certs = objects.TrustedCerts( ids=['0b5d2c72-12cc-4ba6-a8d7-3ff5cc1d8cb8', '674736e3-f25c-405c-8362-bbf991e0ce0a']) libvirt_utils.fetch_image(context, target, image_id, trusted_certs) mock_images.assert_called_once_with( context, image_id, target, trusted_certs)
def test_fetch_initrd_image(self, mock_images): _context = context.RequestContext(project_id=123, project_name="aubergine", user_id=456, user_name="pie") target = '/tmp/targetfile' image_id = '4' trusted_certs = objects.TrustedCerts( ids=['0b5d2c72-12cc-4ba6-a8d7-3ff5cc1d8cb8', '674736e3-f25c-405c-8362-bbf991e0ce0a']) libvirt_utils.fetch_raw_image(_context, target, image_id, trusted_certs) mock_images.assert_called_once_with( _context, image_id, target, trusted_certs)
def _create_instance_data(self): """Creates an instance record and associated data like BDMs, VIFs, migrations, etc in the source cell and returns the Instance object. The idea is to create as many things from the Instance.INSTANCE_OPTIONAL_ATTRS list as possible. :returns: The created Instance and Migration objects """ # Create the nova-compute services record first. fake_service = test_service._fake_service() fake_service.pop('version', None) # version field is immutable fake_service.pop('id', None) # cannot create with an id set service = objects.Service(self.source_context, **fake_service) service.create() # Create the compute node using the service. fake_compute_node = copy.copy(test_compute_node.fake_compute_node) fake_compute_node['host'] = service.host fake_compute_node['hypervisor_hostname'] = service.host fake_compute_node['stats'] = {} # the object requires a dict fake_compute_node['service_id'] = service.id fake_compute_node.pop('id', None) # cannot create with an id set compute_node = objects.ComputeNode(self.source_context, **fake_compute_node) compute_node.create() # Build an Instance object with basic fields set. updates = { 'metadata': { 'foo': 'bar' }, 'system_metadata': { 'roles': ['member'] }, 'host': compute_node.host, 'node': compute_node.hypervisor_hostname } inst = fake_instance.fake_instance_obj(self.source_context, **updates) delattr(inst, 'id') # cannot create an instance with an id set # Now we have to dirty all of the fields because fake_instance_obj # uses Instance._from_db_object to create the Instance object we have # but _from_db_object calls obj_reset_changes() which resets all of # the fields that were on the object, including the basic stuff like # the 'host' field, which means those fields don't get set in the DB. # TODO(mriedem): This should live in fake_instance_obj with a # make_creatable kwarg. for field in inst.obj_fields: if field in inst: setattr(inst, field, getattr(inst, field)) # Make sure at least one expected basic field is dirty on the Instance. self.assertIn('host', inst.obj_what_changed()) # Set the optional fields on the instance before creating it. inst.pci_requests = objects.InstancePCIRequests(requests=[ objects.InstancePCIRequest( **test_instance_pci_requests.fake_pci_requests[0]) ]) inst.numa_topology = objects.InstanceNUMATopology( cells=test_instance_numa.fake_obj_numa_topology.cells) inst.trusted_certs = objects.TrustedCerts(ids=[uuids.cert]) inst.vcpu_model = test_vcpu_model.fake_vcpumodel inst.keypairs = objects.KeyPairList( objects=[objects.KeyPair(**test_keypair.fake_keypair)]) inst.device_metadata = ( test_instance_device_metadata.get_fake_obj_device_metadata( self.source_context)) # FIXME(mriedem): db.instance_create does not handle tags inst.obj_reset_changes(['tags']) inst.create() bdm = { 'instance_uuid': inst.uuid, 'source_type': 'volume', 'destination_type': 'volume', 'volume_id': uuids.volume_id, 'volume_size': 1, 'device_name': '/dev/vda', } bdm = objects.BlockDeviceMapping( self.source_context, **fake_block_device.FakeDbBlockDeviceDict(bdm_dict=bdm)) delattr(bdm, 'id') # cannot create a bdm with an id set bdm.obj_reset_changes(['id']) bdm.create() vif = objects.VirtualInterface(self.source_context, address='de:ad:be:ef:ca:fe', uuid=uuids.port, instance_uuid=inst.uuid) vif.create() info_cache = objects.InstanceInfoCache().new(self.source_context, inst.uuid) info_cache.network_info = network_model.NetworkInfo( [network_model.VIF(id=vif.uuid, address=vif.address)]) info_cache.save(update_cells=False) objects.TagList.create(self.source_context, inst.uuid, ['test']) try: raise test.TestingException('test-fault') except test.TestingException as fault: compute_utils.add_instance_fault_from_exc(self.source_context, inst, fault) objects.InstanceAction().action_start(self.source_context, inst.uuid, 'resize', want_result=False) objects.InstanceActionEvent().event_start(self.source_context, inst.uuid, 'migrate_server', want_result=False) # Create a fake migration for the cross-cell resize operation. migration = objects.Migration( self.source_context, **test_migration.fake_db_migration(instance_uuid=inst.uuid, cross_cell_move=True, migration_type='resize')) delattr(migration, 'id') # cannot create a migration with an id set migration.obj_reset_changes(['id']) migration.create() # Create an old non-resize migration to make sure it is copied to the # target cell database properly. old_migration = objects.Migration( self.source_context, **test_migration.fake_db_migration(instance_uuid=inst.uuid, migration_type='live-migration', status='completed', uuid=uuids.old_migration)) delattr(old_migration, 'id') # cannot create a migration with an id old_migration.obj_reset_changes(['id']) old_migration.create() fake_pci_device = copy.copy(test_pci_device.fake_db_dev) fake_pci_device['extra_info'] = {} # the object requires a dict fake_pci_device['compute_node_id'] = compute_node.id pci_device = objects.PciDevice.create(self.source_context, fake_pci_device) pci_device.allocate(inst) # sets the status and instance_uuid fields pci_device.save() # Return a fresh copy of the instance from the DB with as many joined # fields loaded as possible. expected_attrs = copy.copy(instance_obj.INSTANCE_OPTIONAL_ATTRS) # Cannot load fault from get_by_uuid. expected_attrs.remove('fault') inst = objects.Instance.get_by_uuid(self.source_context, inst.uuid, expected_attrs=expected_attrs) return inst, migration
def fake_trusted_certs(cls, context, instance_uuid): return objects.TrustedCerts(ids=trusted_certs)