def _Run(self, args, supports_kms_keys=False, supports_physical_block=False, support_multiwriter_disk=False, support_vss_erase=False, support_pd_interface=False, support_user_licenses=False): compute_holder = self._GetApiHolder() client = compute_holder.client self.show_unformated_message = not ( args.IsSpecified('image') or args.IsSpecified('image_family') or args.IsSpecified('source_snapshot') or args.IsSpecified('source_disk')) if self.source_instant_snapshot_enabled: self.show_unformated_message = self.show_unformated_message and not ( args.IsSpecified('source_instant_snapshot')) disk_refs = self.ValidateAndParseDiskRefs(args, compute_holder) from_image = self.GetFromImage(args) size_gb = self.GetDiskSizeGb(args, from_image) self.WarnAboutScopeDeprecationsAndMaintenance(disk_refs, client) project_to_source_image = self.GetProjectToSourceImageDict( args, disk_refs, compute_holder, from_image) snapshot_uri = self.GetSnapshotUri(args, compute_holder) # Those features are only exposed in alpha/beta, it would be nice to have # code supporting them only in alpha and beta versions of the command. labels = self.GetLabels(args, client) allow_rsa_encrypted = self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ] csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted) for project in project_to_source_image: source_image_uri = project_to_source_image[project].uri project_to_source_image[project].keys = ( csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, compute_holder.resources, [source_image_uri, snapshot_uri], client.apitools_client)) # end of alpha/beta features. guest_os_feature_messages = _ParseGuestOsFeaturesToMessages( args, client.messages) requests = [] for disk_ref in disk_refs: type_uri = self.GetDiskTypeUri(args, disk_ref, compute_holder) # Those features are only exposed in alpha/beta, it would be nice to have # code supporting them only in alpha and beta versions of the command. # TODO(b/65161039): Stop checking release path in the middle of GA code. kwargs = {} if csek_keys: disk_key_or_none = csek_keys.LookupKey( disk_ref, args.require_csek_key_create) disk_key_message_or_none = csek_utils.MaybeToMessage( disk_key_or_none, client.apitools_client) kwargs['diskEncryptionKey'] = disk_key_message_or_none kwargs['sourceImageEncryptionKey'] = ( project_to_source_image[disk_ref.project].keys[0]) kwargs['sourceSnapshotEncryptionKey'] = ( project_to_source_image[disk_ref.project].keys[1]) if labels: kwargs['labels'] = labels if supports_kms_keys: kwargs['diskEncryptionKey'] = kms_utils.MaybeGetKmsKey( args, client.messages, kwargs.get('diskEncryptionKey', None)) if support_pd_interface and args.interface: kwargs['interface'] = arg_utils.ChoiceToEnum( args.interface, client.messages.Disk.InterfaceValueValuesEnum) # end of alpha/beta features. if supports_physical_block and args.IsSpecified( 'physical_block_size'): physical_block_size_bytes = int(args.physical_block_size) else: physical_block_size_bytes = None resource_policies = getattr(args, 'resource_policies', None) if resource_policies: if disk_ref.Collection() == 'compute.regionDisks': disk_region = disk_ref.region else: disk_region = utils.ZoneNameToRegionName(disk_ref.zone) parsed_resource_policies = [] for policy in resource_policies: resource_policy_ref = resource_util.ParseResourcePolicy( compute_holder.resources, policy, project=disk_ref.project, region=disk_region) parsed_resource_policies.append( resource_policy_ref.SelfLink()) kwargs['resourcePolicies'] = parsed_resource_policies disk = client.messages.Disk( name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, physicalBlockSizeBytes=physical_block_size_bytes, **kwargs) disk.sourceDisk = self.GetSourceDiskUri(args, disk_ref, compute_holder) if self.source_instant_snapshot_enabled: disk.sourceInstantSnapshot = self.GetSourceInstantSnapshotUri( args, compute_holder) if (support_multiwriter_disk and disk_ref.Collection() == 'compute.regionDisks' and args.IsSpecified('multi_writer')): raise exceptions.InvalidArgumentException( '--multi-writer', ('--multi-writer can be used only with --zone flag')) if (support_multiwriter_disk and disk_ref.Collection() == 'compute.disks' and args.IsSpecified('multi_writer')): disk.multiWriter = args.multi_writer if guest_os_feature_messages: disk.guestOsFeatures = guest_os_feature_messages if support_vss_erase and args.IsSpecified( 'erase_windows_vss_signature'): disk.eraseWindowsVssSignature = args.erase_windows_vss_signature disk.licenses = self.ParseLicenses(args) if args.IsSpecified('provisioned_iops'): if type_uri and type_uri.endswith('/pd-extreme'): disk.provisionedIops = args.provisioned_iops else: raise exceptions.InvalidArgumentException( '--provisioned-iops', '--provisioned-iops can be used only with pd-extreme disk type.' ) if support_user_licenses and args.IsSpecified('user_licenses'): disk.userLicenses = args.user_licenses if disk_ref.Collection() == 'compute.disks': request = client.messages.ComputeDisksInsertRequest( disk=disk, project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, zone=disk_ref.zone) request = (client.apitools_client.disks, 'Insert', request) elif disk_ref.Collection() == 'compute.regionDisks': disk.replicaZones = self.GetReplicaZones( args, compute_holder, disk_ref) request = client.messages.ComputeRegionDisksInsertRequest( disk=disk, project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, region=disk_ref.region) request = (client.apitools_client.regionDisks, 'Insert', request) requests.append(request) return client.MakeRequests(requests)
def CreateDefaultBootAttachedDiskMessage(compute_client, resources, disk_type, disk_device_name, disk_auto_delete, disk_size_gb, require_csek_key_create, image_uri, instance_ref, csek_keys=None, kms_args=None, enable_kms=False, snapshot_uri=None): """Returns an AttachedDisk message for creating a new boot disk.""" messages = compute_client.messages compute = compute_client.apitools_client 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 if csek_keys: # If we're going to encrypt the boot disk make sure that we select # a name predictably, instead of letting the API deal with name # conflicts automatically. # # Note that when csek keys are being used we *always* want force this # even if we don't have any encryption key for default disk name. # # Consider the case where the user's key file has a key for disk `foo-1` # and no other disk. Assume she runs # gcloud compute instances create foo --csek-key-file f \ # --no-require-csek-key-create # and gcloud doesn't force the disk name to be `foo`. The API might # select name `foo-1` for the new disk, but has no way of knowing # that the user has a key file mapping for that disk name. That # behavior violates the principle of least surprise. # # Instead it's better for gcloud to force a specific disk name in the # instance create, and fail if that name isn't available. effective_boot_disk_name = (disk_device_name or instance_ref.Name()) disk_ref = resources.Parse(effective_boot_disk_name, collection='compute.disks', params={ 'project': instance_ref.project, 'zone': instance_ref.zone }) disk_key_or_none = csek_utils.MaybeToMessage( csek_keys.LookupKey(disk_ref, require_csek_key_create), compute) [image_key_or_none ] = csek_utils.MaybeLookupKeyMessagesByUri(csek_keys, resources, [image_uri], compute) kwargs_init_parms = {'sourceImageEncryptionKey': image_key_or_none} kwargs_disk = {'diskEncryptionKey': disk_key_or_none} else: kwargs_disk = {} kwargs_init_parms = {} effective_boot_disk_name = disk_device_name if enable_kms: kms_key = kms_utils.MaybeGetKmsKey(kms_args, messages, kwargs_disk.get( 'diskEncryptionKey', None), boot_disk_prefix=True) if kms_key: kwargs_disk = {'diskEncryptionKey': kms_key} initialize_params = messages.AttachedDiskInitializeParams( sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk_type_uri, **kwargs_init_parms) if snapshot_uri: initialize_params.sourceImage = None initialize_params.sourceSnapshot = snapshot_uri return messages.AttachedDisk( autoDelete=disk_auto_delete, boot=True, deviceName=effective_boot_disk_name, initializeParams=initialize_params, mode=messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE, type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, **kwargs_disk)
def CreateDefaultBootAttachedDiskMessage(self, args, boot_disk_size_gb, image_uri, instance_ref): """Returns an AttachedDisk message for creating a new boot disk.""" if args.boot_disk_type: disk_type_ref = self.CreateZonalReference( args.boot_disk_type, instance_ref.zone, resource_type='diskTypes') disk_type_uri = disk_type_ref.SelfLink() else: disk_type_ref = None disk_type_uri = None if self.csek_keys: # If we're going to encrypt the boot disk make sure that we select # a name predictably, instead of letting the API deal with name # conflicts automatically. # # Note that when csek keys are being used we *always* want force this # even if we don't have any encryption key for default disk name. # # Consider the case where the user's key file has a key for disk `foo-1` # and no other disk. Assume she runs # gcloud compute instances create foo --csek-key-file f \ # --no-requires-csek-key-create # and gcloud doesn't force the disk name to be `foo`. The API might # select name `foo-1` for the new disk, but has no way of knowing # that the user has a key file mapping for that disk name. That # behavior violates the principle of least surprise. # # Instead it's better for gcloud to force a specific disk name in the # instance create, and fail if that name isn't available. effective_boot_disk_name = (args.boot_disk_device_name or instance_ref.Name()) disk_ref = self.CreateZonalReference(effective_boot_disk_name, instance_ref.zone, resource_type='disks') disk_key_or_none = csek_utils.MaybeToMessage( self.csek_keys.LookupKey(disk_ref, args.require_csek_key_create), self.compute) [image_key_or_none] = csek_utils.MaybeLookupKeyMessagesByUri( self.csek_keys, self.resources, [image_uri], self.compute) kwargs_init_parms = {'sourceImageEncryptionKey': image_key_or_none} kwargs_disk = {'diskEncryptionKey': disk_key_or_none} else: kwargs_disk = {} kwargs_init_parms = {} effective_boot_disk_name = args.boot_disk_device_name return self.messages.AttachedDisk( autoDelete=args.boot_disk_auto_delete, boot=True, deviceName=effective_boot_disk_name, initializeParams=self.messages.AttachedDiskInitializeParams( sourceImage=image_uri, diskSizeGb=boot_disk_size_gb, diskType=disk_type_uri, **kwargs_init_parms), mode=self.messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE, type=self.messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, **kwargs_disk)
def CreateRequests(self, args): """Returns a list of requests necessary for adding disks.""" size_gb = utils.BytesToGb(args.size) if not size_gb and not args.source_snapshot and not args.image: if args.type and 'pd-ssd' in args.type: size_gb = constants.DEFAULT_SSD_DISK_SIZE_GB else: size_gb = constants.DEFAULT_STANDARD_DISK_SIZE_GB utils.WarnIfDiskSizeIsTooSmall(size_gb, args.type) requests = [] disk_refs = self.CreateZonalReferences(args.names, args.zone) # Check if the zone is deprecated or has maintenance coming. self.WarnForZonalCreation(disk_refs) if args.image: source_image_uri, _ = self.ExpandImageFlag( args, return_image_resource=False) else: source_image_uri = None if args.source_snapshot: snapshot_ref = self.CreateGlobalReference( args.source_snapshot, resource_type='snapshots') snapshot_uri = snapshot_ref.SelfLink() else: snapshot_uri = None if hasattr(args, 'csek_key_file'): csek_keys = csek_utils.CsekKeyStore.FromArgs(args) else: csek_keys = None image_key_message_or_none, snapshot_key_message_or_none = ( csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, self.resources, [source_image_uri, snapshot_uri], self.compute)) for disk_ref in disk_refs: if args.type: type_ref = self.CreateZonalReference(args.type, disk_ref.zone, resource_type='diskTypes') type_uri = type_ref.SelfLink() else: type_uri = None if csek_keys: disk_key_or_none = csek_keys.LookupKey( disk_ref, args.require_csek_key_create) disk_key_message_or_none = csek_utils.MaybeToMessage( disk_key_or_none, self.compute) kwargs = { 'diskEncryptionKey': disk_key_message_or_none, 'sourceImageEncryptionKey': image_key_message_or_none, 'sourceSnapshotEncryptionKey': snapshot_key_message_or_none } else: kwargs = {} request = self.messages.ComputeDisksInsertRequest( disk=self.messages.Disk(name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, **kwargs), project=self.project, sourceImage=source_image_uri, zone=disk_ref.zone) requests.append(request) return requests
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) image.imageEncryptionKey = kms_utils.MaybeGetKmsKey( args, image_ref.project, client.apitools_client, 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) # 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) 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 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, supports_kms_keys=False): compute_holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = compute_holder.client self.show_unformated_message = not (args.IsSpecified('image') or args.IsSpecified('image_family') or args.IsSpecified('source_snapshot')) disk_refs = self.ValidateAndParseDiskRefs(args, compute_holder) from_image = self.GetFromImage(args) size_gb = self.GetDiskSizeGb(args, from_image) self.WarnAboutScopeDeprecationsAndMaintainance(disk_refs, client) project_to_source_image = self.GetProjectToSourceImageDict( args, disk_refs, compute_holder, from_image) snapshot_uri = self.GetSnapshotUri(args, compute_holder) # Those features are only exposed in alpha/beta, it would be nice to have # code supporting them only in alpha and beta versions of the command. labels = self.GetLabels(args, client) allow_rsa_encrypted = self.ReleaseTrack() in [base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA] csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted) for project in project_to_source_image: source_image_uri = project_to_source_image[project].uri project_to_source_image[project].keys = ( csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, compute_holder.resources, [source_image_uri, snapshot_uri], client.apitools_client)) resource_policies = getattr(args, 'resource_policies', None) # end of alpha/beta features. guest_os_feature_messages = _ParseGuestOsFeaturesToMessages( args, client.messages) requests = [] for disk_ref in disk_refs: type_uri = self.GetDiskTypeUri(args, disk_ref, compute_holder) # Those features are only exposed in alpha/beta, it would be nice to have # code supporting them only in alpha and beta versions of the command. # TODO(b/65161039): Stop checking release path in the middle of GA code. kwargs = {} if csek_keys: disk_key_or_none = csek_keys.LookupKey( disk_ref, args.require_csek_key_create) disk_key_message_or_none = csek_utils.MaybeToMessage( disk_key_or_none, client.apitools_client) kwargs['diskEncryptionKey'] = disk_key_message_or_none kwargs['sourceImageEncryptionKey'] = ( project_to_source_image[disk_ref.project].keys[0]) kwargs['sourceSnapshotEncryptionKey'] = ( project_to_source_image[disk_ref.project].keys[1]) if labels: kwargs['labels'] = labels if supports_kms_keys: kwargs['diskEncryptionKey'] = kms_utils.MaybeGetKmsKey( args, client.messages, kwargs.get('diskEncryptionKey', None)) if resource_policies: if disk_ref.Collection() == 'compute.regionDisks': raise exceptions.InvalidArgumentException( '--resource-policies', 'Resource policies are not supported for regional disks.') parsed_resource_policies = [] for policy in resource_policies: resource_policy_ref = resource_util.ParseResourcePolicyWithZone( compute_holder.resources, policy, project=disk_ref.project, zone=disk_ref.zone) parsed_resource_policies.append(resource_policy_ref.SelfLink()) kwargs['resourcePolicies'] = parsed_resource_policies # end of alpha/beta features. disk = client.messages.Disk( name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, **kwargs) if guest_os_feature_messages: disk.guestOsFeatures = guest_os_feature_messages disk.licenses = self.ParseLicenses(args) if disk_ref.Collection() == 'compute.disks': request = client.messages.ComputeDisksInsertRequest( disk=disk, project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, zone=disk_ref.zone) request = (client.apitools_client.disks, 'Insert', request) elif disk_ref.Collection() == 'compute.regionDisks': disk.replicaZones = self.GetReplicaZones(args, compute_holder, disk_ref) request = client.messages.ComputeRegionDisksInsertRequest( disk=disk, project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, region=disk_ref.region) request = (client.apitools_client.regionDisks, 'Insert', request) requests.append(request) return client.MakeRequests(requests)
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(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)) 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) return [request]
def CreateRequests(self, args): """Returns a list of requests necessary for adding disks.""" size_gb = utils.BytesToGb(args.size) from_image = args.image or args.image_family if not size_gb and not args.source_snapshot and not from_image: if args.type and 'pd-ssd' in args.type: size_gb = constants.DEFAULT_SSD_DISK_SIZE_GB else: size_gb = constants.DEFAULT_STANDARD_DISK_SIZE_GB utils.WarnIfDiskSizeIsTooSmall(size_gb, args.type) requests = [] disk_refs = disks_flags.DISKS_ARG.ResolveAsResource( args, self.resources, scope_lister=flags.GetDefaultScopeLister(self.compute_client, self.project)) # Check if the zone is deprecated or has maintenance coming. self.WarnForZonalCreation(disk_refs) if from_image: source_image_uri, _ = self.ExpandImageFlag( args, return_image_resource=False) else: source_image_uri = None snapshot_ref = disks_flags.SOURCE_SNAPSHOT_ARG.ResolveAsResource( args, self.resources) if snapshot_ref: snapshot_uri = snapshot_ref.SelfLink() else: snapshot_uri = None # 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) image_key_message_or_none, snapshot_key_message_or_none = ( csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, self.resources, [source_image_uri, snapshot_uri], self.compute)) for disk_ref in disk_refs: if args.type: type_ref = self.resources.Parse(args.type, collection='compute.diskTypes', params={'zone': disk_ref.zone}) type_uri = type_ref.SelfLink() else: type_uri = None if csek_keys: disk_key_or_none = csek_keys.LookupKey( disk_ref, args.require_csek_key_create) disk_key_message_or_none = csek_utils.MaybeToMessage( disk_key_or_none, self.compute) kwargs = { 'diskEncryptionKey': disk_key_message_or_none, 'sourceImageEncryptionKey': image_key_message_or_none, 'sourceSnapshotEncryptionKey': snapshot_key_message_or_none } else: kwargs = {} request = self.messages.ComputeDisksInsertRequest( disk=self.messages.Disk(name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, **kwargs), project=self.project, sourceImage=source_image_uri, zone=disk_ref.zone) requests.append(request) return requests
def Run(self, args): compute_holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = compute_holder.client disk_refs = self.ValidateAndParse(args, compute_holder) size_gb = utils.BytesToGb(args.size) from_image = args.image or args.image_family if not size_gb and not args.source_snapshot and not from_image: if args.type and 'pd-ssd' in args.type: size_gb = constants.DEFAULT_SSD_DISK_SIZE_GB else: size_gb = constants.DEFAULT_STANDARD_DISK_SIZE_GB utils.WarnIfDiskSizeIsTooSmall(size_gb, args.type) requests = [] # Check if the zone is deprecated or has maintenance coming. zone_resource_fetcher = zone_utils.ZoneResourceFetcher(client) zone_resource_fetcher.WarnForZonalCreation( (ref for ref in disk_refs if ref.Collection() == 'compute.disks')) # Check if the region is deprecated or has maintenance coming. region_resource_fetcher = region_utils.RegionResourceFetcher(client) region_resource_fetcher.WarnForRegionalCreation( (ref for ref in disk_refs if ref.Collection() == 'compute.regionDisks')) project_to_source_image = {} image_expander = image_utils.ImageExpander(client, compute_holder.resources) for disk_ref in disk_refs: if from_image: if disk_ref.project not in project_to_source_image: source_image_uri, _ = image_expander.ExpandImageFlag( user_project=disk_ref.project, image=args.image, image_family=args.image_family, image_project=args.image_project, return_image_resource=False) project_to_source_image[ disk_ref.project] = argparse.Namespace() project_to_source_image[ disk_ref.project].uri = source_image_uri else: project_to_source_image[ disk_ref.project] = argparse.Namespace() project_to_source_image[disk_ref.project].uri = None snapshot_ref = disks_flags.SOURCE_SNAPSHOT_ARG.ResolveAsResource( args, compute_holder.resources) if snapshot_ref: snapshot_uri = snapshot_ref.SelfLink() else: snapshot_uri = None # 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) for project in project_to_source_image: source_image_uri = project_to_source_image[project].uri project_to_source_image[project].keys = ( csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, compute_holder.resources, [source_image_uri, snapshot_uri], client.apitools_client)) for disk_ref in disk_refs: if args.type: if disk_ref.Collection() == 'compute.disks': type_ref = compute_holder.resources.Parse( args.type, collection='compute.diskTypes', params={ 'project': disk_ref.project, 'zone': disk_ref.zone }) elif disk_ref.Collection() == 'compute.regionDisks': type_ref = compute_holder.resources.Parse( args.type, collection='compute.regionDiskTypes', params={ 'project': disk_ref.project, 'region': disk_ref.region }) type_uri = type_ref.SelfLink() else: type_uri = None if csek_keys: disk_key_or_none = csek_keys.LookupKey( disk_ref, args.require_csek_key_create) disk_key_message_or_none = csek_utils.MaybeToMessage( disk_key_or_none, client.apitools_client) kwargs = { 'diskEncryptionKey': disk_key_message_or_none, 'sourceImageEncryptionKey': project_to_source_image[disk_ref.project].keys[0], 'sourceSnapshotEncryptionKey': project_to_source_image[disk_ref.project].keys[1] } else: kwargs = {} if disk_ref.Collection() == 'compute.disks': request = client.messages.ComputeDisksInsertRequest( disk=client.messages.Disk(name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, **kwargs), project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, zone=disk_ref.zone) request = (client.apitools_client.disks, 'Insert', request) elif disk_ref.Collection() == 'compute.regionDisks': def SelfLink(zone, disk_ref): return compute_holder.resources.Parse( zone, collection='compute.zones', params={ 'project': disk_ref.project }).SelfLink() zones = [ SelfLink(zone, disk_ref) for zone in args.replica_zones ] request = client.messages.ComputeRegionDisksInsertRequest( disk=client.messages.Disk(name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, replicaZones=zones, **kwargs), project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, region=disk_ref.region) request = (client.apitools_client.regionDisks, 'Insert', request) requests.append(request) return client.MakeRequests(requests)
def Run(self, args): compute_holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = compute_holder.client disk_refs = self.ValidateAndParseDiskRefs(args, compute_holder) from_image = self.GetFromImage(args) size_gb = self.GetDiskSizeGb(args, from_image) self.WarnAboutScopeDeprecationsAndMaintainance(disk_refs, client) project_to_source_image = self.GetProjectToSourceImageDict( args, disk_refs, compute_holder, from_image) snapshot_uri = self.GetSnapshotUri(args, compute_holder) # Those features are only exposed in alpha/beta, it would be nice to have # code supporting them only in alpha and beta versions of the command. labels = self.GetLabels(args, client) allow_rsa_encrypted = self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ] csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted) for project in project_to_source_image: source_image_uri = project_to_source_image[project].uri project_to_source_image[project].keys = ( csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, compute_holder.resources, [source_image_uri, snapshot_uri], client.apitools_client)) # end of alpha/beta features. requests = [] for disk_ref in disk_refs: type_uri = self.GetDiskTypeUri(args, disk_ref, compute_holder) # Those features are only exposed in alpha/beta, it would be nice to have # code supporting them only in alpha and beta versions of the command. kwargs = {} if csek_keys: disk_key_or_none = csek_keys.LookupKey( disk_ref, args.require_csek_key_create) disk_key_message_or_none = csek_utils.MaybeToMessage( disk_key_or_none, client.apitools_client) kwargs['diskEncryptionKey'] = disk_key_message_or_none kwargs['sourceImageEncryptionKey'] = ( project_to_source_image[disk_ref.project].keys[0]) kwargs['sourceSnapshotEncryptionKey'] = ( project_to_source_image[disk_ref.project].keys[1]) if labels: kwargs['labels'] = labels # end of alpha/beta features. disk = client.messages.Disk(name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, **kwargs) if disk_ref.Collection() == 'compute.disks': request = client.messages.ComputeDisksInsertRequest( disk=disk, project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, zone=disk_ref.zone) request = (client.apitools_client.disks, 'Insert', request) elif disk_ref.Collection() == 'compute.regionDisks': disk.replicaZones = self.GetReplicaZones( args, compute_holder, disk_ref) request = client.messages.ComputeRegionDisksInsertRequest( disk=disk, project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, region=disk_ref.region) request = (client.apitools_client.regionDisks, 'Insert', request) requests.append(request) return client.MakeRequests(requests)
def Run(self, args): """Returns a list of requests necessary for adding machine images.""" holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client machine_image_ref = Create.MACHINE_IMAGE_ARG.ResolveAsResource( args, holder.resources, default_scope=scope.ScopeEnum.GLOBAL, scope_lister=flags.GetDefaultScopeLister(client)) source_instance = Create.SOURCE_INSTANCE.ResolveAsResource( args, holder.resources) machine_image = client.messages.MachineImage( name=machine_image_ref.Name(), description=args.description, sourceInstance=source_instance.SelfLink()) csek_keys = csek_utils.CsekKeyStore.FromArgs( args, self._ALLOW_RSA_ENCRYPTED_CSEK_KEYS) if csek_keys: machine_image.machineImageEncryptionKey = csek_utils.MaybeToMessage( csek_keys.LookupKey( machine_image_ref, raise_if_missing=args.require_csek_key_create), client.apitools_client) machine_image.machineImageEncryptionKey = kms_utils.MaybeGetKmsKey( args, client.messages, machine_image.machineImageEncryptionKey) if args.IsSpecified('storage_location'): machine_image.storageLocations = [args.storage_location] if args.IsSpecified('guest_flush'): machine_image.guestFlush = args.guest_flush source_csek_keys = getattr(args, 'source_disk_csek_key', []) disk_keys = {} if source_csek_keys: for key in source_csek_keys: disk_url = key.get('disk') disk_ref = holder.resources.Parse(disk_url, collection='compute.disks', params={ 'project': source_instance.project, 'zone': source_instance.project }) key_store = csek_utils.CsekKeyStore.FromFile( key.get('csek-key-file'), self._ALLOW_RSA_ENCRYPTED_CSEK_KEYS) disk_key = csek_utils.MaybeToMessage( key_store.LookupKey(disk_ref), client.apitools_client) disk_keys[disk_url] = disk_key source_disk_messages = [] if disk_keys: for disk, key in disk_keys.items(): source_disk_message = client.messages.SourceDiskEncryptionKey( sourceDisk=disk, diskEncryptionKey=key) source_disk_messages.append(source_disk_message) if source_disk_messages: machine_image.sourceDiskEncryptionKeys = source_disk_messages request = client.messages.ComputeMachineImagesInsertRequest( machineImage=machine_image, project=machine_image_ref.project) return client.MakeRequests([(client.apitools_client.machineImages, 'Insert', request)])