def _CreateRequests(self, args, instance_refs, compute_client, resource_parser): # gcloud creates default values for some fields in Instance resource # when no value was specified on command line. # When --source-instance-template was specified, defaults are taken from # Instance Template and gcloud flags are used to override them - by default # fields should not be initialized. source_instance_template = self.GetSourceInstanceTemplate( args, resource_parser) skip_defaults = source_instance_template is not None # 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) 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=compute_client.messages, maintenance_policy=args.maintenance_policy, preemptible=args.preemptible, restart_on_failure=args.restart_on_failure) if args.tags: tags = compute_client.messages.Tags(items=args.tags) else: tags = None labels = None args_labels = getattr(args, 'labels', None) if args_labels: labels = compute_client.messages.Instance.LabelsValue( additionalProperties=[ compute_client.messages.Instance.LabelsValue.AdditionalProperty( key=key, value=value) for key, value in sorted(args.labels.iteritems())]) if (skip_defaults and not args.IsSpecified('metadata') and not args.IsSpecified('metadata_from_file')): metadata = None else: metadata = metadata_utils.ConstructMetadataMessage( compute_client.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) # Check if the zone is deprecated or has maintenance coming. zone_resource_fetcher = zone_utils.ZoneResourceFetcher(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=resource_parser, compute_client=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) if self._support_public_ptr is True: instances_flags.ValidatePublicPtrFlags(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_tier = getattr(args, 'network_tier', None) network_interfaces = [ instance_utils.CreateNetworkInterfaceMessage( resources=resource_parser, compute_client=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)) ] 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=resource_parser, compute_client=compute_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) create_boot_disk = not instance_utils.UseExistingBootDisk(args.disk or []) if create_boot_disk: image_expander = image_utils.ImageExpander(compute_client, resource_parser) image_uri, _ = image_expander.ExpandImageFlag( user_project=instance_refs[0].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(b/36050875): Simplify since resources.Resource is now hashable. existing_boot_disks = {} if (skip_defaults and not args.IsSpecified('disk') and not args.IsSpecified('create_disk') and not args.IsSpecified('local_ssd') and not args.IsSpecified('boot_disk_type') and not args.IsSpecified('boot_disk_device_name') and not args.IsSpecified('boot_disk_auto_delete') and not args.IsSpecified('boot_disk_kms_key') and not args.IsSpecified('boot_disk_kms_project') and not args.IsSpecified('boot_disk_kms_location') and not args.IsSpecified('boot_disk_kms_keyring') and not args.IsSpecified('require_csek_key_create')): disks_messages = [[] for _ in instance_refs] else: for instance_ref in instance_refs: persistent_disks, boot_disk_ref = ( instance_utils.CreatePersistentAttachedDiskMessages( resource_parser, compute_client, self.csek_keys, args.disk or [], instance_ref)) persistent_create_disks = ( instance_utils.CreatePersistentCreateDiskMessages( compute_client, resource_parser, self.csek_keys, getattr(args, 'create_disk', []), instance_ref)) local_ssds = [] for x in args.local_ssd or []: local_ssds.append( instance_utils.CreateLocalSsdMessage( resource_parser, compute_client.messages, x.get('device-name'), x.get('interface'), x.get('size'), instance_ref.zone, instance_ref.project) ) if create_boot_disk: boot_disk = instance_utils.CreateDefaultBootAttachedDiskMessage( compute_client, resource_parser, 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, kms_args=args) 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 = (compute_client.apitools_client.projects, 'Get', compute_client.messages.ComputeProjectsGetRequest( project=instance_ref.project)) errors = [] result = 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 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=compute_client.messages, scopes=scopes, service_account=service_account) project_to_sa[instance_ref.project] = service_accounts if skip_defaults and not args.IsSpecified('can_ip_forward'): can_ip_forward = None else: can_ip_forward = args.can_ip_forward instance = compute_client.messages.Instance( canIpForward=can_ip_forward, disks=disks, description=args.description, machineType=machine_type_uri, metadata=metadata, minCpuPlatform=args.min_cpu_platform, name=instance_ref.Name(), networkInterfaces=network_interfaces, serviceAccounts=project_to_sa[instance_ref.project], scheduling=scheduling, tags=tags) if getattr(args, 'deletion_protection', None) is not None: instance.deletionProtection = args.deletion_protection if labels: instance.labels = labels if accelerator_args: accelerator_type_name = accelerator_args['type'] accelerator_type_ref = resource_parser.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( compute_client.messages, accelerator_type_ref, accelerator_count) instance.guestAccelerators = accelerators request = compute_client.messages.ComputeInstancesInsertRequest( instance=instance, project=instance_ref.project, zone=instance_ref.zone) if source_instance_template: request.sourceInstanceTemplate = source_instance_template sole_tenancy_host_arg = getattr(args, 'sole_tenancy_host', None) if sole_tenancy_host_arg: sole_tenancy_host_ref = resource_parser.Parse( sole_tenancy_host_arg, collection='compute.hosts', params={ 'project': instance_ref.project, 'zone': instance_ref.zone }) request.instance.host = sole_tenancy_host_ref.SelfLink() requests.append( (compute_client.apitools_client.instances, 'Insert', request)) return requests
def _Run(self, args): """Returns a list of requests necessary for adding images.""" holder = self._GetApiHolder() client = holder.client messages = client.messages resource_parser = holder.resources image_ref = Create.DISK_IMAGE_ARG.ResolveAsResource( args, holder.resources) image = messages.Image( name=image_ref.image, description=args.description, sourceType=messages.Image.SourceTypeValueValuesEnum.RAW, family=args.family) csek_keys = csek_utils.CsekKeyStore.FromArgs( args, self._ALLOW_RSA_ENCRYPTED_CSEK_KEYS) if csek_keys: image.imageEncryptionKey = csek_utils.MaybeToMessage( csek_keys.LookupKey( image_ref, raise_if_missing=args.require_csek_key_create), client.apitools_client) image.imageEncryptionKey = kms_utils.MaybeGetKmsKey( args, messages, image.imageEncryptionKey) # Validate parameters. if args.source_disk_zone and not args.source_disk: raise exceptions.ToolException( 'You cannot specify [--source-disk-zone] unless you are specifying ' '[--source-disk].') source_image_project = args.source_image_project source_image = args.source_image source_image_family = args.source_image_family if source_image_project and not (source_image or source_image_family): raise exceptions.ToolException( 'You cannot specify [--source-image-project] unless you are ' 'specifying [--source-image] or [--source-image-family].') if source_image or source_image_family: image_expander = image_utils.ImageExpander(client, resource_parser) _, source_image_ref = image_expander.ExpandImageFlag( user_project=image_ref.project, image=source_image, image_family=source_image_family, image_project=source_image_project, return_image_resource=True) image.sourceImage = source_image_ref.selfLink image.sourceImageEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_image_ref, client.apitools_client) if args.source_uri: source_uri = six.text_type( resources.REGISTRY.Parse(args.source_uri)) image.rawDisk = messages.Image.RawDiskValue(source=source_uri) elif args.source_disk: source_disk_ref = flags.SOURCE_DISK_ARG.ResolveAsResource( args, holder.resources, scope_lister=compute_flags.GetDefaultScopeLister(client)) image.sourceDisk = source_disk_ref.SelfLink() image.sourceDiskEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_disk_ref, client.apitools_client) elif hasattr(args, 'source_snapshot') and args.source_snapshot: source_snapshot_ref = flags.SOURCE_SNAPSHOT_ARG.ResolveAsResource( args, holder.resources, scope_lister=compute_flags.GetDefaultScopeLister(client)) image.sourceSnapshot = source_snapshot_ref.SelfLink() image.sourceSnapshotEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_snapshot_ref, client.apitools_client) if args.licenses: image.licenses = args.licenses guest_os_features = getattr(args, 'guest_os_features', []) if guest_os_features: guest_os_feature_messages = [] for feature in guest_os_features: gf_type = messages.GuestOsFeature.TypeValueValuesEnum(feature) guest_os_feature = messages.GuestOsFeature() guest_os_feature.type = gf_type guest_os_feature_messages.append(guest_os_feature) image.guestOsFeatures = guest_os_feature_messages initial_state, has_set =\ image_utils.CreateInitialStateConfig(args, messages) if has_set: image.shieldedInstanceInitialState = initial_state if args.IsSpecified('storage_location'): image.storageLocations = [args.storage_location] request = messages.ComputeImagesInsertRequest( image=image, project=image_ref.project) args_labels = getattr(args, 'labels', None) if args_labels: labels = messages.Image.LabelsValue(additionalProperties=[ messages.Image.LabelsValue.AdditionalProperty(key=key, value=value) for key, value in sorted(six.iteritems(args_labels)) ]) request.image.labels = labels # --force is in GA, --force-create is in beta and deprecated. if args.force or getattr(args, 'force_create', None): request.forceCreate = True return client.MakeRequests( [(client.apitools_client.images, 'Insert', request)], timeout=POLL_TIMEOUT)
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, support_network_tier=self._support_network_tier) else: network_tier = getattr(args, 'network_tier', None) 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), network_tier=network_tier) ] 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) 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, 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)])
def CreatePersistentCreateDiskMessages(compute_client, resources, csek_keys, create_disks, project, location, scope, holder, enable_kms=False, enable_snapshots=False, container_mount_disk=None, resource_policy=False, enable_source_snapshot_csek=False, enable_image_csek=False, support_replica_zones=False): """Returns a list of AttachedDisk messages for newly creating disks. Args: compute_client: creates resources, resources: parser of resources, csek_keys: customer suplied encryption keys, create_disks: disk objects - contains following properties * name - the name of disk, * description - an optional description for the disk, * mode - 'rw' (R/W), 'ro' (R/O) access mode, * disk-size - the size of the disk, * disk-type - the type of the disk (HDD or SSD), * image - the name of the image to initialize from, * image-csek-required - the name of the CSK protected image, * image-family - the image family name, * image-project - the project name that has the image, * auto-delete - whether disks is deleted when VM is deleted, * device-name - device name on VM, * source-snapshot - the snapshot to initialize from, * source-snapshot-csek-required - CSK protected snapshot, * disk-resource-policy - resource policies applied to disk. * enable_source_snapshot_csek - CSK file for snapshot, * enable_image_csek - CSK file for image project: Project of instance that will own the new disks. location: Location of the instance that will own the new disks. scope: Location type of the instance that will own the new disks. holder: Convenience class to hold lazy initialized client and resources. enable_kms: True if KMS keys are supported for the disk. enable_snapshots: True if snapshot initialization is supported for the disk. container_mount_disk: list of disks to be mounted to container, if any. resource_policy: True if resource-policies are enabled enable_source_snapshot_csek: True if snapshot CSK files are enabled enable_image_csek: True if image CSK files are enabled support_replica_zones: True if we allow creation of regional disks Returns: list of API messages for attached disks """ disks_messages = [] messages = compute_client.messages compute = compute_client.apitools_client for disk in create_disks or []: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY auto_delete_value = disk.get('auto-delete', 'yes') auto_delete = auto_delete_value == 'yes' disk_size_gb = utils.BytesToGb(disk.get('size')) disk_type = disk.get('type') if disk_type: disk_type_ref = instance_utils.ParseDiskType(resources, disk_type, project, location, scope) disk_type_uri = disk_type_ref.SelfLink() else: disk_type_uri = None img = disk.get('image') img_family = disk.get('image-family') img_project = disk.get('image-project') image_uri = None if img or img_family: image_expander = image_utils.ImageExpander(compute_client, resources) image_uri, _ = image_expander.ExpandImageFlag( user_project=project, image=img, image_family=img_family, image_project=img_project, return_image_resource=False) image_key = None disk_key = None if csek_keys: image_key = csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, resources, [image_uri], compute) if name: disk_ref = resources.Parse( name, collection='compute.disks', params={'zone': location}) disk_key = csek_utils.MaybeLookupKeyMessage(csek_keys, disk_ref, compute) if enable_kms: disk_key = kms_utils.MaybeGetKmsKeyFromDict(disk, messages, disk_key) initialize_params = messages.AttachedDiskInitializeParams( diskName=name, description=disk.get('description'), sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk_type_uri, sourceImageEncryptionKey=image_key) replica_zones = disk.get('replica-zones') if support_replica_zones and replica_zones: normalized_zones = [] for zone in replica_zones: zone_ref = holder.resources.Parse( zone, collection='compute.zones', params={'project': project}) normalized_zones.append(zone_ref.SelfLink()) initialize_params.replicaZones = normalized_zones if enable_snapshots: snapshot_name = disk.get('source-snapshot') attached_snapshot_uri = instance_utils.ResolveSnapshotURI( snapshot=snapshot_name, user_project=project, resource_parser=resources) if attached_snapshot_uri: initialize_params.sourceImage = None initialize_params.sourceSnapshot = attached_snapshot_uri if resource_policy: policies = disk.get('disk-resource-policy') if policies: initialize_params.resourcePolicies = policies if enable_image_csek: image_key_file = disk.get('image_csek') if image_key_file: initialize_params.imageKeyFile = image_key_file if enable_source_snapshot_csek: snapshot_key_file = disk.get('source_snapshot_csek') if snapshot_key_file: initialize_params.snapshotKeyFile = snapshot_key_file boot = disk.get('boot') == 'yes' multi_writer = disk.get('multi-writer') == 'yes' if multi_writer: initialize_params.multiWriter = True device_name = instance_utils.GetDiskDeviceName(disk, name, container_mount_disk) create_disk = messages.AttachedDisk( autoDelete=auto_delete, boot=boot, deviceName=device_name, initializeParams=initialize_params, mode=mode, type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key) disks_messages.append(create_disk) return disks_messages
def _RunCreate(compute_api, args, support_source_instance, support_kms=False, support_min_node_cpu=False, support_confidential_compute=False, support_location_hint=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 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 = instance_utils.CreateLocalNvdimmMessages( args, compute_api.resources, client.messages, ) local_ssds = instance_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) 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 CreatePersistentCreateDiskMessages(compute_client, resources, csek_keys, create_disks, instance_ref, enable_kms=False, enable_snapshots=False, container_mount_disk=None): """Returns a list of AttachedDisk messages for newly creating disks. Args: compute_client: creates resources, resources: parser of resources, csek_keys: customer suplied encryption keys, create_disks: disk objects - contains following properties * name - the name of disk, * description - an optional description for the disk, * mode - 'rw' (R/W), 'ro' (R/O) access mode, * disk-size - the size of the disk, * disk-type - the type of the disk (HDD or SSD), * image - the name of the image to initialize from, * image-family - the image family name, * image-project - the project name that has the image, * auto-delete - whether disks is deleted when VM is deleted, * device-name - device name on VM, * source-snapshot - the snapshot to initialize from. instance_ref: reference to the instance that will own the new disks. enable_kms: True if KMS keys are supported for the disk. enable_snapshots: True if snapshot initialization is supported for the disk. container_mount_disk: list of disks to be mounted to container, if any. Returns: list of API messages for attached disks """ disks_messages = [] messages = compute_client.messages compute = compute_client.apitools_client for disk in create_disks or []: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY auto_delete_value = disk.get('auto-delete', 'yes') auto_delete = auto_delete_value == 'yes' disk_size_gb = utils.BytesToGb(disk.get('size')) disk_type = disk.get('type') if disk_type: disk_type_ref = resources.Parse(disk_type, collection='compute.diskTypes', params={ 'project': instance_ref.project, 'zone': instance_ref.zone }) disk_type_uri = disk_type_ref.SelfLink() else: disk_type_uri = None img = disk.get('image') img_family = disk.get('image-family') img_project = disk.get('image-project') image_uri = None if img or img_family: image_expander = image_utils.ImageExpander(compute_client, resources) image_uri, _ = image_expander.ExpandImageFlag( user_project=instance_ref.project, image=img, image_family=img_family, image_project=img_project, return_image_resource=False) image_key = None disk_key = None if csek_keys: image_key = csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, resources, [image_uri], compute) if name: disk_ref = resources.Parse(name, collection='compute.disks', params={'zone': instance_ref.zone}) disk_key = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, compute) if enable_kms: disk_key = kms_utils.MaybeGetKmsKeyFromDict( disk, messages, disk_key) initialize_params = messages.AttachedDiskInitializeParams( diskName=name, description=disk.get('description'), sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk_type_uri, sourceImageEncryptionKey=image_key) if enable_snapshots: snapshot_name = disk.get('source-snapshot') attached_snapshot_uri = ResolveSnapshotURI( snapshot=snapshot_name, user_project=instance_ref.project, resource_parser=resources) if attached_snapshot_uri: initialize_params.sourceImage = None initialize_params.sourceSnapshot = attached_snapshot_uri device_name = GetDiskDeviceName(disk, name, container_mount_disk) create_disk = messages.AttachedDisk( autoDelete=auto_delete, boot=False, deviceName=device_name, initializeParams=initialize_params, mode=mode, type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key) disks_messages.append(create_disk) return disks_messages
def 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) instances_flags.ValidateServiceAccountAndScopeArgs(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)( resources=self.resources, scope_lister=flags.GetDefaultScopeLister(self.compute_client), messages=self.messages, network_interface_arg=args.network_interface, region=args.region) else: network_interfaces = [ 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) 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=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 = 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, ext=getattr(args, 'custom_extensions', None)) 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=instance_template_ref.project) return [request]
def CreatePersistentCreateDiskMessages(client, resources, user_project, create_disks, support_kms=False): """Returns a list of AttachedDisk messages. Args: client: Compute client adapter resources: Compute resources registry user_project: name of user project create_disks: disk objects - contains following properties * name - the name of disk, * mode - 'rw' (R/W), 'ro' (R/O) access mode, * size - the size of the disk, * type - the type of the disk (HDD or SSD), * image - the name of the image to initialize from, * image-family - the image family name, * image-project - the project name that has the image, * auto-delete - whether disks is deleted when VM is deleted ('yes' if True), * device-name - device name on VM. support_kms: if KMS is supported Returns: list of API messages for attached disks """ disks_messages = [] for disk in create_disks or []: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = client.messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = client.messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY auto_delete = disk.get('auto-delete') == 'yes' disk_size_gb = utils.BytesToGb(disk.get('size')) img = disk.get('image') img_family = disk.get('image-family') img_project = disk.get('image-project') image_uri = None if img or img_family: image_expander = image_utils.ImageExpander(client, resources) image_uri, _ = image_expander.ExpandImageFlag( user_project=user_project, image=img, image_family=img_family, image_project=img_project, return_image_resource=False) disk_key = None if support_kms: disk_key = kms_utils.MaybeGetKmsKeyFromDict( disk, client.messages, disk_key) create_disk = client.messages.AttachedDisk( autoDelete=auto_delete, boot=False, deviceName=disk.get('device-name'), initializeParams=client.messages.AttachedDiskInitializeParams( diskName=name, sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk.get('type')), mode=mode, type=client.messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key) disks_messages.append(create_disk) return disks_messages
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
def CreatePersistentCreateDiskMessages(compute_client, resources, csek_keys, create_disks, instance_ref): """Returns a list of AttachedDisk messages for newly creating disks. Args: compute_client: creates resources, resources: parser of resources, csek_keys: customer suplied encryption keys, create_disks: disk objects - contains following properties * name - the name of disk, * mode - 'rw' (R/W), 'ro' (R/O) access mode, * disk-size - the size of the disk, * disk-type - the type of the disk (HDD or SSD), * image - the name of the image to initialize from, * image-family - the image family name, * image-project - the project name that has the image, * auto-delete - whether disks is deleted when VM is deleted, * device-name - device name on VM. instance_ref: reference to the instance that will own the new disks. Returns: list of API messages for attached disks """ disks_messages = [] messages = compute_client.messages compute = compute_client.apitools_client for disk in create_disks or []: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY auto_delete_value = disk.get('auto-delete', 'yes') auto_delete = auto_delete_value == 'yes' disk_size_gb = utils.BytesToGb(disk.get('size')) disk_type = disk.get('type') if disk_type: disk_type_ref = resources.Parse(disk_type, collection='compute.diskTypes', params={ 'project': instance_ref.project, 'zone': instance_ref.zone }) disk_type_uri = disk_type_ref.SelfLink() else: disk_type_ref = None disk_type_uri = None image_expander = image_utils.ImageExpander(compute_client, resources) image_uri, _ = image_expander.ExpandImageFlag( user_project=instance_ref.project, image=disk.get('image'), image_family=disk.get('image-family'), image_project=disk.get('image-project'), return_image_resource=False) image_key = None disk_key = None if csek_keys: image_key = csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, resources, [image_uri], compute) if name: disk_ref = resources.Parse(name, collection='compute.disks', params={'zone': instance_ref.zone}) disk_key = csek_utils.MaybeLookupKeyMessage( csek_keys, disk_ref, compute) create_disk = messages.AttachedDisk( autoDelete=auto_delete, boot=False, deviceName=disk.get('device-name'), initializeParams=messages.AttachedDiskInitializeParams( diskName=name, sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk_type_uri, sourceImageEncryptionKey=image_key), mode=mode, type=messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key) disks_messages.append(create_disk) return disks_messages
def Run(self, args): compute_holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = compute_holder.client self.Validate(args) size_gb = utils.BytesToGb(args.size) from_image = args.image or args.image_family if not size_gb and not args.source_snapshot and not from_image: if args.type and 'pd-ssd' in args.type: size_gb = constants.DEFAULT_SSD_DISK_SIZE_GB else: size_gb = constants.DEFAULT_STANDARD_DISK_SIZE_GB utils.WarnIfDiskSizeIsTooSmall(size_gb, args.type) requests = [] disk_refs = Create.disks_arg.ResolveAsResource( args, compute_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( (ref for ref in disk_refs if ref.Collection() == 'compute.disks')) # Check if the region is deprecated or has maintenance coming. region_resource_fetcher = region_utils.RegionResourceFetcher(client) region_resource_fetcher.WarnForRegionalCreation( (ref for ref in disk_refs if ref.Collection() == 'compute.regionDisks')) project_to_source_image = {} image_expander = image_utils.ImageExpander(client, compute_holder.resources) for disk_ref in disk_refs: if from_image: if disk_ref.project not in project_to_source_image: source_image_uri, _ = image_expander.ExpandImageFlag( user_project=disk_ref.project, image=args.image, image_family=args.image_family, image_project=args.image_project, return_image_resource=False) project_to_source_image[ disk_ref.project] = argparse.Namespace() project_to_source_image[ disk_ref.project].uri = source_image_uri else: project_to_source_image[ disk_ref.project] = argparse.Namespace() project_to_source_image[disk_ref.project].uri = None snapshot_ref = disks_flags.SOURCE_SNAPSHOT_ARG.ResolveAsResource( args, compute_holder.resources) if snapshot_ref: snapshot_uri = snapshot_ref.SelfLink() else: snapshot_uri = None # This feature is only exposed in alpha/beta allow_rsa_encrypted = self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ] csek_keys = csek_utils.CsekKeyStore.FromArgs(args, allow_rsa_encrypted) for project in project_to_source_image: source_image_uri = project_to_source_image[project].uri project_to_source_image[project].keys = ( csek_utils.MaybeLookupKeyMessagesByUri( csek_keys, compute_holder.resources, [source_image_uri, snapshot_uri], client.apitools_client)) for disk_ref in disk_refs: if args.type: if disk_ref.Collection() == 'compute.disks': type_ref = compute_holder.resources.Parse( args.type, collection='compute.diskTypes', params={'zone': disk_ref.zone}) elif disk_ref.Collection() == 'compute.regionDisks': type_ref = compute_holder.resources.Parse( args.type, collection='compute.regionDiskTypes', params={'region': disk_ref.region}) type_uri = type_ref.SelfLink() else: type_uri = None if csek_keys: disk_key_or_none = csek_keys.LookupKey( disk_ref, args.require_csek_key_create) disk_key_message_or_none = csek_utils.MaybeToMessage( disk_key_or_none, client.apitools_client) kwargs = { 'diskEncryptionKey': disk_key_message_or_none, 'sourceImageEncryptionKey': project_to_source_image[disk_ref.project].keys[0], 'sourceSnapshotEncryptionKey': project_to_source_image[disk_ref.project].keys[1] } else: kwargs = {} if disk_ref.Collection() == 'compute.disks': request = client.messages.ComputeDisksInsertRequest( disk=client.messages.Disk(name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, **kwargs), project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, zone=disk_ref.zone) request = (client.apitools_client.disks, 'Insert', request) elif disk_ref.Collection() == 'compute.regionDisks': def SelfLink(zone, disk_ref): return compute_holder.resources.Parse( zone, collection='compute.zones', params={ 'project': disk_ref.project }).SelfLink() zones = [ SelfLink(zone, disk_ref) for zone in args.replica_zones ] request = client.messages.ComputeRegionDisksInsertRequest( disk=client.messages.Disk(name=disk_ref.Name(), description=args.description, sizeGb=size_gb, sourceSnapshot=snapshot_uri, type=type_uri, replicaZones=zones, **kwargs), project=disk_ref.project, sourceImage=project_to_source_image[disk_ref.project].uri, region=disk_ref.region) request = (client.apitools_client.regionDisks, 'Insert', request) requests.append(request) return client.MakeRequests(requests)
def _RunCreate(compute_api, args, support_network_tier=False, support_labels=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_network_tier: Indicates whether network tier is supported or not. support_labels: Indicates whether user labels are supported or not. Returns: A resource object dispatched by display.Displayer(). """ _ValidateInstancesFlags(args) if support_network_tier: instances_flags.ValidateNetworkTierArgs(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)) 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, support_network_tier=support_network_tier) 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, 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) ] 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, 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', []))) 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( compute_api.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))) request = client.messages.ComputeInstanceTemplatesInsertRequest( instanceTemplate=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(), ), project=instance_template_ref.project) if support_labels and args.labels: labels = client.messages.InstanceProperties.LabelsValue( additionalProperties=[ client.messages.InstanceProperties.LabelsValue. AdditionalProperty(key=key, value=value) for key, value in sorted(args.labels.iteritems()) ]) request.instanceTemplate.properties.labels = labels return client.MakeRequests([(client.apitools_client.instanceTemplates, 'Insert', request)])
def CreatePersistentCreateDiskMessages(client, resources, user_project, create_disks, support_kms=False, container_mount_disk=None, support_multi_writer=False): """Returns a list of AttachedDisk messages. Args: client: Compute client adapter resources: Compute resources registry user_project: name of user project create_disks: disk objects - contains following properties * name - the name of disk, * description - an optional description for the disk, * mode - 'rw' (R/W), 'ro' (R/O) access mode, * size - the size of the disk, * provisioned-iops - Indicates how many IOPS must be provisioned for the disk. * type - the type of the disk (HDD or SSD), * image - the name of the image to initialize from, * image-family - the image family name, * image-project - the project name that has the image, * auto-delete - whether disks is deleted when VM is deleted ('yes' if True), * device-name - device name on VM, * disk-resource-policy - resource policies applied to disk. support_kms: if KMS is supported container_mount_disk: list of disks to be mounted to container, if any. support_multi_writer: if multi writer disks are supported. Returns: list of API messages for attached disks """ disks_messages = [] for disk in create_disks or []: name = disk.get('name') # Resolves the mode. mode_value = disk.get('mode', 'rw') if mode_value == 'rw': mode = client.messages.AttachedDisk.ModeValueValuesEnum.READ_WRITE else: mode = client.messages.AttachedDisk.ModeValueValuesEnum.READ_ONLY auto_delete = disk.get('auto-delete', False) boot = disk.get('boot', False) disk_size_gb = utils.BytesToGb(disk.get('size')) img = disk.get('image') img_family = disk.get('image-family') img_project = disk.get('image-project') image_uri = None if img or img_family: image_expander = image_utils.ImageExpander(client, resources) image_uri, _ = image_expander.ExpandImageFlag( user_project=user_project, image=img, image_family=img_family, image_project=img_project, return_image_resource=False) disk_key = None if support_kms: disk_key = kms_utils.MaybeGetKmsKeyFromDict( disk, client.messages, disk_key) device_name = instance_utils.GetDiskDeviceName(disk, name, container_mount_disk) init_params = client.messages.AttachedDiskInitializeParams( diskName=name, description=disk.get('description'), sourceImage=image_uri, diskSizeGb=disk_size_gb, diskType=disk.get('type'), provisionedIops=disk.get('provisioned-iops')) policies = disk.get('disk-resource-policy') if policies: init_params.resourcePolicies = policies multi_writer = disk.get('multi-writer') if support_multi_writer and multi_writer: init_params.multiWriter = True create_disk = client.messages.AttachedDisk( autoDelete=auto_delete, boot=boot, deviceName=device_name, initializeParams=init_params, mode=mode, type=client.messages.AttachedDisk.TypeValueValuesEnum.PERSISTENT, diskEncryptionKey=disk_key) disks_messages.append(create_disk) return disks_messages
def Run(self, args): """Returns a list of requests necessary for adding images.""" holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client messages = client.messages resource_parser = holder.resources image_ref = Create.DISK_IMAGE_ARG.ResolveAsResource( args, holder.resources) image = messages.Image( name=image_ref.image, description=args.description, sourceType=messages.Image.SourceTypeValueValuesEnum.RAW, family=args.family) csek_keys = csek_utils.CsekKeyStore.FromArgs( args, self._ALLOW_RSA_ENCRYPTED_CSEK_KEYS) if csek_keys: image.imageEncryptionKey = csek_utils.MaybeToMessage( csek_keys.LookupKey( image_ref, raise_if_missing=args.require_csek_key_create), client.apitools_client) image.imageEncryptionKey = kms_utils.MaybeGetKmsKey( args, image_ref.project, client.apitools_client, image.imageEncryptionKey) # Validate parameters. if args.source_disk_zone and not args.source_disk: raise exceptions.ToolException( 'You cannot specify [--source-disk-zone] unless you are specifying ' '[--source-disk].') source_image_project = getattr(args, 'source_image_project', None) source_image = getattr(args, 'source_image', None) source_image_family = getattr(args, 'source_image_family', None) if source_image_project and not (source_image or source_image_family): raise exceptions.ToolException( 'You cannot specify [--source-image-project] unless you are ' 'specifying [--source-image] or [--source-image-family].') if source_image or source_image_family: image_expander = image_utils.ImageExpander(client, resource_parser) _, source_image_ref = image_expander.ExpandImageFlag( user_project=image_ref.project, image=source_image, image_family=source_image_family, image_project=source_image_project, return_image_resource=True) image.sourceImage = source_image_ref.selfLink image.sourceImageEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_image_ref, client.apitools_client) # TODO(b/30086260): use resources.REGISTRY.Parse() for GCS URIs. if args.source_uri: source_uri = utils.NormalizeGoogleStorageUri(args.source_uri) image.rawDisk = messages.Image.RawDiskValue(source=source_uri) elif args.source_disk: source_disk_ref = flags.SOURCE_DISK_ARG.ResolveAsResource( args, holder.resources, scope_lister=compute_flags.GetDefaultScopeLister(client)) image.sourceDisk = source_disk_ref.SelfLink() image.sourceDiskEncryptionKey = csek_utils.MaybeLookupKeyMessage( csek_keys, source_disk_ref, client.apitools_client) if args.licenses: image.licenses = args.licenses guest_os_features = getattr(args, 'guest_os_features', []) if guest_os_features: guest_os_feature_messages = [] for feature in guest_os_features: gf_type = messages.GuestOsFeature.TypeValueValuesEnum(feature) guest_os_feature = messages.GuestOsFeature() guest_os_feature.type = gf_type guest_os_feature_messages.append(guest_os_feature) image.guestOsFeatures = guest_os_feature_messages request = messages.ComputeImagesInsertRequest( image=image, project=image_ref.project) args_labels = getattr(args, 'labels', None) if args_labels: labels = messages.Image.LabelsValue(additionalProperties=[ messages.Image.LabelsValue.AdditionalProperty(key=key, value=value) for key, value in sorted(args_labels.iteritems()) ]) request.image.labels = labels # --force is in GA, --force-create is in beta and deprecated. if args.force or getattr(args, 'force_create', None): request.forceCreate = True return client.MakeRequests([(client.apitools_client.images, 'Insert', request)])
def _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)])