def CreatePersistentAttachedDiskMessages(resources, compute_client, csek_keys, disks, project, location, scope, container_mount_disk=None): """Returns a list of AttachedDisk messages and the boot disk's reference.""" disks_messages = [] messages = compute_client.messages compute = compute_client.apitools_client for disk in disks: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY boot = disk.get('boot') == 'yes' auto_delete = disk.get('auto-delete') == 'yes' if 'scope' in disk and disk['scope'] == 'regional': scope = compute_scopes.ScopeEnum.REGION else: scope = compute_scopes.ScopeEnum.ZONE disk_ref = instance_utils.ParseDiskResource(resources, name, project, location, scope) # TODO(b/36051031) drop test after CSEK goes GA if csek_keys: disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, compute) kwargs = {'diskEncryptionKey': disk_key_or_none} else: kwargs = {} device_name = instance_utils.GetDiskDeviceName(disk, name, container_mount_disk) attached_disk = messages.AttachedDisk( autoDelete=auto_delete, boot=boot, deviceName=device_name, mode=mode, source=disk_ref.SelfLink(), type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, **kwargs) # The boot disk must end up at index 0. if boot: disks_messages = [attached_disk] + disks_messages else: disks_messages.append(attached_disk) return disks_messages
def CreateRequests(self, args): """Returns a request for attaching a disk to an instance.""" instance_ref = self.CreateZonalReference(args.name, args.zone) disk_ref = self.CreateZonalReference( args.disk, instance_ref.zone, resource_type='disks') if args.mode == 'rw': mode = self.messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = self.messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY # TODO(user) drop test after CSEK goes GA if hasattr(args, 'csek_key_file'): csek_keys = csek_utils.CsekKeyStore.FromArgs(args) disk_key_or_none = csek_utils.MaybeLookupKeyMessage(csek_keys, disk_ref, self.compute) kwargs = {'diskEncryptionKey': disk_key_or_none} else: kwargs = {} request = self.messages.ComputeInstancesAttachDiskRequest( instance=instance_ref.Name(), project=self.project, attachedDisk=self.messages.AttachedDisk( deviceName=args.device_name, mode=mode, source=disk_ref.SelfLink(), type=self.messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, **kwargs), zone=instance_ref.zone) return [request]
def CreateRequests(self, args): """Returns a request for attaching a disk to an instance.""" instance_ref = instance_flags.INSTANCE_ARG.ResolveAsResource( args, self.resources, scope_lister=flags.GetDefaultScopeLister( self.compute_client, self.project)) disk_ref = self.resources.Parse( args.disk, collection='compute.disks', params={'zone': instance_ref.zone}) if args.mode == 'rw': mode = self.messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = self.messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY allow_rsa_encrypted = self.ReleaseTrack() in [base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA] csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted) disk_key_or_none = csek_utils.MaybeLookupKeyMessage(csek_keys, disk_ref, self.compute) request = self.messages.ComputeInstancesAttachDiskRequest( instance=instance_ref.Name(), project=self.project, attachedDisk=self.messages.AttachedDisk( deviceName=args.device_name, mode=mode, source=disk_ref.SelfLink(), type=self.messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key_or_none), zone=instance_ref.zone) return [request]
def CreateRequests(self, args): """Returns a list of requests necessary for snapshotting disks.""" disk_refs = disks_flags.DISKS_ARG.ResolveAsResource( args, self.resources, scope_lister=flags.GetDefaultScopeLister(self.compute_client, self.project)) if args.snapshot_names: if len(disk_refs) != len(args.snapshot_names): raise exceptions.ToolException( '[--snapshot-names] must have the same number of values as disks ' 'being snapshotted.') snapshot_names = args.snapshot_names else: # Generates names like "d52jsqy3db4q". snapshot_names = [ name_generator.GenerateRandomName() for _ in disk_refs ] snapshot_refs = [ self.resources.Parse(snapshot_name, collection='compute.snapshots') for snapshot_name in snapshot_names ] self._target_to_get_request = {} requests = [] for disk_ref, snapshot_ref in zip(disk_refs, snapshot_refs): # This feature is only exposed in alpha/beta allow_rsa_encrypted = self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ] csek_keys = csek_utils.CsekKeyStore.FromArgs( args, allow_rsa_encrypted) disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, self.compute) # TODO(user) drop test after 'guestFlush' goes GA if hasattr(args, 'guest_flush') and args.guest_flush: request_kwargs = {'guestFlush': True} else: request_kwargs = {} request = self.messages.ComputeDisksCreateSnapshotRequest( disk=disk_ref.Name(), snapshot=self.messages.Snapshot( name=snapshot_ref.Name(), description=args.description, sourceDiskEncryptionKey=disk_key_or_none), project=self.project, zone=disk_ref.zone, **request_kwargs) requests.append(request) self._target_to_get_request[disk_ref.SelfLink()] = ( snapshot_ref.SelfLink(), self.compute.snapshots, self.messages.ComputeSnapshotsGetRequest( snapshot=snapshot_ref.Name(), project=self.project)) return requests
def GetSourceMachineImageKey(args, source_image, compute_client, holder): machine_image_ref = source_image.ResolveAsResource(args, holder.resources) csek_keys = csek_utils.CsekKeyStore.FromFile( args.source_machine_image_csek_key_file, allow_rsa_encrypted=False) disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, machine_image_ref, compute_client.apitools_client) return disk_key_or_none
def CreateRequests(self, args): """Returns a list of requests necessary for adding images.""" image = self.messages.Image( name=args.name, description=args.description, sourceType=self.messages.Image.SourceTypeValueValuesEnum.RAW, family=args.family) csek_keys = csek_utils.CsekKeyStore.FromArgs( args, self._ALLOW_RSA_ENCRYPTED_CSEK_KEYS) if csek_keys: image_ref = self.resources.Parse(args.name, collection='compute.images') image.imageEncryptionKey = csek_utils.MaybeToMessage( csek_keys.LookupKey( image_ref, raise_if_missing=args.require_csek_key_create), self.compute_client.apitools_client) # Validate parameters. if args.source_disk_zone and not args.source_disk: raise exceptions.ToolException( 'You cannot specify [--source-disk-zone] unless you are specifying ' '[--source-disk].') if args.source_disk and args.source_uri: raise exceptions.ConflictingArgumentsException( '--source-uri', '--source-disk') if not (args.source_disk or args.source_uri): raise exceptions.MinimumArgumentException([ '--source-uri', '--source-disk' ], 'Please specify either the source disk or the Google Cloud Storage ' 'URI of the disk image.') # TODO(user): use resources.REGISTRY.Parse() for GCS URIs (b/30086260). if args.source_uri: source_uri = utils.NormalizeGoogleStorageUri(args.source_uri) image.rawDisk = self.messages.Image.RawDiskValue(source=source_uri) else: source_disk_ref = flags.SOURCE_DISK_ARG.ResolveAsResource( args, self.resources, scope_lister=compute_flags.GetDefaultScopeLister( self.compute_client, self.project)) image.sourceDisk = source_disk_ref.SelfLink() image.sourceDiskEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_disk_ref, self.compute_client.apitools_client) if args.licenses: image.licenses = args.licenses request = self.messages.ComputeImagesInsertRequest( image=image, project=self.project) return [request]
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client csek_key_file = args.csek_key_file request_list = [] instance_refs = flags.INSTANCES_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetInstanceZoneScopeLister(client)) if csek_key_file: instances = self.GetInstances(client, instance_refs) else: instances = [None for _ in instance_refs] for instance_ref, instance in zip(instance_refs, instances): disks = [] if csek_key_file: allow_rsa_encrypted = self.ReleaseTrack() in [base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA] csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted) for disk in instance.disks: disk_resource = resources.REGISTRY.Parse(disk.source) disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_resource, client.apitools_client) if disk_key_or_none: disks.append(client.messages.CustomerEncryptionKeyProtectedDisk( diskEncryptionKey=disk_key_or_none, source=disk.source)) if disks: encryption_req = client.messages.InstancesStartWithEncryptionKeyRequest( disks=disks) request = ( client.apitools_client.instances, 'StartWithEncryptionKey', client.messages.ComputeInstancesStartWithEncryptionKeyRequest( instance=instance_ref.Name(), instancesStartWithEncryptionKeyRequest=encryption_req, project=instance_ref.project, zone=instance_ref.zone)) else: request = ( client.apitools_client.instances, 'Start', client.messages.ComputeInstancesStartRequest( instance=instance_ref.Name(), project=instance_ref.project, zone=instance_ref.zone)) request_list.append(request) return client.MakeRequests(request_list)
def CreatePersistentAttachedDiskMessages( resources, compute_client, csek_keys, disks, instance_ref): """Returns a list of AttachedDisk messages and the boot disk's reference.""" disks_messages = [] boot_disk_ref = None messages = compute_client.messages compute = compute_client.apitools_client for disk in disks: name = disk['name'] # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY boot = disk.get('boot') == 'yes' auto_delete = disk.get('auto-delete') == 'yes' disk_ref = resources.Parse( name, collection='compute.disks', params={'zone': instance_ref.zone}) if boot: boot_disk_ref = disk_ref # TODO(user) drop test after CSEK goes GA if csek_keys: disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, compute) kwargs = {'diskEncryptionKey': disk_key_or_none} else: kwargs = {} attached_disk = messages.AttachedDisk( autoDelete=auto_delete, boot=boot, deviceName=disk.get('device-name'), mode=mode, source=disk_ref.SelfLink(), type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, **kwargs) # The boot disk must end up at index 0. if boot: disks_messages = [attached_disk] + disks_messages else: disks_messages.append(attached_disk) return disks_messages, boot_disk_ref
def CreateRequests(self, args): """Returns a list of requests necessary for snapshotting disks.""" if args.snapshot_names: if len(args.disk_names) != len(args.snapshot_names): raise exceptions.ToolException( '[--snapshot-names] must have the same number of values as disks ' 'being snapshotted.') snapshot_names = args.snapshot_names else: # Generates names like "d52jsqy3db4q". snapshot_names = [name_generator.GenerateRandomName() for _ in args.disk_names] snapshot_refs = [ self.CreateGlobalReference(snapshot_name, resource_type='snapshots') for snapshot_name in snapshot_names] self._target_to_get_request = {} requests = [] disk_refs = self.CreateZonalReferences( args.disk_names, args.zone, resource_type='disks') for disk_ref, snapshot_ref in zip(disk_refs, snapshot_refs): # TODO(user) drop test after CSEK goes GA if hasattr(args, 'csek_key_file'): csek_keys = csek_utils.CsekKeyStore.FromArgs(args) disk_key_or_none = csek_utils.MaybeLookupKeyMessage(csek_keys, disk_ref, self.compute) kwargs = {'sourceDiskEncryptionKey': disk_key_or_none} else: kwargs = {} request = self.messages.ComputeDisksCreateSnapshotRequest( disk=disk_ref.Name(), snapshot=self.messages.Snapshot( name=snapshot_ref.Name(), description=args.description, **kwargs ), project=self.project, zone=disk_ref.zone) requests.append(request) self._target_to_get_request[disk_ref.SelfLink()] = ( snapshot_ref.SelfLink(), self.compute.snapshots, self.messages.ComputeSnapshotsGetRequest( snapshot=snapshot_ref.Name(), project=self.project)) return requests
def _Run(self, args, support_disk_scope=False, support_force_attach=False, support_boot=False): """Invokes a request for attaching a disk to an instance.""" holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client instance_ref = flags.INSTANCE_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetInstanceZoneScopeLister(client)) disk_ref = self.ParseDiskRef(holder.resources, args, instance_ref, support_disk_scope) if args.mode == 'rw': mode = client.messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = client.messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY allow_rsa_encrypted = self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ] csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted) disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, client.apitools_client) attached_disk = client.messages.AttachedDisk( deviceName=args.device_name, mode=mode, source=disk_ref.SelfLink(), type=client.messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key_or_none) if support_boot and args.boot: attached_disk.boot = args.boot request = client.messages.ComputeInstancesAttachDiskRequest( instance=instance_ref.Name(), project=instance_ref.project, attachedDisk=attached_disk, zone=instance_ref.zone) if support_force_attach and args.force_attach: request.forceAttach = args.force_attach return client.MakeRequests([(client.apitools_client.instances, 'AttachDisk', request)])
def CreatePersistentAttachedDiskMessages(self, args, instance_ref): """Returns a list of AttachedDisk messages and the boot disk's reference.""" disks = [] boot_disk_ref = None for disk in args.disk or []: name = disk['name'] # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = self.messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = self.messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY boot = disk.get('boot') == 'yes' auto_delete = disk.get('auto-delete') == 'yes' disk_ref = self.CreateZonalReference(name, instance_ref.zone, resource_type='disks') if boot: boot_disk_ref = disk_ref if self.csek_keys: disk_key_or_none = csek_utils.MaybeLookupKeyMessage( self.csek_keys, disk_ref, self.compute) kwargs = {'diskEncryptionKey': disk_key_or_none} else: kwargs = {} attached_disk = self.messages.AttachedDisk( autoDelete=auto_delete, boot=boot, deviceName=disk.get('device-name'), mode=mode, source=disk_ref.SelfLink(), type=self.messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, **kwargs) # The boot disk must end up at index 0. if boot: disks = [attached_disk] + disks else: disks.append(attached_disk) return disks, boot_disk_ref
def CreatePersistentCreateDiskMessages(compute_client, resources, csek_keys, create_disks, instance_ref): """Returns a list of AttachedDisk messages for newly creating disks. Args: compute_client: creates resources, resources: parser of resources, csek_keys: customer suplied encryption keys, create_disks: disk objects - contains following properties * name - the name of disk, * mode - 'rw' (R/W), 'ro' (R/O) access mode, * disk-size - the size of the disk, * disk-type - the type of the disk (HDD or SSD), * image - the name of the image to initialize from, * image-family - the image family name, * image-project - the project name that has the image, * auto-delete - whether disks is deleted when VM is deleted, * device-name - device name on VM. instance_ref: reference to the instance that will own the new disks. Returns: list of API messages for attached disks """ disks_messages = [] messages = compute_client.messages compute = compute_client.apitools_client for disk in create_disks or []: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY auto_delete_value = disk.get('auto-delete', 'yes') auto_delete = auto_delete_value == 'yes' disk_size_gb = utils.BytesToGb(disk.get('size')) disk_type = disk.get('type') if disk_type: disk_type_ref = resources.Parse(disk_type, collection='compute.diskTypes', params={ 'project': instance_ref.project, 'zone': instance_ref.zone }) disk_type_uri = disk_type_ref.SelfLink() else: disk_type_ref = None disk_type_uri = None image_expander = image_utils.ImageExpander(compute_client, resources) image_uri, _ = image_expander.ExpandImageFlag( user_project=instance_ref.project, image=disk.get('image'), image_family=disk.get('image-family'), image_project=disk.get('image-project'), return_image_resource=False) image_key = None disk_key = None if csek_keys: image_key = csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, resources, [image_uri], compute) if name: disk_ref = resources.Parse(name, collection='compute.disks', params={'zone': instance_ref.zone}) disk_key = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, compute) disk_key = kms_utils.MaybeGetKmsKeyFromDict(disk, instance_ref.project, compute, disk_key) create_disk = messages.AttachedDisk( autoDelete=auto_delete, boot=False, deviceName=disk.get('device-name'), initializeParams=messages.AttachedDiskInitializeParams( diskName=name, sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk_type_uri, sourceImageEncryptionKey=image_key), mode=mode, type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key) disks_messages.append(create_disk) return disks_messages
def CreatePersistentCreateDiskMessages(compute_client, resources, csek_keys, create_disks, instance_ref, enable_kms=False, enable_snapshots=False, container_mount_disk=None, resource_policy=False, enable_source_snapshot_csek=False, enable_image_csek=False): """Returns a list of AttachedDisk messages for newly creating disks. Args: compute_client: creates resources, resources: parser of resources, csek_keys: customer suplied encryption keys, create_disks: disk objects - contains following properties * name - the name of disk, * description - an optional description for the disk, * mode - 'rw' (R/W), 'ro' (R/O) access mode, * disk-size - the size of the disk, * disk-type - the type of the disk (HDD or SSD), * image - the name of the image to initialize from, * image-csek-required - the name of the CSK protected image, * image-family - the image family name, * image-project - the project name that has the image, * auto-delete - whether disks is deleted when VM is deleted, * device-name - device name on VM, * source-snapshot - the snapshot to initialize from, * source-snapshot-csek-required - CSK protected snapshot, * disk-resource-policy - resource policies applied to disk. * enable_source_snapshot_csek - CSK file for snapshot, * enable_image_csek - CSK file for image instance_ref: reference to the instance that will own the new disks. enable_kms: True if KMS keys are supported for the disk. enable_snapshots: True if snapshot initialization is supported for the disk. container_mount_disk: list of disks to be mounted to container, if any. resource_policy: True if resource-policies are enabled enable_source_snapshot_csek: True if snapshot CSK files are enabled enable_image_csek: True if image CSK files are enabled Returns: list of API messages for attached disks """ disks_messages = [] messages = compute_client.messages compute = compute_client.apitools_client for disk in create_disks or []: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY auto_delete_value = disk.get('auto-delete', 'yes') auto_delete = auto_delete_value == 'yes' disk_size_gb = utils.BytesToGb(disk.get('size')) disk_type = disk.get('type') if disk_type: disk_type_ref = resources.Parse(disk_type, collection='compute.diskTypes', params={ 'project': instance_ref.project, 'zone': instance_ref.zone }) disk_type_uri = disk_type_ref.SelfLink() else: disk_type_uri = None img = disk.get('image') img_family = disk.get('image-family') img_project = disk.get('image-project') image_uri = None if img or img_family: image_expander = image_utils.ImageExpander(compute_client, resources) image_uri, _ = image_expander.ExpandImageFlag( user_project=instance_ref.project, image=img, image_family=img_family, image_project=img_project, return_image_resource=False) image_key = None disk_key = None if csek_keys: image_key = csek_utils.MaybeLookupKeyMessagesByUri(csek_keys, resources, [image_uri], compute) if name: disk_ref = resources.Parse(name, collection='compute.disks', params={'zone': instance_ref.zone}) disk_key = csek_utils.MaybeLookupKeyMessage(csek_keys, disk_ref, compute) if enable_kms: disk_key = kms_utils.MaybeGetKmsKeyFromDict(disk, messages, disk_key) initialize_params = messages.AttachedDiskInitializeParams( diskName=name, description=disk.get('description'), sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk_type_uri, sourceImageEncryptionKey=image_key) if enable_snapshots: snapshot_name = disk.get('source-snapshot') attached_snapshot_uri = ResolveSnapshotURI( snapshot=snapshot_name, user_project=instance_ref.project, resource_parser=resources) if attached_snapshot_uri: initialize_params.sourceImage = None initialize_params.sourceSnapshot = attached_snapshot_uri if resource_policy: policies = disk.get('disk-resource-policy') if policies: initialize_params.resourcePolicies = policies if enable_image_csek: image_key_file = disk.get('image_csek') if image_key_file: initialize_params.imageKeyFile = image_key_file if enable_source_snapshot_csek: snapshot_key_file = disk.get('source_snapshot_csek') if snapshot_key_file: initialize_params.snapshotKeyFile = snapshot_key_file device_name = GetDiskDeviceName(disk, name, container_mount_disk) create_disk = messages.AttachedDisk( autoDelete=auto_delete, boot=False, deviceName=device_name, initializeParams=initialize_params, mode=mode, type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key) disks_messages.append(create_disk) return disks_messages
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client csek_key_file = args.csek_key_file request_list = [] instance_refs = flags.INSTANCES_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetInstanceZoneScopeLister(client)) # If csek_key_file is supplied, we must first get a reference to the # instances specified in the file to ensure that they exist. # Only then can we verify that the key specified in the file matches what # was used to create the instance. if csek_key_file: instances = self.GetInstances(client, instance_refs) else: instances = [None for _ in instance_refs] for instance_ref, instance in zip(instance_refs, instances): disks = [] if instance: allow_rsa_encrypted = self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ] csek_keys = csek_utils.CsekKeyStore.FromArgs( args, allow_rsa_encrypted) for disk in instance.disks: disk_resource = resources.REGISTRY.Parse(disk.source) disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_resource, client.apitools_client) if disk_key_or_none: disks.append( client.messages.CustomerEncryptionKeyProtectedDisk( diskEncryptionKey=disk_key_or_none, source=disk.source)) if disks: encryption_req = client.messages.InstancesResumeRequest( disks=disks) request = (client.apitools_client.instances, 'Resume', client.messages.ComputeInstancesResumeRequest( instance=instance_ref.Name(), instancesResumeRequest=encryption_req, project=instance_ref.project, zone=instance_ref.zone)) else: request = (client.apitools_client.instances, 'Resume', client.messages.ComputeInstancesResumeRequest( instance=instance_ref.Name(), project=instance_ref.project, zone=instance_ref.zone)) request_list.append(request) errors_to_collect = [] responses = client.BatchRequests(request_list, errors_to_collect) if errors_to_collect: raise exceptions.MultiError(errors_to_collect) operation_refs = [ holder.resources.Parse(r.selfLink) for r in responses ] if args.async_: for operation_ref in operation_refs: log.status.Print( 'Resume instance in progress for [{}].'.format( operation_ref.SelfLink())) log.status.Print( 'Use [gcloud compute operations describe URI] command to check the ' 'status of the operation(s).') return responses operation_poller = poller.BatchPoller(client, client.apitools_client.instances, instance_refs) result = waiter.WaitFor(operation_poller, poller.OperationBatch(operation_refs), 'Resuming instance(s) {0}'.format(', '.join( i.Name() for i in instance_refs)), max_wait_ms=None) for instance_ref in instance_refs: log.status.Print('Updated [{0}].'.format(instance_ref)) return result
def Run(self, args): """Returns a list of requests necessary for snapshotting disks.""" holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) disk_refs = SnapshotDisks.disks_arg.ResolveAsResource( args, holder.resources, scope_lister=flags.GetDefaultScopeLister(holder.client)) if args.snapshot_names: if len(disk_refs) != len(args.snapshot_names): raise exceptions.ToolException( '[--snapshot-names] must have the same number of values as disks ' 'being snapshotted.') snapshot_names = args.snapshot_names else: # Generates names like "d52jsqy3db4q". snapshot_names = [ name_generator.GenerateRandomName() for _ in disk_refs ] snapshot_refs = [ holder.resources.Parse( snapshot_name, params={ 'project': properties.VALUES.core.project.GetOrFail, }, collection='compute.snapshots') for snapshot_name in snapshot_names ] client = holder.client.apitools_client messages = holder.client.messages requests = [] for disk_ref, snapshot_ref in zip(disk_refs, snapshot_refs): # This feature is only exposed in alpha/beta allow_rsa_encrypted = self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ] csek_keys = csek_utils.CsekKeyStore.FromArgs( args, allow_rsa_encrypted) disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, client) snapshot_message = messages.Snapshot( name=snapshot_ref.Name(), description=args.description, sourceDiskEncryptionKey=disk_key_or_none) if (hasattr(args, 'storage_location') and args.IsSpecified('storage_location')): snapshot_message.storageLocations = [args.storage_location] if (hasattr(args, 'labels') and args.IsSpecified('labels')): snapshot_message.labels = labels_util.ParseCreateArgs( args, messages.Snapshot.LabelsValue) if disk_ref.Collection() == 'compute.disks': request = messages.ComputeDisksCreateSnapshotRequest( disk=disk_ref.Name(), snapshot=snapshot_message, project=disk_ref.project, zone=disk_ref.zone, guestFlush=args.guest_flush) requests.append((client.disks, 'CreateSnapshot', request)) elif disk_ref.Collection() == 'compute.regionDisks': request = messages.ComputeRegionDisksCreateSnapshotRequest( disk=disk_ref.Name(), snapshot=snapshot_message, project=disk_ref.project, region=disk_ref.region) if hasattr(request, 'guestFlush'): # only available in alpha API guest_flush = getattr(args, 'guest_flush', None) if guest_flush is not None: request.guestFlush = guest_flush requests.append( (client.regionDisks, 'CreateSnapshot', request)) errors_to_collect = [] responses = holder.client.BatchRequests(requests, errors_to_collect) for r in responses: err = getattr(r, 'error', None) if err: errors_to_collect.append(poller.OperationErrors(err.errors)) if errors_to_collect: raise core_exceptions.MultiError(errors_to_collect) operation_refs = [ holder.resources.Parse(r.selfLink) for r in responses ] if args. async: for operation_ref in operation_refs: log.status.Print('Disk snapshot in progress for [{}].'.format( operation_ref.SelfLink())) log.status.Print( 'Use [gcloud compute operations describe URI] command ' 'to check the status of the operation(s).') return responses operation_poller = poller.BatchPoller(holder.client, client.snapshots, snapshot_refs) return waiter.WaitFor(operation_poller, poller.OperationBatch(operation_refs), 'Creating snapshot(s) {0}'.format(', '.join( s.Name() for s in snapshot_refs)), max_wait_ms=None)
def _Run(self, args, support_source_instant_snapshot=False, support_snapshot_type=False): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client.apitools_client messages = holder.client.messages snap_ref = holder.resources.Parse( args.name, params={ 'project': properties.VALUES.core.project.GetOrFail, }, collection='compute.snapshots') snapshot_message = messages.Snapshot( name=snap_ref.Name(), description=args.description) # This feature is only exposed in alpha/beta allow_rsa_encrypted = self.ReleaseTrack() in [base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA] if args.source_disk: disk_ref = snap_flags.SOURCE_DISK_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetDefaultScopeLister(holder.client)) snapshot_message.sourceDisk = disk_ref.SelfLink() if args.source_disk_key_file: source_keys = csek_utils.CsekKeyStore.FromFile( args.source_disk_key_file, allow_rsa_encrypted) disk_key_or_none = csek_utils.MaybeLookupKeyMessage( source_keys, disk_ref, client) snapshot_message.sourceDiskEncryptionKey = disk_key_or_none if args.csek_key_file: csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted) snap_key_or_none = csek_utils.MaybeLookupKeyMessage(csek_keys, snap_ref, client) snapshot_message.snapshotEncryptionKey = snap_key_or_none if hasattr(args, 'labels') and args.IsSpecified('labels'): snapshot_message.labels = labels_util.ParseCreateArgs( args, messages.Snapshot.LabelsValue) if args.storage_location: snapshot_message.storageLocations = [args.storage_location] if args.guest_flush: snapshot_message.guestFlush = True if args.chain_name: snapshot_message.chainName = args.chain_name if support_source_instant_snapshot and args.source_instant_snapshot: iss_ref = snap_flags.SOURCE_INSTANT_SNAPSHOT_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetDefaultScopeLister(holder.client)) snapshot_message.sourceInstantSnapshot = iss_ref.SelfLink() if support_snapshot_type and args.IsSpecified('snapshot_type'): snapshot_message.snapshotType = snapshot_message.SnapshotTypeValueValuesEnum( args.snapshot_type) request = messages.ComputeSnapshotsInsertRequest( snapshot=snapshot_message, project=snap_ref.project ) result = client.snapshots.Insert(request) operation_ref = resources.REGISTRY.Parse( result.name, params={'project': snap_ref.project}, collection='compute.globalOperations') if args.async_: log.UpdatedResource( operation_ref, kind='gce snapshot {0}'.format(snap_ref.Name()), is_async=True, details='Use [gcloud compute operations describe] command ' 'to check the status of this operation.' ) return result operation_poller = poller.Poller(client.snapshots, snap_ref) return waiter.WaitFor( operation_poller, operation_ref, 'Creating gce snapshot {0}'.format(snap_ref.Name()))
def Run(self, args): """Returns a list of requests necessary for adding images.""" holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client messages = client.messages resource_parser = holder.resources image_ref = Create.DISK_IMAGE_ARG.ResolveAsResource( args, holder.resources) image = messages.Image( name=image_ref.image, description=args.description, sourceType=messages.Image.SourceTypeValueValuesEnum.RAW, family=args.family) csek_keys = csek_utils.CsekKeyStore.FromArgs( args, self._ALLOW_RSA_ENCRYPTED_CSEK_KEYS) if csek_keys: image.imageEncryptionKey = csek_utils.MaybeToMessage( csek_keys.LookupKey( image_ref, raise_if_missing=args.require_csek_key_create), client.apitools_client) # Validate parameters. if args.source_disk_zone and not args.source_disk: raise exceptions.ToolException( 'You cannot specify [--source-disk-zone] unless you are specifying ' '[--source-disk].') source_image_project = getattr(args, 'source_image_project', None) source_image = getattr(args, 'source_image', None) source_image_family = getattr(args, 'source_image_family', None) if source_image_project and not (source_image or source_image_family): raise exceptions.ToolException( 'You cannot specify [--source-image-project] unless you are ' 'specifying [--source-image] or [--source-image-family].') if source_image or source_image_family: image_expander = image_utils.ImageExpander(client, resource_parser) _, source_image_ref = image_expander.ExpandImageFlag( user_project=image_ref.project, image=source_image, image_family=source_image_family, image_project=source_image_project, return_image_resource=True) image.sourceImage = source_image_ref.selfLink image.sourceImageEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_image_ref, client.apitools_client) # TODO(b/30086260): use resources.REGISTRY.Parse() for GCS URIs. if args.source_uri: source_uri = utils.NormalizeGoogleStorageUri(args.source_uri) image.rawDisk = messages.Image.RawDiskValue(source=source_uri) elif args.source_disk: source_disk_ref = flags.SOURCE_DISK_ARG.ResolveAsResource( args, holder.resources, scope_lister=compute_flags.GetDefaultScopeLister(client)) image.sourceDisk = source_disk_ref.SelfLink() image.sourceDiskEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_disk_ref, client.apitools_client) if args.licenses: image.licenses = args.licenses guest_os_features = getattr(args, 'guest_os_features', []) if guest_os_features: guest_os_feature_messages = [] for feature in guest_os_features: gf_type = messages.GuestOsFeature.TypeValueValuesEnum(feature) guest_os_feature = messages.GuestOsFeature() guest_os_feature.type = gf_type guest_os_feature_messages.append(guest_os_feature) image.guestOsFeatures = guest_os_feature_messages request = messages.ComputeImagesInsertRequest( image=image, project=image_ref.project) args_labels = getattr(args, 'labels', None) if args_labels: labels = messages.Image.LabelsValue(additionalProperties=[ messages.Image.LabelsValue.AdditionalProperty(key=key, value=value) for key, value in sorted(args_labels.iteritems()) ]) request.image.labels = labels alpha_or_beta = self.ReleaseTrack() in (base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA) if alpha_or_beta and args.force_create: request.forceCreate = True return client.MakeRequests([(client.apitools_client.images, 'Insert', request)])
def CreatePersistentCreateDiskMessages(compute_client, resources, csek_keys, create_disks, project, location, scope, holder, enable_kms=False, enable_snapshots=False, container_mount_disk=None, enable_source_snapshot_csek=False, enable_image_csek=False, support_replica_zones=False, use_disk_type_uri=True, support_multi_writer=False, support_image_family_scope=False): """Returns a list of AttachedDisk messages for newly creating disks. Args: compute_client: creates resources, resources: parser of resources, csek_keys: customer suplied encryption keys, create_disks: disk objects - contains following properties * name - the name of disk, * description - an optional description for the disk, * mode - 'rw' (R/W), 'ro' (R/O) access mode, * disk-size - the size of the disk, * disk-type - the type of the disk (HDD or SSD), * image - the name of the image to initialize from, * image-csek-required - the name of the CSK protected image, * image-family - the image family name, * image-project - the project name that has the image, * auto-delete - whether disks is deleted when VM is deleted, * device-name - device name on VM, * source-snapshot - the snapshot to initialize from, * source-snapshot-csek-required - CSK protected snapshot, * disk-resource-policy - resource policies applied to disk. * enable_source_snapshot_csek - CSK file for snapshot, * enable_image_csek - CSK file for image project: Project of instance that will own the new disks. location: Location of the instance that will own the new disks. scope: Location type of the instance that will own the new disks. holder: Convenience class to hold lazy initialized client and resources. enable_kms: True if KMS keys are supported for the disk. enable_snapshots: True if snapshot initialization is supported for the disk. container_mount_disk: list of disks to be mounted to container, if any. enable_source_snapshot_csek: True if snapshot CSK files are enabled enable_image_csek: True if image CSK files are enabled support_replica_zones: True if we allow creation of regional disks use_disk_type_uri: True to use disk type URI, False if naked type. support_multi_writer: True if we allow multiple instances to write to disk. support_image_family_scope: True if the zonal image views are supported. Returns: list of API messages for attached disks """ disks_messages = [] messages = compute_client.messages compute = compute_client.apitools_client for disk in create_disks or []: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY auto_delete = disk.get('auto-delete', True) disk_size_gb = utils.BytesToGb(disk.get('size')) disk_type = disk.get('type') if disk_type: if use_disk_type_uri: disk_type_ref = instance_utils.ParseDiskType(resources, disk_type, project, location, scope) disk_type = disk_type_ref.SelfLink() else: disk_type = None img = disk.get('image') img_family = disk.get('image-family') img_project = disk.get('image-project') image_family_scope = disk.get('image_family_scope') image_uri = None if img or img_family: image_expander = image_utils.ImageExpander(compute_client, resources) image_uri, _ = image_expander.ExpandImageFlag( user_project=project, image=img, image_family=img_family, image_project=img_project, return_image_resource=False, image_family_scope=image_family_scope, support_image_family_scope=support_image_family_scope) image_key = None disk_key = None if csek_keys: image_key = csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, resources, [image_uri], compute) if name: disk_ref = resources.Parse( name, collection='compute.disks', params={'zone': location}) disk_key = csek_utils.MaybeLookupKeyMessage(csek_keys, disk_ref, compute) if enable_kms: disk_key = kms_utils.MaybeGetKmsKeyFromDict(disk, messages, disk_key) initialize_params = messages.AttachedDiskInitializeParams( diskName=name, description=disk.get('description'), sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk_type, sourceImageEncryptionKey=image_key) replica_zones = disk.get('replica-zones') if support_replica_zones and replica_zones: normalized_zones = [] for zone in replica_zones: zone_ref = holder.resources.Parse( zone, collection='compute.zones', params={'project': project}) normalized_zones.append(zone_ref.SelfLink()) initialize_params.replicaZones = normalized_zones if enable_snapshots: snapshot_name = disk.get('source-snapshot') attached_snapshot_uri = instance_utils.ResolveSnapshotURI( snapshot=snapshot_name, user_project=project, resource_parser=resources) if attached_snapshot_uri: initialize_params.sourceImage = None initialize_params.sourceSnapshot = attached_snapshot_uri policies = disk.get('disk-resource-policy') if policies: initialize_params.resourcePolicies = policies if enable_image_csek: image_key_file = disk.get('image_csek') if image_key_file: initialize_params.imageKeyFile = image_key_file if enable_source_snapshot_csek: snapshot_key_file = disk.get('source_snapshot_csek') if snapshot_key_file: initialize_params.snapshotKeyFile = snapshot_key_file boot = disk.get('boot', False) multi_writer = disk.get('multi-writer') if support_multi_writer and multi_writer: initialize_params.multiWriter = True provisioned_iops = disk.get('provisioned-iops') if provisioned_iops: initialize_params.provisionedIops = provisioned_iops device_name = instance_utils.GetDiskDeviceName(disk, name, container_mount_disk) create_disk = messages.AttachedDisk( autoDelete=auto_delete, boot=boot, deviceName=device_name, initializeParams=initialize_params, mode=mode, type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key) disks_messages.append(create_disk) return disks_messages
def CreateRequests(self, args): """Returns a list of requests necessary for adding images.""" image_ref = flags.DISK_IMAGE_ARG.ResolveAsResource(args, self.resources) image = self.messages.Image( name=image_ref.image, description=args.description, sourceType=self.messages.Image.SourceTypeValueValuesEnum.RAW, family=args.family) csek_keys = csek_utils.CsekKeyStore.FromArgs( args, self._ALLOW_RSA_ENCRYPTED_CSEK_KEYS) if csek_keys: image.imageEncryptionKey = csek_utils.MaybeToMessage( csek_keys.LookupKey(image_ref, raise_if_missing=args.require_csek_key_create), self.compute_client.apitools_client) # Validate parameters. if args.source_disk_zone and not args.source_disk: raise exceptions.ToolException( 'You cannot specify [--source-disk-zone] unless you are specifying ' '[--source-disk].') if args.source_disk and args.source_uri: raise exceptions.ConflictingArgumentsException( '--source-uri', '--source-disk') if not (args.source_disk or args.source_uri): raise exceptions.MinimumArgumentException( ['--source-uri', '--source-disk'], 'Please specify either the source disk or the Google Cloud Storage ' 'URI of the disk image.' ) # TODO(b/30086260): use resources.REGISTRY.Parse() for GCS URIs. if args.source_uri: source_uri = utils.NormalizeGoogleStorageUri(args.source_uri) image.rawDisk = self.messages.Image.RawDiskValue(source=source_uri) else: source_disk_ref = flags.SOURCE_DISK_ARG.ResolveAsResource( args, self.resources, scope_lister=compute_flags.GetDefaultScopeLister(self.compute_client)) image.sourceDisk = source_disk_ref.SelfLink() image.sourceDiskEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_disk_ref, self.compute_client.apitools_client) if args.licenses: image.licenses = args.licenses guest_os_features = getattr(args, 'guest_os_features', []) if guest_os_features: guest_os_feature_messages = [] for feature in guest_os_features: gf_type = self.messages.GuestOsFeature.TypeValueValuesEnum(feature) guest_os_feature = self.messages.GuestOsFeature() guest_os_feature.type = gf_type guest_os_feature_messages.append(guest_os_feature) image.guestOsFeatures = guest_os_feature_messages request = self.messages.ComputeImagesInsertRequest( image=image, project=image_ref.project) args_labels = getattr(args, 'labels', None) if args_labels: labels = self.messages.Image.LabelsValue(additionalProperties=[ self.messages.Image.LabelsValue.AdditionalProperty( key=key, value=value) for key, value in sorted(args_labels.iteritems())]) request.image.labels = labels return [request]
def _Run(self, args, supports_storage_location=False, supports_shielded_instance_initial_state=False): """Returns a list of requests necessary for adding images.""" holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client messages = client.messages resource_parser = holder.resources image_ref = Create.DISK_IMAGE_ARG.ResolveAsResource( args, holder.resources) image = messages.Image( name=image_ref.image, description=args.description, sourceType=messages.Image.SourceTypeValueValuesEnum.RAW, family=args.family) csek_keys = csek_utils.CsekKeyStore.FromArgs( args, self._ALLOW_RSA_ENCRYPTED_CSEK_KEYS) if csek_keys: image.imageEncryptionKey = csek_utils.MaybeToMessage( csek_keys.LookupKey( image_ref, raise_if_missing=args.require_csek_key_create), client.apitools_client) image.imageEncryptionKey = kms_utils.MaybeGetKmsKey( args, messages, image.imageEncryptionKey) # Validate parameters. if args.source_disk_zone and not args.source_disk: raise exceptions.ToolException( 'You cannot specify [--source-disk-zone] unless you are specifying ' '[--source-disk].') source_image_project = args.source_image_project source_image = args.source_image source_image_family = args.source_image_family if source_image_project and not (source_image or source_image_family): raise exceptions.ToolException( 'You cannot specify [--source-image-project] unless you are ' 'specifying [--source-image] or [--source-image-family].') if source_image or source_image_family: image_expander = image_utils.ImageExpander(client, resource_parser) _, source_image_ref = image_expander.ExpandImageFlag( user_project=image_ref.project, image=source_image, image_family=source_image_family, image_project=source_image_project, return_image_resource=True) image.sourceImage = source_image_ref.selfLink image.sourceImageEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_image_ref, client.apitools_client) if args.source_uri: source_uri = str(resources.REGISTRY.Parse(args.source_uri)) image.rawDisk = messages.Image.RawDiskValue(source=source_uri) elif args.source_disk: source_disk_ref = flags.SOURCE_DISK_ARG.ResolveAsResource( args, holder.resources, scope_lister=compute_flags.GetDefaultScopeLister(client)) image.sourceDisk = source_disk_ref.SelfLink() image.sourceDiskEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_disk_ref, client.apitools_client) elif hasattr(args, 'source_snapshot') and args.source_snapshot: source_snapshot_ref = flags.SOURCE_SNAPSHOT_ARG.ResolveAsResource( args, holder.resources, scope_lister=compute_flags.GetDefaultScopeLister(client)) image.sourceSnapshot = source_snapshot_ref.SelfLink() image.sourceSnapshotEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_snapshot_ref, client.apitools_client) if args.licenses: image.licenses = args.licenses guest_os_features = getattr(args, 'guest_os_features', []) if guest_os_features: guest_os_feature_messages = [] for feature in guest_os_features: gf_type = messages.GuestOsFeature.TypeValueValuesEnum(feature) guest_os_feature = messages.GuestOsFeature() guest_os_feature.type = gf_type guest_os_feature_messages.append(guest_os_feature) image.guestOsFeatures = guest_os_feature_messages if supports_shielded_instance_initial_state: initial_state, has_set =\ image_utils.CreateInitialStateConfig(args, messages) if has_set: image.shieldedInstanceInitialState = initial_state if (supports_storage_location and args.IsSpecified('storage_location')): image.storageLocations = [args.storage_location] request = messages.ComputeImagesInsertRequest( image=image, project=image_ref.project) args_labels = getattr(args, 'labels', None) if args_labels: labels = messages.Image.LabelsValue(additionalProperties=[ messages.Image.LabelsValue.AdditionalProperty(key=key, value=value) for key, value in sorted(six.iteritems(args_labels)) ]) request.image.labels = labels # --force is in GA, --force-create is in beta and deprecated. if args.force or getattr(args, 'force_create', None): request.forceCreate = True return client.MakeRequests([(client.apitools_client.images, 'Insert', request)])
def Run(self, args): """Returns a list of requests necessary for snapshotting disks.""" holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) disk_refs = SnapshotDisks.disks_arg.ResolveAsResource( args, holder.resources, scope_lister=flags.GetDefaultScopeLister(holder.client)) if args.snapshot_names: if len(disk_refs) != len(args.snapshot_names): raise exceptions.ToolException( '[--snapshot-names] must have the same number of values as disks ' 'being snapshotted.') snapshot_names = args.snapshot_names else: # Generates names like "d52jsqy3db4q". snapshot_names = [ name_generator.GenerateRandomName() for _ in disk_refs ] snapshot_refs = [ holder.resources.Parse(snapshot_name, collection='compute.snapshots') for snapshot_name in snapshot_names ] client = holder.client.apitools_client messages = holder.client.messages requests = [] for disk_ref, snapshot_ref in zip(disk_refs, snapshot_refs): # This feature is only exposed in alpha/beta allow_rsa_encrypted = self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ] csek_keys = csek_utils.CsekKeyStore.FromArgs( args, allow_rsa_encrypted) disk_key_or_none = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, client) # TODO(user) drop test after 'guestFlush' goes GA if hasattr(args, 'guest_flush') and args.guest_flush: request_kwargs = {'guestFlush': True} else: request_kwargs = {} if disk_ref.Collection() == 'compute.disks': request = messages.ComputeDisksCreateSnapshotRequest( disk=disk_ref.Name(), snapshot=messages.Snapshot( name=snapshot_ref.Name(), description=args.description, sourceDiskEncryptionKey=disk_key_or_none), project=disk_ref.project, zone=disk_ref.zone, **request_kwargs) requests.append((client.disks, 'CreateSnapshot', request)) elif disk_ref.Collection() == 'compute.regionDisks': request = messages.ComputeRegionDisksCreateSnapshotRequest( disk=disk_ref.Name(), snapshot=messages.Snapshot( name=snapshot_ref.Name(), description=args.description, sourceDiskEncryptionKey=disk_key_or_none), project=disk_ref.project, region=disk_ref.region, **request_kwargs) requests.append( (client.regionDisks, 'CreateSnapshot', request)) errors_to_collect = [] responses = holder.client.BatchRequests(requests, errors_to_collect) if errors_to_collect: raise core_exceptions.MultiError(errors_to_collect) operation_refs = [ holder.resources.Parse(r.selfLink) for r in responses ] if args. async: for operation_ref in operation_refs: log.status.Print('Disk snapshot in progress for [{}].'.format( operation_ref.SelfLink())) log.status.Print( 'Use [gcloud compute operations describe URI] command ' 'to check the status of the operation(s).') return responses operation_poller = poller.BatchPoller(holder.client, client.snapshots, snapshot_refs) return waiter.WaitFor( operation_poller, poller.OperationBatch(operation_refs), 'Creating snapshot(s) {0}'.format(', '.join( s.Name() for s in snapshot_refs)))