Exemple #1
0
  def Run(self, args):
    instances_flags.ValidateDiskFlags(
        args, enable_kms=self.ReleaseTrack() in [base.ReleaseTrack.ALPHA])
    instances_flags.ValidateLocalSsdFlags(args)
    instances_flags.ValidateNicFlags(args)
    instances_flags.ValidateServiceAccountAndScopeArgs(args)
    instances_flags.ValidateAcceleratorArgs(args)
    if self._support_network_tier:
      instances_flags.ValidateNetworkTierArgs(args)

    holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
    compute_client = holder.client
    resource_parser = holder.resources

    instance_refs = instances_flags.INSTANCES_ARG.ResolveAsResource(
        args, resource_parser,
        scope_lister=flags.GetDefaultScopeLister(compute_client))

    requests = self._CreateRequests(args, instance_refs,
                                    compute_client, resource_parser)

    if not args.async:
      # TODO(b/63664449): Replace this with poller + progress tracker.
      try:
        # Using legacy MakeRequests (which also does polling) here until
        # replaced by api_lib.utils.waiter.
        return compute_client.MakeRequests(requests)
      except exceptions.ToolException as e:
        invalid_machine_type_message_regex = (
            r'Invalid value for field \'resource.machineType\': .+. '
            r'Machine type with name \'.+\' does not exist in zone \'.+\'\.')
        if re.search(invalid_machine_type_message_regex, e.message):
          raise exceptions.ToolException(
              e.message +
              '\nUse `gcloud compute machine-types list --zones` to see the '
              'available machine  types.')
        raise

    errors_to_collect = []
    responses = compute_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]

    for instance_ref, operation_ref in zip(instance_refs, operation_refs):
      log.status.Print('Instance creation in progress for [{}]: {}'
                       .format(instance_ref.instance, operation_ref.SelfLink()))
    log.status.Print('Use [gcloud compute operations describe URI] command '
                     'to check the status of the operation(s).')
    if not args.IsSpecified('format'):
      # For async output we need a separate format. Since we already printed in
      # the status messages information about operations there is nothing else
      # needs to be printed.
      args.format = 'disable'
    return responses
def _ValidateInstancesFlags(
    args,
    support_kms=False,
    support_max_run_duration=False
):
  """Validate flags for instance template that affects instance creation.

  Args:
      args: argparse.Namespace, An object that contains the values for the
        arguments specified in the .Args() method.
      support_kms: If KMS is supported.
      support_max_run_duration: max-run-durrations is supported in instance
        scheduling.
  """
  instances_flags.ValidateDiskCommonFlags(args)
  instances_flags.ValidateDiskBootFlags(args, enable_kms=support_kms)
  instances_flags.ValidateCreateDiskFlags(args)
  instances_flags.ValidateLocalSsdFlags(args)
  instances_flags.ValidateNicFlags(args)
  instances_flags.ValidateServiceAccountAndScopeArgs(args)
  instances_flags.ValidateAcceleratorArgs(args)
  instances_flags.ValidateReservationAffinityGroup(args)
  instances_flags.ValidateNetworkPerformanceConfigsArgs(args)
  instances_flags.ValidateInstanceScheduling(
      args, support_max_run_duration=support_max_run_duration)
Exemple #3
0
    def Run(self, args):
        instances_flags.ValidateBulkDiskFlags(
            args,
            enable_snapshots=True,
            enable_source_snapshot_csek=self._support_source_snapshot_csek,
            enable_image_csek=self._support_image_csek)
        instances_flags.ValidateImageFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        instances_flags.ValidateAcceleratorArgs(args)
        instances_flags.ValidateNetworkTierArgs(args)
        instances_flags.ValidateReservationAffinityGroup(args)

        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        compute_client = holder.client
        resource_parser = holder.resources

        project = properties.VALUES.core.project.GetOrFail()
        location = None
        scope = None

        if args.IsSpecified('zone'):
            location = args.zone
            scope = compute_scopes.ScopeEnum.ZONE
        elif args.IsSpecified('region'):
            location = args.region
            scope = compute_scopes.ScopeEnum.REGION

        instances_service, request = self._CreateRequests(
            args, holder, compute_client, resource_parser, project, location,
            scope)

        self._errors = []
        self._log_async = False
        self._status_message = None

        if args.async_:
            self._log_async = True
            try:
                response = instances_service.BulkInsert(request)
                self._operation_selflink = response.selfLink
                return
            except exceptions.HttpError as error:
                raise error

        errors_to_collect = []
        response = compute_client.MakeRequests(
            [(instances_service, 'BulkInsert', request)],
            errors_to_collect=errors_to_collect,
            log_result=False,
            always_return_operation=True,
            no_followup=True)

        self._errors = errors_to_collect
        if response:
            self._status_message = response[0].statusMessage

        return
 def _ValidateBetaArgs(self, args):
     instances_flags.ValidateKonletArgs(args)
     instances_flags.ValidateDiskCommonFlags(args)
     instances_flags.ValidateLocalSsdFlags(args)
     instances_flags.ValidateServiceAccountAndScopeArgs(args)
     if instance_utils.UseExistingBootDisk(args.disk or []):
         raise exceptions.InvalidArgumentException(
             '--disk', 'Boot disk specified for containerized VM.')
Exemple #5
0
    def Run(self, args):
        instances_flags.ValidateDiskFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        instances_flags.ValidateAcceleratorArgs(args)

        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        compute_client = holder.client
        resource_parser = holder.resources

        requests = self._CreateRequests(args, compute_client, resource_parser)
        return compute_client.MakeRequests(requests)
Exemple #6
0
def _ValidateInstancesFlags(args):
    """Validate flags for instance template that affects instance creation.

  Args:
      args: argparse.Namespace, An object that contains the values for the
          arguments specified in the .Args() method.
  """
    instances_flags.ValidateDiskCommonFlags(args)
    instances_flags.ValidateDiskBootFlags(args)
    instances_flags.ValidateCreateDiskFlags(args)
    instances_flags.ValidateLocalSsdFlags(args)
    instances_flags.ValidateNicFlags(args)
    instances_flags.ValidateServiceAccountAndScopeArgs(args)
    instances_flags.ValidateAcceleratorArgs(args)
def _ValidateInstancesFlags(args, support_kms=False,):
  """Validate flags for instance template that affects instance creation.

  Args:
      args: argparse.Namespace, An object that contains the values for the
        arguments specified in the .Args() method.
      support_kms: If KMS is supported.
  """
  instances_flags.ValidateDiskCommonFlags(args)
  instances_flags.ValidateDiskBootFlags(args, enable_kms=support_kms)
  instances_flags.ValidateCreateDiskFlags(args)
  instances_flags.ValidateLocalSsdFlags(args)
  instances_flags.ValidateNicFlags(args)
  instances_flags.ValidateServiceAccountAndScopeArgs(args)
  instances_flags.ValidateAcceleratorArgs(args)
  instances_flags.ValidateReservationAffinityGroup(args)
Exemple #8
0
  def Run(self, args):
    instances_flags.ValidateDiskFlags(args)
    instances_flags.ValidateLocalSsdFlags(args)
    instances_flags.ValidateNicFlags(args)
    instances_flags.ValidateServiceAccountAndScopeArgs(args)
    instances_flags.ValidateAcceleratorArgs(args)

    holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
    compute_client = holder.client
    resource_parser = holder.resources

    requests = self._CreateRequests(args, compute_client, resource_parser)
    try:
      return compute_client.MakeRequests(requests)
    except exceptions.ToolException as e:
      invalid_machine_type_message_regex = (
          r'Invalid value for field \'resource.machineType\': .+. '
          r'Machine type with name \'.+\' does not exist in zone \'.+\'\.')
      if re.search(invalid_machine_type_message_regex, e.message):
        raise exceptions.ToolException(
            e.message +
            '\nUse `gcloud compute machine-types list --zones` to see the '
            'available machine  types.')
      raise
Exemple #9
0
    def Run(self, args):
        instances_flags.ValidateDiskFlags(
            args,
            enable_kms=self._support_kms,
            enable_snapshots=True,
            enable_source_snapshot_csek=self._support_source_snapshot_csek,
            enable_image_csek=self._support_image_csek)
        instances_flags.ValidateImageFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        instances_flags.ValidateAcceleratorArgs(args)
        instances_flags.ValidateNetworkTierArgs(args)
        instances_flags.ValidateReservationAffinityGroup(args)

        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        compute_client = holder.client
        resource_parser = holder.resources

        instance_refs = instance_utils.GetInstanceRefs(args, compute_client,
                                                       holder)

        requests = self._CreateRequests(args, instance_refs,
                                        instance_refs[0].project,
                                        instance_refs[0].zone, compute_client,
                                        resource_parser, holder)
        if not args.async_:
            # TODO(b/63664449): Replace this with poller + progress tracker.
            try:
                # Using legacy MakeRequests (which also does polling) here until
                # replaced by api_lib.utils.waiter.
                return compute_client.MakeRequests(requests)
            except exceptions.ToolException as e:
                invalid_machine_type_message_regex = (
                    r'Invalid value for field \'resource.machineType\': .+. '
                    r'Machine type with name \'.+\' does not exist in zone \'.+\'\.'
                )
                if re.search(invalid_machine_type_message_regex,
                             six.text_type(e)):
                    raise exceptions.ToolException(
                        six.text_type(e) +
                        '\nUse `gcloud compute machine-types list --zones` to see the '
                        'available machine  types.')
                raise

        errors_to_collect = []
        responses = compute_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
        ]

        log.status.Print(
            'NOTE: The users will be charged for public IPs when VMs '
            'are created.')

        for instance_ref, operation_ref in zip(instance_refs, operation_refs):
            log.status.Print(
                'Instance creation in progress for [{}]: {}'.format(
                    instance_ref.instance, operation_ref.SelfLink()))
        log.status.Print(
            'Use [gcloud compute operations describe URI] command '
            'to check the status of the operation(s).')
        if not args.IsSpecified('format'):
            # For async output we need a separate format. Since we already printed in
            # the status messages information about operations there is nothing else
            # needs to be printed.
            args.format = 'disable'
        return responses
    def CreateRequests(self, args):
        instances_flags.ValidateDockerArgs(args)
        instances_flags.ValidateDiskCommonFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        if instance_utils.UseExistingBootDisk(args.disk or []):
            raise exceptions.InvalidArgumentException(
                '--disk', 'Boot disk specified for containerized VM.')

        scheduling = instance_utils.CreateSchedulingMessage(
            messages=self.messages,
            maintenance_policy=args.maintenance_policy,
            preemptible=args.preemptible,
            restart_on_failure=args.restart_on_failure)

        service_accounts = instance_utils.CreateServiceAccountMessages(
            messages=self.messages,
            scopes=([] if args.no_scopes else args.scopes))

        user_metadata = metadata_utils.ConstructMetadataMessage(
            self.messages,
            metadata=args.metadata,
            metadata_from_file=args.metadata_from_file)
        containers_utils.ValidateUserMetadata(user_metadata)

        boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
        utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

        instance_refs = instances_flags.INSTANCES_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(instance_refs)

        network_interface = instance_utils.CreateNetworkInterfaceMessage(
            resources=self.resources,
            compute_client=self.compute_client,
            network=args.network,
            subnet=args.subnet,
            private_network_ip=args.private_network_ip,
            no_address=args.no_address,
            address=args.address,
            instance_refs=instance_refs)

        machine_type_uris = instance_utils.CreateMachineTypeUris(
            resources=self.resources,
            compute_client=self.compute_client,
            project=self.project,
            machine_type=args.machine_type,
            custom_cpu=args.custom_cpu,
            custom_memory=args.custom_memory,
            instance_refs=instance_refs)

        image_uri = containers_utils.ExpandGciImageFlag(self.compute_client)
        requests = []
        for instance_ref, machine_type_uri in zip(instance_refs,
                                                  machine_type_uris):
            metadata = containers_utils.CreateMetadataMessage(
                self.messages, args.run_as_privileged, args.container_manifest,
                args.docker_image, args.port_mappings, args.run_command,
                user_metadata, instance_ref.Name())
            requests.append(
                self.messages.ComputeInstancesInsertRequest(
                    instance=self.messages.Instance(
                        canIpForward=args.can_ip_forward,
                        disks=(self._CreateDiskMessages(
                            args, boot_disk_size_gb, image_uri, instance_ref)),
                        description=args.description,
                        machineType=machine_type_uri,
                        metadata=metadata,
                        name=instance_ref.Name(),
                        networkInterfaces=[network_interface],
                        serviceAccounts=service_accounts,
                        scheduling=scheduling,
                        tags=containers_utils.CreateTagsMessage(
                            self.messages, args.tags),
                    ),
                    project=self.project,
                    zone=instance_ref.zone))
        return requests
 def _ValidateArgs(self, args):
   super(CreateWithContainerBeta, self)._ValidateArgs(args)
   instances_flags.ValidateLocalSsdFlags(args)
  def CreateRequests(self, args):
    """Creates and returns an InstanceTemplates.Insert request.

    Args:
      args: the argparse arguments that this command was invoked with.

    Returns:
      request: a ComputeInstanceTemplatesInsertRequest message object
    """
    instances_flags.ValidateDockerArgs(args)
    instances_flags.ValidateDiskCommonFlags(args)
    instances_flags.ValidateLocalSsdFlags(args)
    instances_flags.ValidateServiceAccountAndScopeArgs(args)
    if instance_utils.UseExistingBootDisk(args.disk or []):
      raise exceptions.InvalidArgumentException(
          '--disk',
          'Boot disk specified for containerized VM.')

    boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
    utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

    instance_template_ref = (
        CreateFromContainer.InstanceTemplateArg.ResolveAsResource(
            args, self.resources))

    user_metadata = metadata_utils.ConstructMetadataMessage(
        self.messages,
        metadata=args.metadata,
        metadata_from_file=args.metadata_from_file)
    containers_utils.ValidateUserMetadata(user_metadata)

    network_interface = instance_template_utils.CreateNetworkInterfaceMessage(
        resources=self.resources,
        scope_lister=flags.GetDefaultScopeLister(self.compute_client),
        messages=self.messages,
        network=args.network,
        region=args.region,
        subnet=args.subnet,
        address=(instance_template_utils.EPHEMERAL_ADDRESS
                 if not args.no_address and not args.address
                 else args.address))

    scheduling = instance_utils.CreateSchedulingMessage(
        messages=self.messages,
        maintenance_policy=args.maintenance_policy,
        preemptible=args.preemptible,
        restart_on_failure=args.restart_on_failure)

    if args.no_service_account:
      service_account = None
    else:
      service_account = args.service_account
    service_accounts = instance_utils.CreateServiceAccountMessages(
        messages=self.messages,
        scopes=[] if args.no_scopes else args.scopes,
        service_account=service_account)

    image_uri = containers_utils.ExpandCosImageFlag(self.compute_client)

    machine_type = instance_utils.InterpretMachineType(
        machine_type=args.machine_type,
        custom_cpu=args.custom_cpu,
        custom_memory=args.custom_memory,
        ext=getattr(args, 'custom_extensions', None))

    metadata = containers_utils.CreateMetadataMessage(
        self.messages, args.run_as_privileged, args.container_manifest,
        args.docker_image, args.port_mappings, args.run_command,
        user_metadata, instance_template_ref.Name())

    request = self.messages.ComputeInstanceTemplatesInsertRequest(
        instanceTemplate=self.messages.InstanceTemplate(
            properties=self.messages.InstanceProperties(
                machineType=machine_type,
                disks=self._CreateDiskMessages(args, boot_disk_size_gb,
                                               image_uri,
                                               instance_template_ref.project),
                canIpForward=args.can_ip_forward,
                metadata=metadata,
                minCpuPlatform=args.min_cpu_platform,
                networkInterfaces=[network_interface],
                serviceAccounts=service_accounts,
                scheduling=scheduling,
                tags=containers_utils.CreateTagsMessage(
                    self.messages, args.tags),
            ),
            description=args.description,
            name=instance_template_ref.Name(),
        ),
        project=instance_template_ref.project)

    return [request]
 def _ValidateTrackSpecificArgs(self, args):
     instances_flags.ValidateLocalSsdFlags(args)
     instances_flags.ValidatePublicDnsFlags(args)
     instances_flags.ValidatePublicPtrFlags(args)
Exemple #14
0
    def Run(self, args):
        """Creates and runs an InstanceTemplates.Insert request.

    Args:
      args: argparse.Namespace, An object that contains the values for the
          arguments specified in the .Args() method.

    Returns:
      A resource object dispatched by display.Displayer().
    """
        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        client = holder.client

        self.ValidateDiskFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        instances_flags.ValidateAcceleratorArgs(args)

        boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
        utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

        instance_template_ref = (Create.InstanceTemplateArg.ResolveAsResource(
            args, holder.resources))

        metadata = metadata_utils.ConstructMetadataMessage(
            client.messages,
            metadata=args.metadata,
            metadata_from_file=args.metadata_from_file)

        if hasattr(args, 'network_interface') and args.network_interface:
            network_interfaces = (
                instance_template_utils.CreateNetworkInterfaceMessages)(
                    resources=holder.resources,
                    scope_lister=flags.GetDefaultScopeLister(client),
                    messages=client.messages,
                    network_interface_arg=args.network_interface,
                    region=args.region)
        else:
            network_interfaces = [
                instance_template_utils.CreateNetworkInterfaceMessage(
                    resources=holder.resources,
                    scope_lister=flags.GetDefaultScopeLister(client),
                    messages=client.messages,
                    network=args.network,
                    region=args.region,
                    subnet=args.subnet,
                    address=(instance_template_utils.EPHEMERAL_ADDRESS
                             if not args.no_address and not args.address else
                             args.address))
            ]

        scheduling = instance_utils.CreateSchedulingMessage(
            messages=client.messages,
            maintenance_policy=args.maintenance_policy,
            preemptible=args.preemptible,
            restart_on_failure=args.restart_on_failure)

        if args.no_service_account:
            service_account = None
        else:
            service_account = args.service_account
        service_accounts = instance_utils.CreateServiceAccountMessages(
            messages=client.messages,
            scopes=[] if args.no_scopes else args.scopes,
            service_account=service_account)

        create_boot_disk = not instance_utils.UseExistingBootDisk(args.disk
                                                                  or [])
        if create_boot_disk:
            image_expander = image_utils.ImageExpander(client,
                                                       holder.resources)
            image_uri, _ = image_expander.ExpandImageFlag(
                user_project=instance_template_ref.project,
                image=args.image,
                image_family=args.image_family,
                image_project=args.image_project,
                return_image_resource=True)
        else:
            image_uri = None

        if args.tags:
            tags = client.messages.Tags(items=args.tags)
        else:
            tags = None

        persistent_disks = (
            instance_template_utils.CreatePersistentAttachedDiskMessages(
                client.messages, args.disk or []))

        persistent_create_disks = (
            instance_template_utils.CreatePersistentCreateDiskMessages(
                client, holder.resources, instance_template_ref.project,
                getattr(args, 'create_disk', [])))

        if create_boot_disk:
            boot_disk_list = [
                instance_template_utils.CreateDefaultBootAttachedDiskMessage(
                    messages=client.messages,
                    disk_type=args.boot_disk_type,
                    disk_device_name=args.boot_disk_device_name,
                    disk_auto_delete=args.boot_disk_auto_delete,
                    disk_size_gb=boot_disk_size_gb,
                    image_uri=image_uri)
            ]
        else:
            boot_disk_list = []

        local_ssds = []
        for x in args.local_ssd or []:
            local_ssd = instance_utils.CreateLocalSsdMessage(
                holder.resources, client.messages, x.get('device-name'),
                x.get('interface'), x.get('size'))
            local_ssds.append(local_ssd)

        disks = (boot_disk_list + persistent_disks + persistent_create_disks +
                 local_ssds)

        machine_type = instance_utils.InterpretMachineType(
            machine_type=args.machine_type,
            custom_cpu=args.custom_cpu,
            custom_memory=args.custom_memory,
            ext=getattr(args, 'custom_extensions', None))

        guest_accelerators = (
            instance_template_utils.CreateAcceleratorConfigMessages(
                client.messages, getattr(args, 'accelerator', None)))

        instance_properties = client.messages.InstanceProperties(
            machineType=machine_type,
            disks=disks,
            canIpForward=args.can_ip_forward,
            metadata=metadata,
            networkInterfaces=network_interfaces,
            serviceAccounts=service_accounts,
            scheduling=scheduling,
            tags=tags,
        )

        # TODO(b/36890961): Pass this directly into guestAccelerators once GA.
        if guest_accelerators:
            instance_properties.guestAccelerators = guest_accelerators

        request = client.messages.ComputeInstanceTemplatesInsertRequest(
            instanceTemplate=client.messages.InstanceTemplate(
                properties=instance_properties,
                description=args.description,
                name=instance_template_ref.Name(),
            ),
            project=instance_template_ref.project)

        if getattr(args, 'min_cpu_platform', None):
            request.instanceTemplate.properties.minCpuPlatform = args.min_cpu_platform

        return client.MakeRequests([(client.apitools_client.instanceTemplates,
                                     'Insert', request)])
Exemple #15
0
  def CreateRequests(self, args):
    instances_flags.ValidateDiskFlags(args)
    instances_flags.ValidateLocalSsdFlags(args)
    instances_flags.ValidateNicFlags(args)

    # This feature is only exposed in alpha/beta
    allow_rsa_encrypted = self.ReleaseTrack() in [base.ReleaseTrack.ALPHA,
                                                  base.ReleaseTrack.BETA]
    self.csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted)

    scheduling = instance_utils.CreateSchedulingMessage(
        messages=self.messages,
        maintenance_policy=args.maintenance_policy,
        preemptible=args.preemptible,
        restart_on_failure=args.restart_on_failure)

    service_accounts = instance_utils.CreateServiceAccountMessages(
        messages=self.messages,
        scopes=([] if args.no_scopes else args.scopes))

    if args.tags:
      tags = self.messages.Tags(items=args.tags)
    else:
      tags = None

    metadata = metadata_utils.ConstructMetadataMessage(
        self.messages,
        metadata=args.metadata,
        metadata_from_file=args.metadata_from_file)

    # If the user already provided an initial Windows password and
    # username through metadata, then there is no need to check
    # whether the image or the boot disk is Windows.

    boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
    utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

    instance_refs = instances_flags.INSTANCES_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(instance_refs)

    if hasattr(args, 'network_interface') and args.network_interface:
      network_interfaces = instance_utils.CreateNetworkInterfaceMessages(
          resources=self.resources,
          compute_client=self.compute_client,
          network_interface_arg=args.network_interface,
          instance_refs=instance_refs)
    else:
      network_interfaces = [
          instance_utils.CreateNetworkInterfaceMessage(
              resources=self.resources,
              compute_client=self.compute_client,
              network=args.network,
              subnet=args.subnet,
              private_network_ip=args.private_network_ip,
              no_address=args.no_address,
              address=args.address,
              instance_refs=instance_refs)
      ]

    machine_type_uris = instance_utils.CreateMachineTypeUris(
        resources=self.resources,
        compute_client=self.compute_client,
        project=self.project,
        machine_type=args.machine_type,
        custom_cpu=args.custom_cpu,
        custom_memory=args.custom_memory,
        instance_refs=instance_refs)

    create_boot_disk = not instance_utils.UseExistingBootDisk(args.disk or [])
    if create_boot_disk:
      image_uri, _ = self.ExpandImageFlag(
          image=args.image,
          image_family=args.image_family,
          image_project=args.image_project,
          return_image_resource=False)
    else:
      image_uri = None

    # A list of lists where the element at index i contains a list of
    # disk messages that should be set for the instance at index i.
    disks_messages = []

    # A mapping of zone to boot disk references for all existing boot
    # disks that are being attached.
    # TODO(user): Simplify this once resources.Resource becomes
    # hashable.
    existing_boot_disks = {}

    for instance_ref in instance_refs:
      persistent_disks, boot_disk_ref = (
          instance_utils.CreatePersistentAttachedDiskMessages(
              self.resources, self.compute_client, self.csek_keys,
              args.disk or [], instance_ref))
      persistent_create_disks = (
          instance_utils.CreatePersistentCreateDiskMessages(
              self,
              self.compute_client,
              self.resources,
              self.csek_keys,
              getattr(args, 'create_disk', []),
              instance_ref))
      local_ssds = []
      for x in args.local_ssd or []:
        local_ssds.append(
            instance_utils.CreateLocalSsdMessage(
                self.resources,
                self.messages,
                x.get('device-name'),
                x.get('interface'),
                instance_ref.zone)
        )

      if create_boot_disk:
        boot_disk = instance_utils.CreateDefaultBootAttachedDiskMessage(
            self.compute_client, self.resources,
            disk_type=args.boot_disk_type,
            disk_device_name=args.boot_disk_device_name,
            disk_auto_delete=args.boot_disk_auto_delete,
            disk_size_gb=boot_disk_size_gb,
            require_csek_key_create=(
                args.require_csek_key_create if self.csek_keys else None),
            image_uri=image_uri,
            instance_ref=instance_ref,
            csek_keys=self.csek_keys)
        persistent_disks = [boot_disk] + persistent_disks
      else:
        existing_boot_disks[boot_disk_ref.zone] = boot_disk_ref
      disks_messages.append(persistent_disks + persistent_create_disks +
                            local_ssds)

    requests = []
    for instance_ref, machine_type_uri, disks in zip(
        instance_refs, machine_type_uris, disks_messages):
      requests.append(self.messages.ComputeInstancesInsertRequest(
          instance=self.messages.Instance(
              canIpForward=args.can_ip_forward,
              disks=disks,
              description=args.description,
              machineType=machine_type_uri,
              metadata=metadata,
              name=instance_ref.Name(),
              networkInterfaces=network_interfaces,
              serviceAccounts=service_accounts,
              scheduling=scheduling,
              tags=tags,
          ),
          project=self.project,
          zone=instance_ref.zone))

    return requests
Exemple #16
0
 def _ValidateTrackSpecificArgs(self, args):
     instances_flags.ValidateLocalSsdFlags(args)
    def Run(self, args):
        """Issues an InstanceTemplates.Insert request.

    Args:
      args: the argparse arguments that this command was invoked with.

    Returns:
      an InstanceTemplate message object
    """
        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        client = holder.client

        instances_flags.ValidateKonletArgs(args)
        instances_flags.ValidateDiskCommonFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        instances_flags.ValidateNetworkTierArgs(args,
                                                support_network_tier=True)
        if instance_utils.UseExistingBootDisk(args.disk or []):
            raise exceptions.InvalidArgumentException(
                '--disk', 'Boot disk specified for containerized VM.')

        boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
        utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

        instance_template_ref = (
            CreateWithContainer.InstanceTemplateArg.ResolveAsResource(
                args, holder.resources))

        user_metadata = metadata_utils.ConstructMetadataMessage(
            client.messages,
            metadata=args.metadata,
            metadata_from_file=args.metadata_from_file)
        containers_utils.ValidateUserMetadata(user_metadata)

        network_interface = instance_template_utils.CreateNetworkInterfaceMessage(
            resources=holder.resources,
            scope_lister=flags.GetDefaultScopeLister(client),
            messages=client.messages,
            network=args.network,
            region=args.region,
            subnet=args.subnet,
            address=(instance_template_utils.EPHEMERAL_ADDRESS
                     if not args.no_address and not args.address else
                     args.address),
            network_tier=getattr(args, 'network_tier', None))

        scheduling = instance_utils.CreateSchedulingMessage(
            messages=client.messages,
            maintenance_policy=args.maintenance_policy,
            preemptible=args.preemptible,
            restart_on_failure=args.restart_on_failure)

        if args.no_service_account:
            service_account = None
        else:
            service_account = args.service_account
        service_accounts = instance_utils.CreateServiceAccountMessages(
            messages=client.messages,
            scopes=[] if args.no_scopes else args.scopes,
            service_account=service_account)

        if (args.IsSpecified('image') or args.IsSpecified('image_family')
                or args.IsSpecified('image_project')):
            image_expander = image_utils.ImageExpander(client,
                                                       holder.resources)
            image_uri, _ = image_expander.ExpandImageFlag(
                user_project=instance_template_ref.project,
                image=args.image,
                image_family=args.image_family,
                image_project=args.image_project)
            if holder.resources.Parse(image_uri).project != 'cos-cloud':
                log.warn(
                    'This container deployment mechanism requires a '
                    'Container-Optimized OS image in order to work. Select an '
                    'image from a cos-cloud project (cost-stable, cos-beta, '
                    'cos-dev image families).')
        else:
            image_uri = containers_utils.ExpandKonletCosImageFlag(client)

        machine_type = instance_utils.InterpretMachineType(
            machine_type=args.machine_type,
            custom_cpu=args.custom_cpu,
            custom_memory=args.custom_memory,
            ext=getattr(args, 'custom_extensions', None))

        metadata = containers_utils.CreateKonletMetadataMessage(
            client.messages, args, instance_template_ref.Name(), user_metadata)

        request = client.messages.ComputeInstanceTemplatesInsertRequest(
            instanceTemplate=client.messages.InstanceTemplate(
                properties=client.messages.InstanceProperties(
                    machineType=machine_type,
                    disks=self._CreateDiskMessages(
                        holder, args, boot_disk_size_gb, image_uri,
                        instance_template_ref.project),
                    canIpForward=args.can_ip_forward,
                    metadata=metadata,
                    minCpuPlatform=args.min_cpu_platform,
                    networkInterfaces=[network_interface],
                    serviceAccounts=service_accounts,
                    scheduling=scheduling,
                    tags=containers_utils.CreateTagsMessage(
                        client.messages, args.tags),
                ),
                description=args.description,
                name=instance_template_ref.Name(),
            ),
            project=instance_template_ref.project)

        return client.MakeRequests([(client.apitools_client.instanceTemplates,
                                     'Insert', request)])
    def CreateRequests(self, args):
        instances_flags.ValidateDockerArgs(args)
        instances_flags.ValidateDiskCommonFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        if instance_utils.UseExistingBootDisk(args.disk or []):
            raise exceptions.InvalidArgumentException(
                '--disk', 'Boot disk specified for containerized VM.')

        scheduling = instance_utils.CreateSchedulingMessage(
            messages=self.messages,
            maintenance_policy=args.maintenance_policy,
            preemptible=args.preemptible,
            restart_on_failure=args.restart_on_failure)

        if args.no_service_account:
            service_account = None
        else:
            service_account = args.service_account
        service_accounts = instance_utils.CreateServiceAccountMessages(
            messages=self.messages,
            scopes=[] if args.no_scopes else args.scopes,
            service_account=service_account)

        user_metadata = metadata_utils.ConstructMetadataMessage(
            self.messages,
            metadata=args.metadata,
            metadata_from_file=args.metadata_from_file)
        containers_utils.ValidateUserMetadata(user_metadata)

        boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
        utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

        instance_refs = instances_flags.INSTANCES_ARG.ResolveAsResource(
            args,
            self.resources,
            scope_lister=flags.GetDefaultScopeLister(self.compute_client,
                                                     self.project))

        # Check if the zone is deprecated or has maintenance coming.
        zone_resource_fetcher = zone_utils.ZoneResourceFetcher(
            self.compute_client)
        zone_resource_fetcher.WarnForZonalCreation(instance_refs)

        instances_flags.ValidatePublicDnsFlags(args)

        network_interface = instance_utils.CreateNetworkInterfaceMessage(
            resources=self.resources,
            compute_client=self.compute_client,
            network=args.network,
            subnet=args.subnet,
            private_network_ip=args.private_network_ip,
            no_address=args.no_address,
            address=args.address,
            instance_refs=instance_refs,
            network_tier=args.network_tier,
            no_public_dns=getattr(args, 'no_public_dns', None),
            public_dns=getattr(args, 'public_dns', None),
            no_public_ptr=getattr(args, 'no_public_ptr', None),
            public_ptr=getattr(args, 'public_ptr', None),
            no_public_ptr_domain=getattr(args, 'no_public_ptr_domain', None),
            public_ptr_domain=getattr(args, 'public_ptr_domain', None))

        machine_type_uris = instance_utils.CreateMachineTypeUris(
            resources=self.resources,
            compute_client=self.compute_client,
            project=self.project,
            machine_type=args.machine_type,
            custom_cpu=args.custom_cpu,
            custom_memory=args.custom_memory,
            ext=getattr(args, 'custom_extensions', None),
            instance_refs=instance_refs)

        image_uri = containers_utils.ExpandCosImageFlag(self.compute_client)

        args_labels = getattr(args, 'labels', None)
        labels = None
        if args_labels:
            labels = self.messages.Instance.LabelsValue(additionalProperties=[
                self.messages.Instance.LabelsValue.AdditionalProperty(
                    key=key, value=value)
                for key, value in sorted(args.labels.iteritems())
            ])

        requests = []
        for instance_ref, machine_type_uri in zip(instance_refs,
                                                  machine_type_uris):
            metadata = containers_utils.CreateMetadataMessage(
                self.messages, args.run_as_privileged, args.container_manifest,
                args.docker_image, args.port_mappings, args.run_command,
                user_metadata, instance_ref.Name())
            request = self.messages.ComputeInstancesInsertRequest(
                instance=self.messages.Instance(
                    canIpForward=args.can_ip_forward,
                    disks=(self._CreateDiskMessages(args, boot_disk_size_gb,
                                                    image_uri, instance_ref)),
                    description=args.description,
                    machineType=machine_type_uri,
                    metadata=metadata,
                    minCpuPlatform=args.min_cpu_platform,
                    name=instance_ref.Name(),
                    networkInterfaces=[network_interface],
                    serviceAccounts=service_accounts,
                    scheduling=scheduling,
                    tags=containers_utils.CreateTagsMessage(
                        self.messages, args.tags),
                ),
                project=self.project,
                zone=instance_ref.zone)
            if labels:
                request.instance.labels = labels
            requests.append(request)

        return requests
Exemple #19
0
  def _CreateRequests(self, args):
    instances_flags.ValidateDiskFlags(args)
    instances_flags.ValidateLocalSsdFlags(args)
    instances_flags.ValidateNicFlags(args)
    instances_flags.ValidateServiceAccountAndScopeArgs(args)
    instances_flags.ValidateAcceleratorArgs(args)

    # This feature is only exposed in alpha/beta
    allow_rsa_encrypted = self.ReleaseTrack() in [base.ReleaseTrack.ALPHA,
                                                  base.ReleaseTrack.BETA]
    self.csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted)

    scheduling = instance_utils.CreateSchedulingMessage(
        messages=self.messages,
        maintenance_policy=args.maintenance_policy,
        preemptible=args.preemptible,
        restart_on_failure=args.restart_on_failure)

    if args.tags:
      tags = self.messages.Tags(items=args.tags)
    else:
      tags = None

    metadata = metadata_utils.ConstructMetadataMessage(
        self.messages,
        metadata=args.metadata,
        metadata_from_file=args.metadata_from_file)

    # If the user already provided an initial Windows password and
    # username through metadata, then there is no need to check
    # whether the image or the boot disk is Windows.

    boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
    utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

    instance_refs = instances_flags.INSTANCES_ARG.ResolveAsResource(
        args, self.resources, scope_lister=flags.GetDefaultScopeLister(
            self.compute_client, self.project))

    # Check if the zone is deprecated or has maintenance coming.
    zone_resource_fetcher = zone_utils.ZoneResourceFetcher(self.compute_client)
    zone_resource_fetcher.WarnForZonalCreation(instance_refs)

    network_interface_arg = getattr(args, 'network_interface', None)
    if network_interface_arg:
      network_interfaces = instance_utils.CreateNetworkInterfaceMessages(
          resources=self.resources,
          compute_client=self.compute_client,
          network_interface_arg=network_interface_arg,
          instance_refs=instance_refs,
          support_network_tier=self._support_network_tier)
    else:
      if self._support_public_dns is True:
        instances_flags.ValidatePublicDnsFlags(args)

      network_tier = getattr(args, 'network_tier', None)

      network_interfaces = [
          instance_utils.CreateNetworkInterfaceMessage(
              resources=self.resources,
              compute_client=self.compute_client,
              network=args.network,
              subnet=args.subnet,
              private_network_ip=args.private_network_ip,
              no_address=args.no_address,
              address=args.address,
              instance_refs=instance_refs,
              network_tier=network_tier,
              no_public_dns=getattr(args, 'no_public_dns', None),
              public_dns=getattr(args, 'public_dns', None),
              no_public_ptr=getattr(args, 'no_public_ptr', None),
              public_ptr=getattr(args, 'public_ptr', None),
              no_public_ptr_domain=getattr(args, 'no_public_ptr_domain', None),
              public_ptr_domain=getattr(args, 'public_ptr_domain', None))
      ]

    machine_type_uris = instance_utils.CreateMachineTypeUris(
        resources=self.resources,
        compute_client=self.compute_client,
        project=self.project,
        machine_type=args.machine_type,
        custom_cpu=args.custom_cpu,
        custom_memory=args.custom_memory,
        ext=getattr(args, 'custom_extensions', None),
        instance_refs=instance_refs)

    create_boot_disk = not instance_utils.UseExistingBootDisk(args.disk or [])
    if create_boot_disk:
      image_expander = image_utils.ImageExpander(self.compute_client,
                                                 self.resources)
      image_uri, _ = image_expander.ExpandImageFlag(
          user_project=self.project,
          image=args.image,
          image_family=args.image_family,
          image_project=args.image_project,
          return_image_resource=False)
    else:
      image_uri = None

    # A list of lists where the element at index i contains a list of
    # disk messages that should be set for the instance at index i.
    disks_messages = []

    # A mapping of zone to boot disk references for all existing boot
    # disks that are being attached.
    # TODO(user): Simplify this once resources.Resource becomes
    # hashable.
    existing_boot_disks = {}

    for instance_ref in instance_refs:
      persistent_disks, boot_disk_ref = (
          instance_utils.CreatePersistentAttachedDiskMessages(
              self.resources, self.compute_client, self.csek_keys,
              args.disk or [], instance_ref))
      persistent_create_disks = (
          instance_utils.CreatePersistentCreateDiskMessages(
              self,
              self.compute_client,
              self.resources,
              self.csek_keys,
              getattr(args, 'create_disk', []),
              instance_ref))
      local_ssds = []
      for x in args.local_ssd or []:
        local_ssds.append(
            instance_utils.CreateLocalSsdMessage(
                self.resources,
                self.messages,
                x.get('device-name'),
                x.get('interface'),
                instance_ref.zone)
        )

      if create_boot_disk:
        boot_disk = instance_utils.CreateDefaultBootAttachedDiskMessage(
            self.compute_client, self.resources,
            disk_type=args.boot_disk_type,
            disk_device_name=args.boot_disk_device_name,
            disk_auto_delete=args.boot_disk_auto_delete,
            disk_size_gb=boot_disk_size_gb,
            require_csek_key_create=(
                args.require_csek_key_create if self.csek_keys else None),
            image_uri=image_uri,
            instance_ref=instance_ref,
            csek_keys=self.csek_keys)
        persistent_disks = [boot_disk] + persistent_disks
      else:
        existing_boot_disks[boot_disk_ref.zone] = boot_disk_ref
      disks_messages.append(persistent_disks + persistent_create_disks +
                            local_ssds)

    accelerator_args = getattr(args, 'accelerator', None)

    project_to_sa = {}
    requests = []
    for instance_ref, machine_type_uri, disks in zip(
        instance_refs, machine_type_uris, disks_messages):
      if instance_ref.project not in project_to_sa:
        scopes = None
        if not args.no_scopes and not args.scopes:
          # User didn't provide any input on scopes. If project has no default
          # service account then we want to create a VM with no scopes
          request = (self.compute.projects,
                     'Get',
                     self.messages.ComputeProjectsGetRequest(
                         project=instance_ref.project))
          errors = []
          result = self.compute_client.MakeRequests([request], errors)
          if not errors:
            if not result[0].defaultServiceAccount:
              scopes = []
              log.status.Print(
                  'There is no default service account for project {}. '
                  'Instance {} will not have scopes.'.format(
                      instance_ref.project, instance_ref.Name))
        if scopes is None:
          scopes = [] if args.no_scopes else args.scopes

        if args.no_service_account:
          service_account = None
        else:
          service_account = args.service_account
        service_accounts = instance_utils.CreateServiceAccountMessages(
            messages=self.messages,
            scopes=scopes,
            service_account=service_account)
        project_to_sa[instance_ref.project] = service_accounts

      instance = self.messages.Instance(
          canIpForward=args.can_ip_forward,
          disks=disks,
          description=args.description,
          machineType=machine_type_uri,
          metadata=metadata,
          name=instance_ref.Name(),
          networkInterfaces=network_interfaces,
          serviceAccounts=project_to_sa[instance_ref.project],
          scheduling=scheduling,
          tags=tags)
      if getattr(args, 'min_cpu_platform', None):
        instance.minCpuPlatform = args.min_cpu_platform
      if accelerator_args:
        accelerator_type_name = accelerator_args['type']
        accelerator_type_ref = self.resources.Parse(
            accelerator_type_name,
            collection='compute.acceleratorTypes',
            params={'project': instance_ref.project,
                    'zone': instance_ref.zone})
        # Accelerator count is default to 1.
        accelerator_count = int(accelerator_args.get('count', 1))
        accelerators = instance_utils.CreateAcceleratorConfigMessages(
            self.compute_client.messages, accelerator_type_ref,
            accelerator_count)
        instance.guestAccelerators = accelerators

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

      sole_tenancy_host_arg = getattr(args, 'sole_tenancy_host', None)
      if sole_tenancy_host_arg:
        sole_tenancy_host_ref = self.resources.Parse(
            sole_tenancy_host_arg, collection='compute.hosts',
            params={'zone': instance_ref.zone})
        request.instance.host = sole_tenancy_host_ref.SelfLink()
      requests.append((self.compute.instances, 'Insert', request))
    return requests
Exemple #20
0
 def _ValidateTrackSpecificArgs(self, args):
     instances_flags.ValidateLocalSsdFlags(args)
     instances_flags.ValidatePublicDnsFlags(args)
     instances_flags.ValidatePublicPtrFlags(args)
     instances_flags.ValidateNetworkPerformanceConfigsArgs(args)
    def Run(self, args):
        """Runs bulk create command.

    Args:
      args: argparse.Namespace, An object that contains the values for the
        arguments specified in the .Args() method.

    Returns:
      A resource object dispatched by display.Displayer().
    """

        instances_flags.ValidateBulkCreateArgs(args)
        if self._support_enable_target_shape:
            instances_flags.ValidateBulkTargetShapeArgs(args)
        instances_flags.ValidateLocationPolicyArgs(args)
        instances_flags.ValidateBulkDiskFlags(
            args,
            enable_source_snapshot_csek=self._support_source_snapshot_csek,
            enable_image_csek=self._support_image_csek)
        instances_flags.ValidateImageFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        instances_flags.ValidateAcceleratorArgs(args)
        instances_flags.ValidateNetworkTierArgs(args)
        instances_flags.ValidateReservationAffinityGroup(args)
        instances_flags.ValidateNetworkPerformanceConfigsArgs(args)
        instances_flags.ValidateInstanceScheduling(
            args, support_max_run_duration=self._support_max_run_duration)

        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        compute_client = holder.client
        resource_parser = holder.resources

        project = properties.VALUES.core.project.GetOrFail()
        location = None
        scope = None

        if args.IsSpecified('zone'):
            location = args.zone
            scope = compute_scopes.ScopeEnum.ZONE
        elif args.IsSpecified('region'):
            location = args.region
            scope = compute_scopes.ScopeEnum.REGION

        instances_service, request = self._CreateRequests(
            args, holder, compute_client, resource_parser, project, location,
            scope)

        self._errors = []
        self._log_async = False
        self._status_message = None

        if args.async_:
            self._log_async = True
            try:
                response = instances_service.BulkInsert(request)
                self._operation_selflink = response.selfLink
                return {'operationGroupId': response.operationGroupId}
            except exceptions.HttpException as error:
                raise error

        errors_to_collect = []
        response = compute_client.MakeRequests(
            [(instances_service, 'BulkInsert', request)],
            errors_to_collect=errors_to_collect,
            log_result=False,
            always_return_operation=True,
            no_followup=True)

        self._errors = errors_to_collect
        if response:
            operation_group_id = response[0].operationGroupId
            result = _GetResult(compute_client, request, operation_group_id)
            if result['createdInstanceCount'] is not None and result[
                    'failedInstanceCount'] is not None:
                self._status_message = 'VM instances created: {}, failed: {}.'.format(
                    result['createdInstanceCount'],
                    result['failedInstanceCount'])
            return result
        return
Exemple #22
0
    def CreateRequests(self, args):
        """Creates and returns an InstanceTemplates.Insert request.

    Args:
      args: the argparse arguments that this command was invoked with.

    Returns:
      request: a ComputeInstanceTemplatesInsertRequest message object
    """
        self.ValidateDiskFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)

        boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
        utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

        instance_template_ref = (
            instance_templates_flags.INSTANCE_TEMPLATE_ARG.ResolveAsResource(
                args, self.resources))

        metadata = metadata_utils.ConstructMetadataMessage(
            self.messages,
            metadata=args.metadata,
            metadata_from_file=args.metadata_from_file)

        if hasattr(args, 'network_interface') and args.network_interface:
            network_interfaces = (
                instance_template_utils.CreateNetworkInterfaceMessages)(
                    scope_prompter=self,
                    messages=self.messages,
                    network_interface_arg=args.network_interface,
                    region=args.region)
        else:
            network_interfaces = [
                instance_template_utils.CreateNetworkInterfaceMessage(
                    scope_prompter=self,
                    messages=self.messages,
                    network=args.network,
                    region=args.region,
                    subnet=args.subnet,
                    address=(instance_template_utils.EPHEMERAL_ADDRESS
                             if not args.no_address and not args.address else
                             args.address))
            ]

        scheduling = instance_utils.CreateSchedulingMessage(
            messages=self.messages,
            maintenance_policy=args.maintenance_policy,
            preemptible=args.preemptible,
            restart_on_failure=args.restart_on_failure)

        service_accounts = instance_utils.CreateServiceAccountMessages(
            messages=self.messages,
            scopes=([] if args.no_scopes else args.scopes))

        create_boot_disk = not instance_utils.UseExistingBootDisk(args.disk
                                                                  or [])
        if create_boot_disk:
            image_uri, _ = self.ExpandImageFlag(
                image=args.image,
                image_family=args.image_family,
                image_project=args.image_project,
                return_image_resource=True)
        else:
            image_uri = None

        if args.tags:
            tags = self.messages.Tags(items=args.tags)
        else:
            tags = None

        persistent_disks = (
            instance_template_utils.CreatePersistentAttachedDiskMessages(
                self.messages, args.disk or []))

        persistent_create_disks = (
            instance_template_utils.CreatePersistentCreateDiskMessages(
                self, self.messages, getattr(args, 'create_disk', [])))

        if create_boot_disk:
            boot_disk_list = [
                instance_template_utils.CreateDefaultBootAttachedDiskMessage(
                    messages=self.messages,
                    disk_type=args.boot_disk_type,
                    disk_device_name=args.boot_disk_device_name,
                    disk_auto_delete=args.boot_disk_auto_delete,
                    disk_size_gb=boot_disk_size_gb,
                    image_uri=image_uri)
            ]
        else:
            boot_disk_list = []

        local_ssds = []
        for x in args.local_ssd or []:
            local_ssd = instance_utils.CreateLocalSsdMessage(
                self.resources, self.messages, x.get('device-name'),
                x.get('interface'))
            local_ssds.append(local_ssd)

        disks = (boot_disk_list + persistent_disks + persistent_create_disks +
                 local_ssds)

        machine_type = instance_utils.InterpretMachineType(
            machine_type=args.machine_type,
            custom_cpu=args.custom_cpu,
            custom_memory=args.custom_memory)

        request = self.messages.ComputeInstanceTemplatesInsertRequest(
            instanceTemplate=self.messages.InstanceTemplate(
                properties=self.messages.InstanceProperties(
                    machineType=machine_type,
                    disks=disks,
                    canIpForward=args.can_ip_forward,
                    metadata=metadata,
                    networkInterfaces=network_interfaces,
                    serviceAccounts=service_accounts,
                    scheduling=scheduling,
                    tags=tags,
                ),
                description=args.description,
                name=instance_template_ref.Name(),
            ),
            project=self.project)

        return [request]
Exemple #23
0
    def Run(self, args):
        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        client = holder.client

        source_instance_template = self.GetSourceInstanceTemplate(
            args, holder.resources)
        # 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.
        skip_defaults = source_instance_template is not None

        instances_flags.ValidateDockerArgs(args)
        instances_flags.ValidateDiskCommonFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        if instance_utils.UseExistingBootDisk(args.disk or []):
            raise exceptions.InvalidArgumentException(
                '--disk', 'Boot disk specified for containerized VM.')

        if (skip_defaults and not args.IsSpecified('maintenance_policy')
                and not args.IsSpecified('preemptible')
                and not args.IsSpecified('restart_on_failure')):
            scheduling = None
        else:
            scheduling = instance_utils.CreateSchedulingMessage(
                messages=client.messages,
                maintenance_policy=args.maintenance_policy,
                preemptible=args.preemptible,
                restart_on_failure=args.restart_on_failure)

        if args.no_service_account:
            service_account = None
        else:
            service_account = args.service_account
        if (skip_defaults and not args.IsSpecified('scopes')
                and not args.IsSpecified('no_scopes')
                and not args.IsSpecified('service_account')
                and not args.IsSpecified('no_service_account')):
            service_accounts = []
        else:
            service_accounts = instance_utils.CreateServiceAccountMessages(
                messages=client.messages,
                scopes=[] if args.no_scopes else args.scopes,
                service_account=service_account)

        user_metadata = metadata_utils.ConstructMetadataMessage(
            client.messages,
            metadata=args.metadata,
            metadata_from_file=args.metadata_from_file)
        containers_utils.ValidateUserMetadata(user_metadata)

        boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
        utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

        instance_refs = instances_flags.INSTANCES_ARG.ResolveAsResource(
            args,
            holder.resources,
            scope_lister=flags.GetDefaultScopeLister(client))

        # Check if the zone is deprecated or has maintenance coming.
        zone_resource_fetcher = zone_utils.ZoneResourceFetcher(client)
        zone_resource_fetcher.WarnForZonalCreation(instance_refs)

        instances_flags.ValidatePublicDnsFlags(args)

        if (skip_defaults and not args.IsSpecified('network')
                and not args.IsSpecified('subnet')
                and not args.IsSpecified('private_network_ip')
                and not args.IsSpecified('no_address')
                and not args.IsSpecified('address')
                and not args.IsSpecified('network_tier')
                and not args.IsSpecified('no_public_dns')
                and not args.IsSpecified('public_dns')
                and not args.IsSpecified('no_public_ptr')
                and not args.IsSpecified('public_ptr')
                and not args.IsSpecified('no_public_ptr_domain')
                and not args.IsSpecified('public_ptr_domain')):
            network_interfaces = []
        else:
            network_interfaces = [
                instance_utils.CreateNetworkInterfaceMessage(
                    resources=holder.resources,
                    compute_client=client,
                    network=args.network,
                    subnet=args.subnet,
                    private_network_ip=args.private_network_ip,
                    no_address=args.no_address,
                    address=args.address,
                    instance_refs=instance_refs,
                    network_tier=args.network_tier,
                    no_public_dns=getattr(args, 'no_public_dns', None),
                    public_dns=getattr(args, 'public_dns', None),
                    no_public_ptr=getattr(args, 'no_public_ptr', None),
                    public_ptr=getattr(args, 'public_ptr', None),
                    no_public_ptr_domain=getattr(args, 'no_public_ptr_domain',
                                                 None),
                    public_ptr_domain=getattr(args, 'public_ptr_domain', None))
            ]

        if (skip_defaults and not args.IsSpecified('machine_type')
                and not args.IsSpecified('custom_cpu')
                and not args.IsSpecified('custom_memory')):
            machine_type_uris = [None for _ in instance_refs]
        else:
            machine_type_uris = instance_utils.CreateMachineTypeUris(
                resources=holder.resources,
                compute_client=client,
                machine_type=args.machine_type,
                custom_cpu=args.custom_cpu,
                custom_memory=args.custom_memory,
                ext=getattr(args, 'custom_extensions', None),
                instance_refs=instance_refs)

        image_uri = containers_utils.ExpandCosImageFlag(client)

        args_labels = getattr(args, 'labels', None)
        labels = None
        if args_labels:
            labels = client.messages.Instance.LabelsValue(
                additionalProperties=[
                    client.messages.Instance.LabelsValue.AdditionalProperty(
                        key=key, value=value)
                    for key, value in sorted(args.labels.iteritems())
                ])

        if skip_defaults and not args.IsSpecified('can_ip_forward'):
            can_ip_forward = None
        else:
            can_ip_forward = args.can_ip_forward

        requests = []
        for instance_ref, machine_type_uri in zip(instance_refs,
                                                  machine_type_uris):
            metadata = containers_utils.CreateMetadataMessage(
                client.messages, args.run_as_privileged,
                args.container_manifest, args.docker_image, args.port_mappings,
                args.run_command, user_metadata, instance_ref.Name())
            request = client.messages.ComputeInstancesInsertRequest(
                instance=client.messages.Instance(
                    canIpForward=can_ip_forward,
                    disks=(self._CreateDiskMessages(holder, args,
                                                    boot_disk_size_gb,
                                                    image_uri, instance_ref,
                                                    skip_defaults)),
                    description=args.description,
                    machineType=machine_type_uri,
                    metadata=metadata,
                    minCpuPlatform=args.min_cpu_platform,
                    name=instance_ref.Name(),
                    networkInterfaces=network_interfaces,
                    serviceAccounts=service_accounts,
                    scheduling=scheduling,
                    tags=containers_utils.CreateTagsMessage(
                        client.messages, args.tags)),
                project=instance_ref.project,
                zone=instance_ref.zone)
            if labels:
                request.instance.labels = labels
            if source_instance_template:
                request.sourceInstanceTemplate = source_instance_template

            requests.append(
                (client.apitools_client.instances, 'Insert', request))

        return client.MakeRequests(requests)