Example #1
0
def CreateDefaultBootAttachedDiskMessage(messages,
                                         disk_type,
                                         disk_device_name,
                                         disk_auto_delete,
                                         disk_size_gb,
                                         image_uri,
                                         kms_args=None,
                                         support_kms=False):
    """Returns an AttachedDisk message for creating a new boot disk."""
    disk_key = None

    if support_kms:
        disk_key = kms_utils.MaybeGetKmsKey(kms_args,
                                            messages,
                                            disk_key,
                                            boot_disk_prefix=True)

    return messages.AttachedDisk(
        autoDelete=disk_auto_delete,
        boot=True,
        deviceName=disk_device_name,
        initializeParams=messages.AttachedDiskInitializeParams(
            sourceImage=image_uri, diskSizeGb=disk_size_gb,
            diskType=disk_type),
        mode=messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE,
        type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT,
        diskEncryptionKey=disk_key)
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'

        if 'scope' in disk and disk['scope'] == 'regional':
            scope = compute_scopes.ScopeEnum.REGION
        else:
            scope = compute_scopes.ScopeEnum.ZONE
        disk_ref = ParseDiskResource(resources, name, instance_ref.project,
                                     instance_ref.zone, scope)

        if boot:
            boot_disk_ref = disk_ref

        # 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 = {}

        kwargs['diskEncryptionKey'] = kms_utils.MaybeGetKmsKey(
            disk, disk_ref.project, compute,
            kwargs.get('diskEncryptionKey', None))

        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 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):
    """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_ref = None
        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

    kms_key = kms_utils.MaybeGetKmsKey(
        kms_args, instance_ref.project, compute,
        kwargs_disk.get('diskEncryptionKey', None))
    if kms_key:
        kwargs_disk = {'diskEncryptionKey': kms_key}

    return messages.AttachedDisk(
        autoDelete=disk_auto_delete,
        boot=True,
        deviceName=effective_boot_disk_name,
        initializeParams=messages.AttachedDiskInitializeParams(
            sourceImage=image_uri,
            diskSizeGb=disk_size_gb,
            diskType=disk_type_uri,
            **kwargs_init_parms),
        mode=messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE,
        type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT,
        **kwargs_disk)
Example #4
0
  def _Run(self, args, supports_kms_keys=False, supports_physical_block=False,
           support_shared_disk=False, support_vss_erase=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'))
    if self.source_disk_enabled:
      self.show_unformated_message = self.show_unformated_message and not (
          args.IsSpecified('source_disk'))

    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))

      # 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)
      if self.source_disk_enabled:
        source_disk_ref = self.GetSourceDiskUri(args, compute_holder)
        disk.sourceDisk = source_disk_ref
      if (support_shared_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_shared_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 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)
Example #5
0
    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)])
Example #6
0
  def Run(self, args):
    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))
    # end of alpha/beta features.

    guest_os_feature_messages = self.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

      kwargs['diskEncryptionKey'] = kms_utils.MaybeGetKmsKey(
          args, disk_ref.project, client.apitools_client,
          kwargs.get('diskEncryptionKey', None))

      # 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)
Example #7
0
    def _Run(self, args, supports_kms_keys=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)
        if supports_kms_keys:
            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)

        # 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)])
Example #8
0
    def _Run(self,
             args,
             support_user_licenses=False,
             support_disk_architecture=False):
        """Returns a list of requests necessary for adding images."""
        holder = self._GetApiHolder()
        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)

        if support_disk_architecture and args.IsSpecified('architecture'):
            image.architecture = messages.Image.ArchitectureValueValuesEnum(
                args.architecture)

        if support_user_licenses and args.IsSpecified('user_licenses'):
            image.userLicenses = args.user_licenses
        csek_keys = csek_utils.CsekKeyStore.FromArgs(args, True)
        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.InvalidArgumentException(
                '--source-disk-zone',
                'You cannot specify [--source-disk-zone] unless you are specifying '
                '[--source-disk].')

        if args.source_disk_project and not args.source_disk:
            raise exceptions.InvalidArgumentException(
                'source_disk_project',
                'You cannot specify [source_disk_project] 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.InvalidArgumentException(
                '--source-image-project',
                '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 = six.text_type(
                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),
                source_project=args.source_disk_project)
            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

        initial_state, has_set =\
            image_utils.CreateInitialStateConfig(args, messages)
        if has_set:
            image.shieldedInstanceInitialState = initial_state

        if args.IsSpecified('storage_location'):
            image.storageLocations = [args.storage_location]

        if hasattr(image, 'locked'):
            image.locked = args.locked
        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)],
            timeout=POLL_TIMEOUT)
Example #9
0
    def _CreateRequests(self, args, instance_refs, project, zone,
                        compute_client, resource_parser, holder):
        # gcloud creates default values for some fields in Instance resource
        # when no value was specified on command line.
        # When --source-instance-template was specified, defaults are taken from
        # Instance Template and gcloud flags are used to override them - by default
        # fields should not be initialized.
        source_instance_template = self.GetSourceInstanceTemplate(
            args, resource_parser)
        skip_defaults = source_instance_template is not None

        source_machine_image = self.GetSourceMachineImage(
            args, resource_parser)
        skip_defaults = skip_defaults or source_machine_image is not None

        scheduling = instance_utils.GetScheduling(
            args,
            compute_client,
            skip_defaults,
            support_node_affinity=True,
            support_node_project=self._support_node_project,
            support_host_error_timeout_seconds=self.
            _support_host_error_timeout_seconds,
            support_max_run_duration=self._support_max_run_duration)
        tags = instance_utils.GetTags(args, compute_client)
        labels = instance_utils.GetLabels(args, compute_client)
        metadata = instance_utils.GetMetadata(args, compute_client,
                                              skip_defaults)
        boot_disk_size_gb = instance_utils.GetBootDiskSizeGb(args)

        network_interfaces = create_utils.GetNetworkInterfacesWithValidation(
            args=args,
            resource_parser=resource_parser,
            compute_client=compute_client,
            holder=holder,
            project=project,
            location=zone,
            scope=compute_scopes.ScopeEnum.ZONE,
            skip_defaults=skip_defaults,
            support_public_dns=self._support_public_dns,
            support_ipv6_assignment=self._support_ipv6_assignment)

        confidential_vm = (args.IsSpecified('confidential_compute')
                           and args.confidential_compute)

        create_boot_disk = not (
            instance_utils.UseExistingBootDisk((args.disk or []) +
                                               (args.create_disk or [])))

        image_uri = create_utils.GetImageUri(
            args,
            compute_client,
            create_boot_disk,
            project,
            resource_parser,
            confidential_vm,
            image_family_scope=args.image_family_scope,
            support_image_family_scope=True)

        shielded_instance_config = create_utils.BuildShieldedInstanceConfigMessage(
            messages=compute_client.messages, args=args)

        confidential_instance_config = (
            create_utils.BuildConfidentialInstanceConfigMessage(
                messages=compute_client.messages, args=args))

        csek_keys = csek_utils.CsekKeyStore.FromArgs(
            args, self._support_rsa_encrypted)

        project_to_sa = create_utils.GetProjectToServiceAccountMap(
            args, instance_refs, compute_client, skip_defaults)

        requests = []
        for instance_ref in instance_refs:

            disks = []
            if create_utils.CheckSpecifiedDiskArgs(
                    args=args,
                    skip_defaults=skip_defaults,
                    support_kms=self._support_kms):
                disks = create_utils.CreateDiskMessages(
                    args=args,
                    instance_name=instance_ref.Name(),
                    project=instance_ref.project,
                    location=instance_ref.zone,
                    scope=compute_scopes.ScopeEnum.ZONE,
                    compute_client=compute_client,
                    resource_parser=resource_parser,
                    boot_disk_size_gb=boot_disk_size_gb,
                    image_uri=image_uri,
                    create_boot_disk=create_boot_disk,
                    csek_keys=csek_keys,
                    holder=holder,
                    support_kms=self._support_kms,
                    support_nvdimm=self._support_nvdimm,
                    support_source_snapshot_csek=self.
                    _support_source_snapshot_csek,
                    support_boot_snapshot_uri=self._support_boot_snapshot_uri,
                    support_image_csek=self._support_image_csek,
                    support_create_disk_snapshots=self.
                    _support_create_disk_snapshots,
                    support_replica_zones=self._support_replica_zones,
                    support_multi_writer=self._support_multi_writer,
                    support_disk_architecture=self._support_disk_architecture)

            machine_type_uri = None
            if instance_utils.CheckSpecifiedMachineTypeArgs(
                    args, skip_defaults):
                machine_type_uri = instance_utils.CreateMachineTypeUri(
                    args=args,
                    compute_client=compute_client,
                    resource_parser=resource_parser,
                    project=instance_ref.project,
                    location=instance_ref.zone,
                    scope=compute_scopes.ScopeEnum.ZONE,
                    confidential_vm=confidential_vm)

            can_ip_forward = instance_utils.GetCanIpForward(
                args, skip_defaults)
            guest_accelerators = create_utils.GetAccelerators(
                args=args,
                compute_client=compute_client,
                resource_parser=resource_parser,
                project=instance_ref.project,
                location=instance_ref.zone,
                scope=compute_scopes.ScopeEnum.ZONE)

            instance = compute_client.messages.Instance(
                canIpForward=can_ip_forward,
                deletionProtection=args.deletion_protection,
                description=args.description,
                disks=disks,
                guestAccelerators=guest_accelerators,
                hostname=args.hostname,
                labels=labels,
                machineType=machine_type_uri,
                metadata=metadata,
                minCpuPlatform=args.min_cpu_platform,
                name=instance_ref.Name(),
                networkInterfaces=network_interfaces,
                serviceAccounts=project_to_sa[instance_ref.project],
                scheduling=scheduling,
                tags=tags)

            if self._support_instance_kms and args.CONCEPTS.instance_kms_key:
                instance.instanceEncryptionKey = kms_utils.MaybeGetKmsKey(
                    args,
                    compute_client.messages,
                    instance.instanceEncryptionKey,
                    instance_prefix=True)

            if self._support_secure_tag and args.secure_tags:
                instance.secureTags = secure_tags_utils.GetSecureTags(
                    args.secure_tags)

            if args.resource_manager_tags:
                ret_resource_manager_tags = resource_manager_tags_utils.GetResourceManagerTags(
                    args.resource_manager_tags)
                if ret_resource_manager_tags is not None:
                    params = compute_client.messages.InstanceParams
                    instance.params = params(
                        resourceManagerTags=params.ResourceManagerTagsValue(
                            additionalProperties=[
                                params.ResourceManagerTagsValue.
                                AdditionalProperty(key=key, value=value)
                                for key, value in sorted(
                                    six.iteritems(ret_resource_manager_tags))
                            ]))

            if args.private_ipv6_google_access_type is not None:
                instance.privateIpv6GoogleAccess = (
                    instances_flags.GetPrivateIpv6GoogleAccessTypeFlagMapper(
                        compute_client.messages).GetEnumForChoice(
                            args.private_ipv6_google_access_type))

            has_visible_core_count = (self._support_visible_core_count
                                      and args.visible_core_count is not None)
            if (args.enable_nested_virtualization is not None
                    or args.threads_per_core is not None
                    or (self._support_numa_node_count
                        and args.numa_node_count is not None)
                    or has_visible_core_count
                    or args.enable_uefi_networking is not None):
                visible_core_count = args.visible_core_count if has_visible_core_count else None
                instance.advancedMachineFeatures = (
                    instance_utils.CreateAdvancedMachineFeaturesMessage(
                        compute_client.messages,
                        args.enable_nested_virtualization,
                        args.threads_per_core, args.numa_node_count
                        if self._support_numa_node_count else None,
                        visible_core_count, args.enable_uefi_networking))

            resource_policies = getattr(args, 'resource_policies', None)
            if resource_policies:
                parsed_resource_policies = []
                for policy in resource_policies:
                    resource_policy_ref = maintenance_util.ParseResourcePolicyWithZone(
                        resource_parser,
                        policy,
                        project=instance_ref.project,
                        zone=instance_ref.zone)
                    parsed_resource_policies.append(
                        resource_policy_ref.SelfLink())
                instance.resourcePolicies = parsed_resource_policies

            if shielded_instance_config:
                instance.shieldedInstanceConfig = shielded_instance_config

            if confidential_instance_config:
                instance.confidentialInstanceConfig = confidential_instance_config

            if self._support_erase_vss and args.IsSpecified(
                    'erase_windows_vss_signature'):
                instance.eraseWindowsVssSignature = args.erase_windows_vss_signature

            if self._support_post_key_revocation_action_type and args.IsSpecified(
                    'post_key_revocation_action_type'):
                instance.postKeyRevocationActionType = arg_utils.ChoiceToEnum(
                    args.post_key_revocation_action_type,
                    compute_client.messages.Instance.
                    PostKeyRevocationActionTypeValueValuesEnum)

            if self._support_key_revocation_action_type and args.IsSpecified(
                    'key_revocation_action_type'):
                instance.keyRevocationActionType = arg_utils.ChoiceToEnum(
                    args.key_revocation_action_type, compute_client.messages.
                    Instance.KeyRevocationActionTypeValueValuesEnum)

            if args.IsSpecified('network_performance_configs'):
                instance.networkPerformanceConfig = instance_utils.GetNetworkPerformanceConfig(
                    args, compute_client)

            request = compute_client.messages.ComputeInstancesInsertRequest(
                instance=instance,
                project=instance_ref.project,
                zone=instance_ref.zone)

            if source_instance_template:
                request.sourceInstanceTemplate = source_instance_template

            if source_machine_image:
                request.instance.sourceMachineImage = source_machine_image
                if args.IsSpecified('source_machine_image_csek_key_file'):
                    key = instance_utils.GetSourceMachineImageKey(
                        args, self.SOURCE_MACHINE_IMAGE, compute_client,
                        holder)
                    request.instance.sourceMachineImageEncryptionKey = key

            if self._support_machine_image_key and args.IsSpecified(
                    'source_machine_image_csek_key_file'):
                if not args.IsSpecified('source_machine_image'):
                    raise exceptions.RequiredArgumentException(
                        '`--source-machine-image`',
                        '`--source-machine-image-csek-key-file` requires '
                        '`--source-machine-image` to be specified`')

            if args.IsSpecified('enable_display_device'):
                request.instance.displayDevice = compute_client.messages.DisplayDevice(
                    enableDisplay=args.enable_display_device)

            request.instance.reservationAffinity = instance_utils.GetReservationAffinity(
                args, compute_client)

            requests.append(
                (compute_client.apitools_client.instances, 'Insert', request))
        return requests