def _CreateDiskMessages(self,
                         holder,
                         args,
                         boot_disk_size_gb,
                         image_uri,
                         project,
                         match_container_mount_disks=False):
   """Creates API messages with disks attached to VM instance."""
   container_mount_disk = (
       args.container_mount_disk if match_container_mount_disks else [])
   persistent_disks = (
       instance_template_utils.CreatePersistentAttachedDiskMessages(
           holder.client.messages,
           args.disk or [],
           container_mount_disk=container_mount_disk))
   boot_disk_list = [
       instance_template_utils.CreateDefaultBootAttachedDiskMessage(
           messages=holder.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)
   ]
   persistent_create_disks = (
       instance_template_utils.CreatePersistentCreateDiskMessages(
           holder.client,
           holder.resources,
           project,
           getattr(args, 'create_disk', []),
           container_mount_disk=container_mount_disk))
   local_nvdimms = create_utils.CreateLocalNvdimmMessages(
       args,
       holder.resources,
       holder.client.messages,
   )
   local_ssds = create_utils.CreateLocalSsdMessages(
       args,
       holder.resources,
       holder.client.messages,
   )
   return (boot_disk_list + persistent_disks + persistent_create_disks +
           local_nvdimms + local_ssds)
Beispiel #2
0
def _RunCreate(compute_api,
               args,
               support_source_instance,
               support_kms=False,
               support_min_node_cpu=False,
               support_confidential_compute=False,
               support_location_hint=False,
               support_private_ipv6_google_access=False):
    """Common routine for creating instance template.

  This is shared between various release tracks.

  Args:
      compute_api: The compute api.
      args: argparse.Namespace, An object that contains the values for the
        arguments specified in the .Args() method.
      support_source_instance: indicates whether source instance is supported.
      support_kms: Indicate whether KMS is integrated or not.
      support_min_node_cpu: Indicate whether the --min-node-cpu flag for
        sole tenancy overcommit is supported.
      support_confidential_compute: Indicate whether confidential compute is
        supported.
      support_location_hint: Indicate whether location hint is supported.
      support_private_ipv6_google_access: Indicate whether private ipv6 google
        access is supported.

  Returns:
      A resource object dispatched by display.Displayer().
  """
    _ValidateInstancesFlags(args, support_kms=support_kms)
    instances_flags.ValidateNetworkTierArgs(args)

    instance_templates_flags.ValidateMeshModeFlags(args)

    client = compute_api.client

    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, compute_api.resources))

    AddScopesForMeshMode(args)
    AddMeshArgsToMetadata(args)

    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=compute_api.resources,
                scope_lister=flags.GetDefaultScopeLister(client),
                messages=client.messages,
                network_interface_arg=args.network_interface,
                region=args.region)
    else:
        network_tier = getattr(args, 'network_tier', None)
        network_interfaces = [
            instance_template_utils.CreateNetworkInterfaceMessage(
                resources=compute_api.resources,
                scope_lister=flags.GetDefaultScopeLister(client),
                messages=client.messages,
                network=args.network,
                private_ip=args.private_network_ip,
                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=network_tier)
        ]

    # Compute the shieldedInstanceConfig message.
    shieldedinstance_config_message = BuildShieldedInstanceConfigMessage(
        messages=client.messages, args=args)

    if support_confidential_compute:
        confidential_instance_config_message = (
            BuildConfidentialInstanceConfigMessage(messages=client.messages,
                                                   args=args))

    node_affinities = sole_tenancy_util.GetSchedulingNodeAffinityListFromArgs(
        args, client.messages)

    min_node_cpu = None
    if support_min_node_cpu and args.IsSpecified('min_node_cpu'):
        min_node_cpu = args.min_node_cpu

    location_hint = None
    if support_location_hint and args.IsSpecified('location_hint'):
        location_hint = args.location_hint

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

    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,
                                                   compute_api.resources)
        try:
            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)
        except utils.ImageNotFoundError as e:
            if args.IsSpecified('image_project'):
                raise e
            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=False)
            raise utils.ImageNotFoundError(
                'The resource [{}] was not found. Is the image located in another '
                'project? Use the --image-project flag to specify the '
                'project where the image is located.'.format(image_uri))
    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,
            compute_api.resources,
            instance_template_ref.project,
            getattr(args, 'create_disk', []),
            support_kms=support_kms))

    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,
                kms_args=args,
                support_kms=support_kms)
        ]
    else:
        boot_disk_list = []

    local_nvdimms = create_utils.CreateLocalNvdimmMessages(
        args,
        compute_api.resources,
        client.messages,
    )

    local_ssds = create_utils.CreateLocalSsdMessages(
        args,
        compute_api.resources,
        client.messages,
    )

    disks = (boot_disk_list + persistent_disks + persistent_create_disks +
             local_nvdimms + 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),
        vm_type=getattr(args, 'custom_vm_type', None))

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

    instance_template = client.messages.InstanceTemplate(
        properties=client.messages.InstanceProperties(
            machineType=machine_type,
            disks=disks,
            canIpForward=args.can_ip_forward,
            metadata=metadata,
            minCpuPlatform=args.min_cpu_platform,
            networkInterfaces=network_interfaces,
            serviceAccounts=service_accounts,
            scheduling=scheduling,
            tags=tags,
            guestAccelerators=guest_accelerators,
        ),
        description=args.description,
        name=instance_template_ref.Name(),
    )

    instance_template.properties.shieldedInstanceConfig = shieldedinstance_config_message

    instance_template.properties.reservationAffinity = instance_utils.GetReservationAffinity(
        args, client)

    if support_confidential_compute:
        instance_template.properties.confidentialInstanceConfig = (
            confidential_instance_config_message)

    if (support_private_ipv6_google_access
            and args.private_ipv6_google_access_type is not None):
        instance_template.properties.privateIpv6GoogleAccess = (
            instances_flags.
            GetPrivateIpv6GoogleAccessTypeFlagMapperForTemplate(
                client.messages).GetEnumForChoice(
                    args.private_ipv6_google_access_type))

    request = client.messages.ComputeInstanceTemplatesInsertRequest(
        instanceTemplate=instance_template,
        project=instance_template_ref.project)

    request.instanceTemplate.properties.labels = ParseCreateArgsWithMeshMode(
        args, client.messages.InstanceProperties.LabelsValue)

    _AddSourceInstanceToTemplate(compute_api, args, instance_template,
                                 support_source_instance)

    return client.MakeRequests([(client.apitools_client.instanceTemplates,
                                 'Insert', request)])
def _RunCreate(compute_api,
               args,
               support_source_instance,
               support_kms=False,
               support_post_key_revocation_action_type=False,
               support_multi_writer=False,
               support_mesh=False,
               support_host_error_timeout_seconds=False,
               support_numa_node_count=False,
               support_visible_core_count=False,
               support_disk_architecture=False,
               support_key_revocation_action_type=False,
               support_max_run_duration=False):
  """Common routine for creating instance template.

  This is shared between various release tracks.

  Args:
      compute_api: The compute api.
      args: argparse.Namespace, An object that contains the values for the
        arguments specified in the .Args() method.
      support_source_instance: indicates whether source instance is supported.
      support_kms: Indicate whether KMS is integrated or not.
      support_post_key_revocation_action_type: Indicate whether
        post_key_revocation_action_type is supported.
      support_multi_writer: Indicates whether a disk can have multiple writers.
      support_mesh: Indicates whether adding VM to a Anthos Service Mesh is
        supported.
      support_host_error_timeout_seconds: Indicate the timeout in seconds for
        host error detection.
      support_numa_node_count: Indicates whether setting NUMA node count is
        supported.
      support_visible_core_count: Indicates whether setting a custom visible
      support_disk_architecture: Storage resources can be used to create boot
        disks compatible with ARM64 or X86_64 machine architectures. If this
        field is not specified, the default is ARCHITECTURE_UNSPECIFIED.
      support_key_revocation_action_type: Indicate whether
        key_revocation_action_type is supported.
      support_max_run_duration: Indicate whether max-run-duration or
        termination-time issupported.

  Returns:
      A resource object dispatched by display.Displayer().
  """
  _ValidateInstancesFlags(
      args,
      support_kms=support_kms,
      support_max_run_duration=support_max_run_duration)
  instances_flags.ValidateNetworkTierArgs(args)

  instance_templates_flags.ValidateServiceProxyFlags(args)
  if support_mesh:
    instance_templates_flags.ValidateMeshFlag(args)

  client = compute_api.client

  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, compute_api.resources))

  AddScopesForServiceProxy(args)
  AddServiceProxyArgsToMetadata(args)

  if hasattr(args, 'network_interface') and args.network_interface:
    network_interfaces = (
        instance_template_utils.CreateNetworkInterfaceMessages)(
            resources=compute_api.resources,
            scope_lister=flags.GetDefaultScopeLister(client),
            messages=client.messages,
            network_interface_arg=args.network_interface,
            region=args.region)
  else:
    network_tier = getattr(args, 'network_tier', None)
    stack_type = getattr(args, 'stack_type', None)
    ipv6_network_tier = getattr(args, 'ipv6_network_tier', None)
    network_interfaces = [
        instance_template_utils.CreateNetworkInterfaceMessage(
            resources=compute_api.resources,
            scope_lister=flags.GetDefaultScopeLister(client),
            messages=client.messages,
            network=args.network,
            private_ip=args.private_network_ip,
            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=network_tier,
            stack_type=stack_type,
            ipv6_network_tier=ipv6_network_tier)
    ]

  if support_mesh:
    ConfigureMeshTemplate(args, instance_template_ref, network_interfaces)

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

  # Compute the shieldedInstanceConfig message.
  shieldedinstance_config_message = BuildShieldedInstanceConfigMessage(
      messages=client.messages, args=args)

  confidential_instance_config_message = (
      BuildConfidentialInstanceConfigMessage(
          messages=client.messages, args=args))

  node_affinities = sole_tenancy_util.GetSchedulingNodeAffinityListFromArgs(
      args, client.messages)

  location_hint = None
  if args.IsSpecified('location_hint'):
    location_hint = args.location_hint

  provisioning_model = None
  if (hasattr(args, 'provisioning_model') and
      args.IsSpecified('provisioning_model')):
    provisioning_model = args.provisioning_model

  termination_action = None
  if (hasattr(args, 'instance_termination_action') and
      args.IsSpecified('instance_termination_action')):
    termination_action = args.instance_termination_action

  max_run_duration = None
  if (hasattr(args, 'max_run_duration') and
      args.IsSpecified('max_run_duration')):
    max_run_duration = args.max_run_duration

  termination_time = None
  if (hasattr(args, 'termination_time') and
      args.IsSpecified('termination_time')):
    termination_time = args.termination_time

  host_error_timeout_seconds = None
  if support_host_error_timeout_seconds and args.IsSpecified(
      'host_error_timeout_seconds'):
    host_error_timeout_seconds = args.host_error_timeout_seconds
  scheduling = instance_utils.CreateSchedulingMessage(
      messages=client.messages,
      maintenance_policy=args.maintenance_policy,
      preemptible=args.preemptible,
      restart_on_failure=args.restart_on_failure,
      node_affinities=node_affinities,
      min_node_cpu=args.min_node_cpu,
      location_hint=location_hint,
      provisioning_model=provisioning_model,
      instance_termination_action=termination_action,
      host_error_timeout_seconds=host_error_timeout_seconds,
      max_run_duration=max_run_duration,
      termination_time=termination_time)

  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 []) +
                                         (args.create_disk or [])))
  if create_boot_disk:
    image_expander = image_utils.ImageExpander(client, compute_api.resources)
    try:
      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)
    except utils.ImageNotFoundError as e:
      if args.IsSpecified('image_project'):
        raise e
      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=False)
      raise utils.ImageNotFoundError(
          'The resource [{}] was not found. Is the image located in another '
          'project? Use the --image-project flag to specify the '
          'project where the image is located.'.format(image_uri))
  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,
          compute_api.resources,
          instance_template_ref.project,
          getattr(args, 'create_disk', []),
          support_kms=support_kms,
          support_multi_writer=support_multi_writer,
          support_disk_architecture=support_disk_architecture))

  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,
            kms_args=args,
            support_kms=support_kms,
            disk_provisioned_iops=args.boot_disk_provisioned_iops)
    ]
  else:
    boot_disk_list = []

  local_nvdimms = create_utils.CreateLocalNvdimmMessages(
      args,
      compute_api.resources,
      client.messages,
  )

  local_ssds = create_utils.CreateLocalSsdMessages(
      args,
      compute_api.resources,
      client.messages,
  )

  disks = (
      boot_disk_list + persistent_disks + persistent_create_disks +
      local_nvdimms + 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),
      vm_type=getattr(args, 'custom_vm_type', None))

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

  instance_template = client.messages.InstanceTemplate(
      properties=client.messages.InstanceProperties(
          machineType=machine_type,
          disks=disks,
          canIpForward=args.can_ip_forward,
          metadata=metadata,
          minCpuPlatform=args.min_cpu_platform,
          networkInterfaces=network_interfaces,
          serviceAccounts=service_accounts,
          scheduling=scheduling,
          tags=tags,
          guestAccelerators=guest_accelerators,
      ),
      description=args.description,
      name=instance_template_ref.Name(),
  )

  instance_template.properties.shieldedInstanceConfig = shieldedinstance_config_message

  instance_template.properties.reservationAffinity = instance_utils.GetReservationAffinity(
      args, client)

  instance_template.properties.confidentialInstanceConfig = (
      confidential_instance_config_message)

  if args.IsSpecified('network_performance_configs'):
    instance_template.properties.networkPerformanceConfig = (
        instance_utils.GetNetworkPerformanceConfig(args, client))

  if args.IsSpecified('resource_policies'):
    instance_template.properties.resourcePolicies = getattr(
        args, 'resource_policies', [])

  if support_post_key_revocation_action_type and args.IsSpecified(
      'post_key_revocation_action_type'):
    instance_template.properties.postKeyRevocationActionType = arg_utils.ChoiceToEnum(
        args.post_key_revocation_action_type, client.messages.InstanceProperties
        .PostKeyRevocationActionTypeValueValuesEnum)

  if support_key_revocation_action_type and args.IsSpecified(
      'key_revocation_action_type'):
    instance_template.properties.keyRevocationActionType = arg_utils.ChoiceToEnum(
        args.key_revocation_action_type, client.messages.InstanceProperties
        .KeyRevocationActionTypeValueValuesEnum)

  if args.private_ipv6_google_access_type is not None:
    instance_template.properties.privateIpv6GoogleAccess = (
        instances_flags.GetPrivateIpv6GoogleAccessTypeFlagMapperForTemplate(
            client.messages).GetEnumForChoice(
                args.private_ipv6_google_access_type))

  # Create an AdvancedMachineFeatures message if any of the features requiring
  # one have been specified.
  has_visible_core_count = (
      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
      (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_template.properties.advancedMachineFeatures = (
        instance_utils.CreateAdvancedMachineFeaturesMessage(
            client.messages, args.enable_nested_virtualization,
            args.threads_per_core,
            args.numa_node_count if support_numa_node_count else None,
            visible_core_count, args.enable_uefi_networking))

  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:
      properties = client.messages.InstanceProperties
      instance_template.properties.resourceManagerTags = properties.ResourceManagerTagsValue(
          additionalProperties=[
              properties.ResourceManagerTagsValue.AdditionalProperty(
                  key=key, value=value) for key, value in sorted(
                      six.iteritems(ret_resource_manager_tags))
          ])

  request = client.messages.ComputeInstanceTemplatesInsertRequest(
      instanceTemplate=instance_template, project=instance_template_ref.project)

  request.instanceTemplate.properties.labels = ParseCreateArgsWithServiceProxy(
      args, client.messages.InstanceProperties.LabelsValue)

  _AddSourceInstanceToTemplate(compute_api, args, instance_template,
                               support_source_instance)

  return client.MakeRequests([(client.apitools_client.instanceTemplates,
                               'Insert', request)])