def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client.apitools_client messages = holder.client.messages disk_ref = self.DISK_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetDefaultScopeLister(holder.client)) add_labels = labels_util.GetUpdateLabelsDictFromArgs(args) if disk_ref.Collection() == 'compute.disks': service = client.disks request_type = messages.ComputeDisksGetRequest elif disk_ref.Collection() == 'compute.regionDisks': service = client.regionDisks request_type = messages.ComputeRegionDisksGetRequest else: raise ValueError('Unexpected resource argument of {}'.format( disk_ref.Collection())) disk = service.Get(request_type(**disk_ref.AsDict())) if disk_ref.Collection() == 'compute.disks': operation_collection = 'compute.zoneOperations' labels_update = labels_util.Diff(additions=add_labels).Apply( messages.ZoneSetLabelsRequest.LabelsValue, disk.labels) request = messages.ComputeDisksSetLabelsRequest( project=disk_ref.project, resource=disk_ref.disk, zone=disk_ref.zone, zoneSetLabelsRequest=messages.ZoneSetLabelsRequest( labelFingerprint=disk.labelFingerprint, labels=labels_update.GetOrNone())) else: operation_collection = 'compute.regionOperations' labels_update = labels_util.Diff(additions=add_labels).Apply( messages.RegionSetLabelsRequest.LabelsValue, disk.labels) request = messages.ComputeRegionDisksSetLabelsRequest( project=disk_ref.project, resource=disk_ref.disk, region=disk_ref.region, regionSetLabelsRequest=messages.RegionSetLabelsRequest( labelFingerprint=disk.labelFingerprint, labels=labels_update.GetOrNone())) if not labels_update.needs_update: return disk operation = service.SetLabels(request) operation_ref = holder.resources.Parse(operation.selfLink, collection=operation_collection) operation_poller = poller.Poller(service) return waiter.WaitFor( operation_poller, operation_ref, 'Updating labels of disk [{0}]'.format(disk_ref.Name()))
def __init__(self, endpoint_visibility): """Determine label changes for modifying endpoint visibility. Args: endpoint_visibility: bool, True if Cloud Run on GKE service should only be addressable from within the cluster. False if it should be publicly addressable. """ if endpoint_visibility: diff = labels_util.Diff( additions={service.ENDPOINT_VISIBILITY: service.CLUSTER_LOCAL}) else: diff = labels_util.Diff(subtractions=[service.ENDPOINT_VISIBILITY]) super(EndpointVisibilityChange, self).__init__(diff)
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client.apitools_client messages = holder.client.messages snapshot_ref = SnapshotsAddLabels.SnapshotArg.ResolveAsResource( args, holder.resources) add_labels = labels_util.GetUpdateLabelsDictFromArgs(args) snapshot = client.snapshots.Get( messages.ComputeSnapshotsGetRequest(**snapshot_ref.AsDict())) labels_update = labels_util.Diff(additions=add_labels).Apply( messages.GlobalSetLabelsRequest.LabelsValue, snapshot.labels) if not labels_update.needs_update: return snapshot request = messages.ComputeSnapshotsSetLabelsRequest( project=snapshot_ref.project, resource=snapshot_ref.snapshot, globalSetLabelsRequest=messages.GlobalSetLabelsRequest( labelFingerprint=snapshot.labelFingerprint, labels=labels_update.labels)) operation = client.snapshots.SetLabels(request) operation_ref = holder.resources.Parse( operation.selfLink, collection='compute.globalOperations') operation_poller = poller.Poller(client.snapshots) return waiter.WaitFor( operation_poller, operation_ref, 'Updating labels of snapshot [{0}]'.format(snapshot_ref.Name()))
def ProcessUpdateLabels(args, labels_name, labels_cls, orig_labels): """Returns the result of applying the diff constructed from args. This API doesn't conform to the standard patch semantics, and instead does a replace operation on update. Therefore, if there are no updates to do, then the original labels must be returned as writing None into the labels field would replace it. Args: args: argparse.Namespace, the parsed arguments with update_labels, remove_labels, and clear_labels labels_name: str, the name for the labels flag. labels_cls: type, the LabelsValue class for the new labels. orig_labels: message, the original LabelsValue value to be updated. Returns: LabelsValue: The updated labels of type labels_cls. Raises: ValueError: if the update does not change the labels. """ labels_diff = labels_util.Diff(additions=getattr(args, 'update_' + labels_name), subtractions=getattr( args, 'remove_' + labels_name), clear=getattr(args, 'clear_' + labels_name)) if not labels_diff.MayHaveUpdates(): return None return labels_diff.Apply(labels_cls, orig_labels).GetOrNone()
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client.apitools_client messages = holder.client.messages ips_ref = self.IPS_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetDefaultScopeLister(holder.client)) add_labels = labels_util.GetUpdateLabelsDictFromArgs(args) ips_info = api_util.GetInPlaceSnapshotInfo(ips_ref, client, messages) ips = ips_info.GetInPlaceSnapshotResource() set_label_req = ips_info.GetSetLabelsRequestMessage() labels_update = labels_util.Diff(additions=add_labels).Apply( set_label_req.LabelsValue, ips.labels) request = ips_info.GetSetInPlaceSnapshotLabelsRequestMessage( ips, labels_update.GetOrNone()) if not labels_update.needs_update: return ips service = ips_info.GetService() operation = service.SetLabels(request) operation_ref = holder.resources.Parse( operation.selfLink, collection=ips_info.GetOperationCollection()) operation_poller = poller.Poller(service) return waiter.WaitFor( operation_poller, operation_ref, 'Updating labels of in-place snapshot [{0}]'.format( ips_ref.Name()))
def SetFunctionLabels(function, update_labels, remove_labels, clear_labels): """Set the labels on a function based on args. Args: function: the function to set the labels on update_labels: a dict of <label-name>-<label-value> pairs for the labels to be updated, from --update-labels remove_labels: a list of the labels to be removed, from --remove-labels clear_labels: a bool representing whether or not to clear all labels, from --clear-labels Returns: A bool indicating whether or not any labels were updated on the function. """ labels_to_update = update_labels or {} labels_to_update['deployment-tool'] = 'cli-gcloud' labels_diff = args_labels_util.Diff(additions=labels_to_update, subtractions=remove_labels, clear=clear_labels) messages = api_util.GetApiMessagesModule() labels_update = labels_diff.Apply(messages.CloudFunction.LabelsValue, function.labels) if labels_update.needs_update: function.labels = labels_update.labels return True return False
def Run(self, args): project_ref = command_lib_util.ParseProject(args.id) result = projects_api.Update(project_ref, name=args.name, labels_diff=labels_util.Diff()) log.UpdatedResource(project_ref) return result
def testClearAndRemoveLabelsNotAllowed(self): parser = argparse.ArgumentParser() labels_util.AddUpdateLabelsFlags(parser, enable_clear=True) with self.assertRaises(SystemExit): parser.parse_args('--remove-labels foo --clear-labels'.split()) with self.assertRaises(ValueError): labels_util.Diff(subtractions=['foo'], clear=True)
def Run(self, args): if args.name is None: raise ArgumentError('--name must be specified.') project_ref = command_lib_util.ParseProject(args.id) result = projects_api.Update(project_ref, name=args.name, labels_diff=labels_util.Diff()) log.UpdatedResource(project_ref) return result
def testLabelsUpdateWithClusterLocalEndpointVisibility(self): self.resource.labels[service.ENDPOINT_VISIBILITY] = service.CLUSTER_LOCAL labels_change = config_changes.LabelChanges( labels_util.Diff(additions={'test': 'abc'})) self.resource = labels_change.Adjust(self.resource) self.assertDictEqual( { service.ENDPOINT_VISIBILITY: service.CLUSTER_LOCAL, 'test': 'abc' }, dict(self.resource.labels)) self.assertDictEqual({'test': 'abc'}, dict(self.template.labels))
def _UpdateLabels(self, args, migration_job, update_fields): """Updates labels of the migration job.""" add_labels = labels_util.GetUpdateLabelsDictFromArgs(args) remove_labels = labels_util.GetRemoveLabelsListFromArgs(args) value_type = self.messages.MigrationJob.LabelsValue update_result = labels_util.Diff( additions=add_labels, subtractions=remove_labels, clear=args.clear_labels).Apply(value_type) if update_result.needs_update: migration_job.labels = update_result.labels update_fields.append('labels')
def _UpdateLabels(self, stream, args): """Updates labels of the stream.""" add_labels = labels_util.GetUpdateLabelsDictFromArgs(args) remove_labels = labels_util.GetRemoveLabelsListFromArgs(args) value_type = self._messages.Stream.LabelsValue update_result = labels_util.Diff( additions=add_labels, subtractions=remove_labels, clear=args.clear_labels ).Apply(value_type, stream.labels) if update_result.needs_update: stream.labels = update_result.labels
def _UpdateLabels(self, connection_profile, args): """Updates labels of the connection profile.""" add_labels = labels_util.GetUpdateLabelsDictFromArgs(args) remove_labels = labels_util.GetRemoveLabelsListFromArgs(args) value_type = self._messages.ConnectionProfile.LabelsValue update_result = labels_util.Diff(additions=add_labels, subtractions=remove_labels, clear=args.clear_labels).Apply( value_type, connection_profile.labels) if update_result.needs_update: connection_profile.labels = update_result.labels
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client.apitools_client messages = holder.client.messages instance_ref = flags.INSTANCE_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetInstanceZoneScopeLister(holder.client)) remove_labels = labels_util.GetUpdateLabelsDictFromArgs(args) instance = client.instances.Get( messages.ComputeInstancesGetRequest(**instance_ref.AsDict())) if args.all: # removing all existing labels from the instance. remove_labels = {} if instance.labels: for label in instance.labels.additionalProperties: remove_labels[label.key] = label.value labels_update = labels_util.Diff(subtractions=remove_labels).Apply( messages.InstancesSetLabelsRequest.LabelsValue, instance.labels) if not labels_update.needs_update: return instance request = messages.ComputeInstancesSetLabelsRequest( project=instance_ref.project, instance=instance_ref.instance, zone=instance_ref.zone, instancesSetLabelsRequest= messages.InstancesSetLabelsRequest( labelFingerprint=instance.labelFingerprint, labels=labels_update.labels)) operation = client.instances.SetLabels(request) operation_ref = holder.resources.Parse( operation.selfLink, collection='compute.zoneOperations') operation_poller = poller.Poller(client.instances) return waiter.WaitFor( operation_poller, operation_ref, 'Changing labels of instance [{0}]'.format( instance_ref.Name()))
def _ApplyArgsToFunction(self, function, is_new_function, trigger_params, function_ref, args, project): """Apply values from args to base_function. Args: function: function message to modify is_new_function: bool, indicates if this is a new function (and source code for it must be deployed) or an existing function (so it may keep its old source code). trigger_params: parameters for creating functions trigger. function_ref: reference to function. args: commandline args specyfying how to modify the function. project: project of the function. Returns: Pair of function and update mask. """ update_mask = [] messages = util.GetApiMessagesModule() client = util.GetApiClientInstance() self._ApplyNonSourceArgsToFunction(function, function_ref, update_mask, messages, args, trigger_params) # Only Add source to function if its explicitly provided, a new function, # using a stage budget or deploy of an existing function that previously # used local source if (args.source or args.stage_bucket or is_new_function or function.sourceUploadUrl): # deploy_util.AddSourceToFunction( function, function_ref, update_mask, args.source, args.stage_bucket, messages, client.projects_locations_functions) # Set information about deployment tool. labels_to_update = args.update_labels or {} labels_to_update['deployment-tool'] = 'cli-gcloud' labels_diff = labels_util.Diff(additions=labels_to_update, subtractions=args.remove_labels, clear=args.clear_labels) labels_update = labels_diff.Apply(messages.CloudFunction.LabelsValue, function.labels) if labels_update.needs_update: function.labels = labels_update.labels update_mask.append('labels') return function, ','.join(sorted(update_mask))
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client.apitools_client messages = holder.client.messages image_ref = self.DISK_IMAGE_ARG.ResolveAsResource( args, holder.resources) remove_labels = labels_util.GetUpdateLabelsDictFromArgs(args) image = client.images.Get( messages.ComputeImagesGetRequest(**image_ref.AsDict())) if args.all: # removing all existing labels from the image. remove_labels = {} if image.labels: for label in image.labels.additionalProperties: remove_labels[label.key] = label.value labels_update = labels_util.Diff(subtractions=remove_labels).Apply( messages.GlobalSetLabelsRequest.LabelsValue, image.labels) if not labels_update.needs_update: return image request = messages.ComputeImagesSetLabelsRequest( project=image_ref.project, resource=image_ref.image, globalSetLabelsRequest= messages.GlobalSetLabelsRequest( labelFingerprint=image.labelFingerprint, labels=labels_update.labels)) operation = client.images.SetLabels(request) operation_ref = holder.resources.Parse( operation.selfLink, collection='compute.globalOperations') operation_poller = poller.Poller(client.images) return waiter.WaitFor( operation_poller, operation_ref, 'Updating labels of image [{0}]'.format( image_ref.Name()))
def Run(self, args): dataproc = dp.Dataproc(self.ReleaseTrack()) template_ref = args.CONCEPTS.template.Parse() workflow_template = dataproc.GetRegionsWorkflowTemplate( template_ref, args.version) labels = labels_util.Diff(additions=args.cluster_labels).Apply( dataproc.messages.ClusterSelector.ClusterLabelsValue).GetOrNone() cluster_selector = dataproc.messages.ClusterSelector( clusterLabels=labels) workflow_template.placement = dataproc.messages.WorkflowTemplatePlacement( clusterSelector=cluster_selector) response = dataproc.client.projects_regions_workflowTemplates.Update( workflow_template) return response
def Run(self, args): dataproc = dp.Dataproc(self.ReleaseTrack()) template = util.ParseWorkflowTemplates(args.template, dataproc) workflow_template = dataproc.GetRegionsWorkflowTemplate( template, args.version) labels = labels_util.Diff(additions=args.cluster_labels).Apply( dataproc.messages.ClusterSelector.ClusterLabelsValue).GetOrNone() cluster_selector = dataproc.messages.ClusterSelector( clusterLabels=labels, zone=properties.VALUES.compute.zone.GetOrFail()) workflow_template.placement = dataproc.messages.WorkflowTemplatePlacement( clusterSelector=cluster_selector) response = dataproc.client.projects_regions_workflowTemplates.Update( workflow_template) return response
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client.apitools_client messages = holder.client.messages disk_ref = self.DISK_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetDefaultScopeLister(holder.client)) remove_labels = labels_util.GetUpdateLabelsDictFromArgs(args) disk_info = api_util.GetDiskInfo(disk_ref, client, messages) disk = disk_info.GetDiskResource() if args.all: # removing all existing labels from the disk. remove_labels = {} if disk.labels: for label in disk.labels.additionalProperties: remove_labels[label.key] = label.value labels_diff = labels_util.Diff(subtractions=remove_labels) set_label_req = disk_info.GetSetLabelsRequestMessage() labels_update = labels_diff.Apply(set_label_req.LabelsValue, disk.labels) request = disk_info.GetSetDiskLabelsRequestMessage( disk, labels_update.GetOrNone()) if not labels_update.needs_update: return disk service = disk_info.GetService() operation = service.SetLabels(request) operation_ref = holder.resources.Parse( operation.selfLink, collection=disk_info.GetOperationCollection()) operation_poller = poller.Poller(service) return waiter.WaitFor( operation_poller, operation_ref, 'Updating labels of disk [{0}]'.format(disk_ref.Name()))
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client.apitools_client messages = holder.client.messages image_ref = self.DISK_IMAGE_ARG.ResolveAsResource( args, holder.resources, scope_lister=flags.GetDefaultScopeLister(holder.client)) add_labels = labels_util.GetUpdateLabelsDictFromArgs(args) image = client.images.Get( messages.ComputeImagesGetRequest(**image_ref.AsDict())) labels_update = labels_util.Diff(additions=add_labels).Apply( messages.GlobalSetLabelsRequest.LabelsValue, image.labels) if not labels_update.needs_update: return image request = messages.ComputeImagesSetLabelsRequest( project=image_ref.project, resource=image_ref.image, globalSetLabelsRequest= messages.GlobalSetLabelsRequest( labelFingerprint=image.labelFingerprint, labels=labels_update.labels)) operation = client.images.SetLabels(request) operation_ref = holder.resources.Parse( operation.selfLink, collection='compute.globalOperations') operation_poller = poller.Poller(client.images) return waiter.WaitFor( operation_poller, operation_ref, 'Updating labels of image [{0}]'.format( image_ref.Name()))
def _expectCreationCall(self, test_project, labels=None, exception=None): operation_name = 'pc.1234' labels_message = labels_util.Diff(additions=labels).Apply( self.messages.Project.LabelsValue).GetOrNone() if exception: response = None else: response = self.messages.Operation(name='operations/' + operation_name) self.mock_client.projects.Create.Expect( self.messages.Project( projectId=test_project.projectId, name=test_project.name, parent=test_project.parent, labels=labels_message), exception=exception, response=response) if not exception: self.mock_client.operations.Get.Expect( request=self.messages.CloudresourcemanagerOperationsGetRequest( operationsId=operation_name), response=self.messages.Operation( name='operations/' + operation_name, done=True, response=operations.ToOperationResponse(test_project)))
def MakeClusterSelector(self, cluster_labels): labels = labels_util.Diff(additions=cluster_labels).Apply( self.messages.ClusterSelector.ClusterLabelsValue).GetOrNone() return self.messages.ClusterSelector(clusterLabels=labels)
def GetConfigurationChanges(args): """Returns a list of changes to Configuration, based on the flags set.""" changes = [] changes.extend(_GetScalingChanges(args)) if _HasEnvChanges(args): changes.append(_GetEnvChanges(args)) if _HasTrafficChanges(args): changes.append(_GetTrafficChanges(args)) if _HasCloudSQLChanges(args): region = GetRegion(args) project = ( getattr(args, 'project', None) or properties.VALUES.core.project.Get(required=True)) _CheckCloudSQLApiEnablement() changes.append(config_changes.CloudSQLChanges(project, region, args)) if _HasSecretsChanges(args): changes.extend(_GetSecretsChanges(args)) if _HasConfigMapsChanges(args): changes.extend(_GetConfigMapsChanges(args)) if 'no_traffic' in args and args.no_traffic: changes.append(config_changes.NoTrafficChange()) if 'cpu' in args and args.cpu: changes.append(config_changes.ResourceChanges(cpu=args.cpu)) if 'memory' in args and args.memory: changes.append(config_changes.ResourceChanges(memory=args.memory)) if 'concurrency' in args and args.concurrency: changes.append(config_changes.ConcurrencyChanges( concurrency=args.concurrency)) if 'timeout' in args and args.timeout: try: # A bare number is interpreted as seconds. timeout_secs = int(args.timeout) except ValueError: timeout_duration = times.ParseDuration(args.timeout) timeout_secs = int(timeout_duration.total_seconds) if timeout_secs <= 0: raise ArgumentError( 'The --timeout argument must be a positive time duration.') changes.append(config_changes.TimeoutChanges(timeout=timeout_secs)) if 'service_account' in args and args.service_account: changes.append( config_changes.ServiceAccountChanges( service_account=args.service_account)) if _HasLabelChanges(args): additions = ( args.labels if _FlagIsExplicitlySet(args, 'labels') else args.update_labels) diff = labels_util.Diff( additions=additions, subtractions=args.remove_labels, clear=args.clear_labels) if diff.MayHaveUpdates(): changes.append(config_changes.LabelChanges(diff)) if 'revision_suffix' in args and args.revision_suffix: changes.append(config_changes.RevisionNameChanges(args.revision_suffix)) if 'vpc_connector' in args and args.vpc_connector: changes.append(config_changes.VpcConnectorChange(args.vpc_connector)) if 'clear_vpc_connector' in args and args.clear_vpc_connector: changes.append(config_changes.ClearVpcConnectorChange()) if 'connectivity' in args and args.connectivity: if args.connectivity == 'internal': changes.append(config_changes.EndpointVisibilityChange(True)) elif args.connectivity == 'external': changes.append(config_changes.EndpointVisibilityChange(False)) if 'command' in args and args.command is not None: # Allow passing an empty string here to reset the field changes.append(config_changes.ContainerCommandChange(args.command)) if 'args' in args and args.args is not None: # Allow passing an empty string here to reset the field changes.append(config_changes.ContainerArgsChange(args.args)) if _FlagIsExplicitlySet(args, 'port'): changes.append(config_changes.ContainerPortChange(port=args.port)) if _FlagIsExplicitlySet(args, 'use_http2'): changes.append(config_changes.ContainerPortChange(use_http2=args.use_http2)) return changes
def GetConfigurationChanges(args): """Returns a list of changes to Configuration, based on the flags set.""" changes = [] changes.extend(_GetScalingChanges(args)) if _HasEnvChanges(args): changes.append(_GetEnvChanges(args)) if _HasCloudSQLChanges(args): region = GetRegion(args) project = (getattr(args, 'project', None) or properties.VALUES.core.project.Get(required=True)) _CheckCloudSQLApiEnablement() changes.append(config_changes.CloudSQLChanges(project, region, args)) if _HasSecretsChanges(args): changes.append(_GetSecretsChanges(args)) if _HasConfigMapsChanges(args): changes.append(_GetConfigMapsChanges(args)) if 'cpu' in args and args.cpu: changes.append(config_changes.ResourceChanges(cpu=args.cpu)) if 'memory' in args and args.memory: changes.append(config_changes.ResourceChanges(memory=args.memory)) if 'concurrency' in args and args.concurrency: try: c = int(args.concurrency) except ValueError: c = args.concurrency if c != 'default': log.warning( 'Specifying concurrency as Single or Multi is deprecated; ' 'an integer is preferred.') changes.append(config_changes.ConcurrencyChanges(concurrency=c)) if 'timeout' in args and args.timeout: try: # A bare number is interpreted as seconds. timeout_secs = int(args.timeout) except ValueError: timeout_duration = times.ParseDuration(args.timeout) timeout_secs = int(timeout_duration.total_seconds) if timeout_secs <= 0: raise ArgumentError( 'The --timeout argument must be a positive time duration.') changes.append(config_changes.TimeoutChanges(timeout=timeout_secs)) if 'service_account' in args and args.service_account: changes.append( config_changes.ServiceAccountChanges( service_account=args.service_account)) if _HasLabelChanges(args): additions = (args.labels if _FlagIsExplicitlySet(args, 'labels') else args.update_labels) diff = labels_util.Diff(additions=additions, subtractions=args.remove_labels, clear=args.clear_labels) if diff.MayHaveUpdates(): changes.append(config_changes.LabelChanges(diff)) if 'revision_suffix' in args and args.revision_suffix: changes.append(config_changes.RevisionNameChanges( args.revision_suffix)) if 'vpc_connector' in args and args.vpc_connector: changes.append(config_changes.VpcConnectorChange(args.vpc_connector)) if 'clear_vpc_connector' in args and args.clear_vpc_connector: changes.append(config_changes.ClearVpcConnectorChange()) if 'connectivity' in args and args.connectivity: if args.connectivity == 'internal': changes.append(config_changes.EndpointVisibilityChange(True)) elif args.connectivity == 'external': changes.append(config_changes.EndpointVisibilityChange(False)) return changes