def Run(self, args): self.ref = self.CreateReference(args) get_request = self.GetGetRequest(args) errors = [] objects = list( request_helper.MakeRequests(requests=[get_request], http=self.http, batch_url=self.batch_url, errors=errors)) if errors: utils.RaiseToolException( errors, error_message='There was a problem fetching the resource:') new_object = self.Modify(args, objects[0]) # If existing object is equal to the proposed object or if # Modify() returns None, then there is no work to be done, so we # print the resource and return. if not new_object or objects[0] == new_object: for resource in lister.ProcessResults( resources=[objects[0]], field_selector=property_selector.PropertySelector( properties=None, transformations=self.transformations)): log.status.Print( 'No change requested; skipping update for [{0}].'.format( resource[u'name'])) yield resource return resource_list = request_helper.MakeRequests( requests=[self.GetSetRequest(args, new_object, objects[0])], http=self.http, batch_url=self.batch_url, errors=errors) resource_list = lister.ProcessResults( resources=resource_list, field_selector=property_selector.PropertySelector( properties=None, transformations=self.transformations)) for resource in resource_list: yield resource if errors: utils.RaiseToolException( errors, error_message='There was a problem modifying the resource:')
def _Run(self, args): """Yields JSON-serializable dicts of resources or self links.""" # Data structures used to perform client-side filtering of # resources by their names and/or URIs. self.self_links = set() self.names = set() self.resource_refs = [] # The field selector should be constructed before any resources # are fetched, so if there are any syntactic errors with the # fields, we can fail fast. field_selector = property_selector.PropertySelector( properties=None, transformations=self.transformations) errors = [] self.PopulateResourceFilteringStructures(args) items = self.FilterResults( args, self.GetResources(args, errors)) items = lister.ProcessResults( resources=items, field_selector=field_selector) items = self.ComputeDynamicProperties(args, items) for item in items: yield item if errors: utils.RaiseToolException(errors)
def Run(self, args): sort_key_fn = None descending = False errors = [] if args.uri: field_selector = None else: field_selector = property_selector.PropertySelector( properties=None, transformations=self._FIELD_TRANSFORMS) sort_key_fn, descending = GetSortKey(args.sort_by, self._LIST_TABS) responses, errors = self.GetResources(args) if errors: utils.RaiseToolException(errors) items = lister.ProcessResults(resources=list( _UnwrapResponse(responses, self.list_field)), field_selector=field_selector, sort_key_fn=sort_key_fn, reverse_sort=descending, limit=args.limit) for item in items: if args.uri: yield item['instance'] else: yield item
def Run(self, args): request_protobufs = self.CreateRequests(args) requests = [] for request in request_protobufs: requests.append((self.service, self.method, request)) errors = [] if args. async: resources, new_errors = batch_helper.MakeRequests( requests=requests, http=self.http, batch_url=self.batch_url) if not new_errors: for invalidation_operation in resources: log.status.write('Invalidation pending for [{0}]\n'.format( invalidation_operation.targetLink)) log.status.write('Monitor its progress at [{0}]\n'.format( invalidation_operation.selfLink)) errors.extend(new_errors) else: # We want to run through the generator that MakeRequests returns in order # to actually make the requests. resources = list( request_helper.MakeRequests(requests=requests, http=self.http, batch_url=self.batch_url, errors=errors)) resources = lister.ProcessResults( resources=resources, field_selector=property_selector.PropertySelector( properties=None, transformations=self.transformations)) if errors: utils.RaiseToolException(errors) return resources
def testFilteringAndTransformations(self): selector = property_selector.PropertySelector( properties=[ 'dictOfDicts.dictTwo', 'listOfDicts[0]', 'string', ], transformations=[ ('string', lambda x: x.upper()), ('dictOfDicts.dictTwo.string', lambda x: x * 2), ('listOfDicts[].string', lambda x: x.upper()), ('nested', lambda x: 'Hello'), ]) res = selector.Apply(self.object) self.assertEqual( res, { 'string': 'ONE', 'dictOfDicts': { 'dictTwo': { 'string': 'twotwo', 'hello': 'world' } }, 'listOfDicts': [{ 'string': 'ONE', 'hello': 'world' }, None, None], })
def Run(self, args): field_selector = property_selector.PropertySelector(properties=None, transformations=[]) sort_key_fn, descending = GetSortKey(args.sort_by, self._COLUMNS) responses, errors = self.GetResources(args) if errors: utils.RaiseToolException(errors) return lister.ProcessResults(resources=list( _UnwrapResponse(responses, 'namedPorts')), field_selector=field_selector, sort_key_fn=sort_key_fn, reverse_sort=descending, limit=args.limit)
def testFilteringCopiesResult(self): expected = { 'string': 'one', 'integer': 123, 'dictOfDicts': { 'dictTwo': { 'string': 'two', 'hello': 'world' }, 'dictOne': { 'string': 'one' } }, 'listOfDicts': [{ 'string': 'one', 'hello': 'world' }, { 'string': 'two' }, { 'string': 'three', 'another': 'string' }] } selector = property_selector.PropertySelector([ 'listOfDicts[1].string', 'listOfDicts[].string', 'listOfDicts[0].hello', 'integer', 'dictOfDicts.dictOne.string', 'dictOfDicts.dictTwo', 'dictOfDicts.dictTwo.hello', 'listOfDicts[0].string', 'listOfDicts[].another', 'string', ]) res = selector.Apply(self.object) self.assertEqual(res, expected) # Ensures that Apply() makes a deep copy of its result # before returning it to the client. self.object['dictOfDicts']['dictTwo'] = 'garbage' self.object['listOfDicts'][0] = 'garbage' self.object['listOfDicts'][1]['string'] = 'garbage' self.object['integer'] = 300 self.assertEqual(res, expected)
def Run(self, args): errors = [] requests = self._CreateRequests(args) resource_list = self.compute_client.MakeRequests(requests, errors) # changes machine type uri to just machine type name resource_list = lister.ProcessResults( resources=resource_list, field_selector=property_selector.PropertySelector( properties=None, transformations=self.transformations)) if errors: utils.RaiseToolException(errors) return resource_list
def Run(self, args): errors = [] resource_list = self.MakeRequests(self.CreateRequests(args), errors) resource_list = lister.ProcessResults( resources=resource_list, field_selector=property_selector.PropertySelector( properties=None, transformations=self.transformations)) resource_list = self.ComputeDynamicProperties(args, resource_list) if errors: utils.RaiseToolException(errors) return resource_list
def _ProcessEditedResource(self, holder, backend_service_ref, file_contents, original_object, original_record, modifiable_record, args): """Returns an updated resource that was edited by the user.""" # It's very important that we replace the characters of comment # lines with spaces instead of removing the comment lines # entirely. JSON and YAML deserialization give error messages # containing line, column, and the character offset of where the # error occurred. If the deserialization fails; we want to make # sure those numbers map back to what the user actually had in # front of him or her otherwise the errors will not be very # useful. non_comment_lines = '\n'.join( ' ' * len(line) if line.startswith('#') else line for line in file_contents.splitlines()) modified_record = base_classes.DeserializeValue( non_comment_lines, args.format or Edit.DEFAULT_FORMAT) # Normalizes all of the fields that refer to other # resource. (i.e., translates short names to URIs) reference_normalizer = property_selector.PropertySelector( transformations=self.GetReferenceNormalizers(holder.resources)) modified_record = reference_normalizer.Apply(modified_record) if modifiable_record == modified_record: new_object = None else: modified_record['name'] = original_record['name'] fingerprint = original_record.get('fingerprint') if fingerprint: modified_record['fingerprint'] = fingerprint new_object = encoding.DictToMessage( modified_record, holder.client.messages.BackendService) # If existing object is equal to the proposed object or if # there is no new object, then there is no work to be done, so we # return the original object. if not new_object or original_object == new_object: return [original_object] return holder.client.MakeRequests([ self.GetSetRequest(holder.client, backend_service_ref, new_object) ])
def EditResource(self, args, client, holder, original_object, url_map_ref): original_record = encoding.MessageToDict(original_object) # Selects only the fields that can be modified. field_selector = property_selector.PropertySelector(properties=[ 'defaultService', 'description', 'hostRules', 'pathMatchers', 'tests', ]) modifiable_record = field_selector.Apply(original_record) buf = self.BuildFileContents(args, client, modifiable_record, original_record) file_contents = buf.getvalue() while True: try: file_contents = edit.OnlineEdit(file_contents) except edit.NoSaveException: raise exceptions.ToolException('Edit aborted by user.') try: resource_list = self._ProcessEditedResource( holder, url_map_ref, file_contents, original_object, original_record, modifiable_record, args) break except (ValueError, yaml.error.YAMLError, messages.ValidationError, exceptions.ToolException) as e: if isinstance(e, ValueError): message = e.message else: message = str(e) if isinstance(e, exceptions.ToolException): problem_type = 'applying' else: problem_type = 'parsing' message = ('There was a problem {0} your changes: {1}'.format( problem_type, message)) if not console_io.PromptContinue( message=message, prompt_string= 'Would you like to edit the resource again?'): raise exceptions.ToolException('Edit aborted by user.') return resource_list
def Run(self, args): cleared_fields = [] (service, method, request) = self.CreateRequest(args, cleared_fields) errors = [] with self.compute_client.apitools_client.IncludeFields(cleared_fields): resources = list( request_helper.MakeRequests(requests=[(service, method, request)], http=self.http, batch_url=self.batch_url, errors=errors)) resources = lister.ProcessResults( resources=resources, field_selector=property_selector.PropertySelector( properties=None, transformations=self.transformations)) if errors: utils.RaiseToolException(errors) return resources
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client backend_service_ref = self._BACKEND_SERVICE_ARG.ResolveAsResource( args, holder.resources, default_scope=backend_services_utils.GetDefaultScope(), scope_lister=compute_flags.GetDefaultScopeLister(client)) get_request = self.GetGetRequest(client, backend_service_ref) objects = client.MakeRequests([get_request]) original_object = objects[0] original_record = encoding.MessageToDict(original_object) # Selects only the fields that can be modified. field_selector = property_selector.PropertySelector(properties=[ 'backends', 'description', 'enableCDN', 'healthChecks', 'iap.enabled', 'iap.oauth2ClientId', 'iap.oauth2ClientSecret', 'port', 'portName', 'protocol', 'timeoutSec', ]) modifiable_record = field_selector.Apply(original_record) file_contents = self.BuildFileContents(args, client, original_record, modifiable_record) resource_list = self.EditResource(args, backend_service_ref, file_contents, holder, modifiable_record, original_object, original_record) for resource in resource_list: yield resource
def TestFiltering(self, properties, expected): selector = property_selector.PropertySelector(properties=properties) self.assertEqual(selector.Apply(self.object), expected)
def testTrasnformations(self): selector = property_selector.PropertySelector(transformations=[ ('string', lambda x: x.upper()), ('dictOfDicts.dictOne.string', lambda x: x * 4), ('nonExistentKey.nonExistentKey', lambda _: 'Hello!'), ('listOfDicts[].string', lambda x: x * 3), ('anotherListOfDicts', lambda x: 'list replacement'), ('integerList[5]', lambda x: x**2), ('integerList[10]', lambda x: x**3), ('nested[].x[].y[]', lambda x: x**4), ]) res = selector.Apply(self.object) self.assertEqual( res, { 'string': 'ONE', 'integer': 123, 'integerList': [ 0, 1, 2, 3, 4, 25, 6, 7, 8, 9, 1000, 11, 12, 13, 14, 15, 16, 17, 18, 19 ], 'dict': { 'string': 'one', 'integer': 2 }, 'listOfDicts': [{ 'string': 'oneoneone', 'hello': 'world' }, { 'string': 'twotwotwo' }, { 'string': 'threethreethree', 'another': 'string' }], 'dictOfDicts': { 'dictOne': { 'string': 'oneoneoneone' }, 'dictTwo': { 'string': 'two', 'hello': 'world' }, 'dictThree': { 'string': 'three', 'another': 1 } }, 'anotherListOfDicts': 'list replacement', 'nested': [{ 'x': [{ 'y': [1, 16] }, { 'y': [16, 81] }], 'z': [555] }, { 'x': [{ 'y': [256, 625] }, { 'y': [625, 1296] }], 'z': [777] }] })