def testRemoveTargetPoolHealthCheckGeneratesCorrectRequest(self): expected_project = 'test-project' expected_target_pool = 'test-target-pool' expected_health_check = 'health-check1' expected_region = 'us-north1.a' set_flags = { 'project': expected_project, 'region': expected_region, 'health_check': expected_health_check, } command = self._CreateAndInitializeCommand( target_pool_cmds.RemoveTargetPoolHealthCheck, 'removetargetpoolhealthcheck', set_flags=set_flags) call = self.mock.Respond('compute.targetPools.removeHealthCheck', {}) command.Handle(expected_target_pool) request = call.GetRequest() self.assertEqual('POST', request.method) self.assertEqual(expected_project, request.parameters['project']) self.assertEqual(expected_region, request.parameters['region']) body = json.loads(request.body) # URLs will have an http/path prefix attached. if self.api.version == version.get('v1beta15'): self.assertTrue(body['healthCheck'].endswith('global/httpHealthChecks/' + expected_health_check)) elif self.api.version >= version.get('v1beta16'): health_checks = body['healthChecks'] self.assertEqual(len(health_checks), 1) self.assertTrue(health_checks[0]['healthCheck'].endswith( 'global/httpHealthChecks/' + expected_health_check))
def SelectTemplateForVersion(template_dict, apiversion): """Selects the most recent item from a dict compatible with apiversion. Args: template_dict: A dict of things to select from, usually templates in a unit test. apiversion: The API version to select for. Returns: An value from template_dict. """ selected_version = '' # By default, selected version will be the smallest in the dict. # This takes care of the edge case where the api version is smaller than # everything in the dict. for template in template_dict: if not selected_version or template < version.get(selected_version): selected_version = template # Now, we select the largest compatible version. for template in template_dict: if template <= apiversion and template > version.get(selected_version): selected_version = template return template_dict[selected_version]
def Handle(self, target_pool_name): """Remove the health check from the target pool. Args: target_pool_name: The name of the target_pool to update. Returns: The result of removing the health check from the target_pool. """ self._AutoDetectRegion() target_pool_context = self._context_parser.ParseContextOrPrompt( 'targetPools', target_pool_name) if self._flags.health_check is None: raise gcutil_errors.CommandError('Please specify a --health_check.') health_check = self._context_parser.NormalizeOrPrompt( 'httpHealthChecks', self._flags.health_check) if self.api.version == version.get('v1beta15'): target_pool_resource = { 'healthCheck': health_check, } elif self.api.version >= version.get('v1beta16'): target_pool_resource = { 'healthChecks': [{'healthCheck': health_check}] } kwargs = self._PrepareRequestArgs(target_pool_context) target_pool_request = self.api.target_pools.removeHealthCheck( body=target_pool_resource, **kwargs) return target_pool_request.execute()
def testRemoveTargetPoolInstanceGeneratesCorrectRequest(self): expected_project = 'test-project' expected_region = 'us-north1.a' expected_target_pool = 'test-target-pool' expected_instances = ['zone1/instances/instance1', 'zone2/instances/instance2'] set_flags = { 'project': expected_project, 'region': expected_region, 'instances': expected_instances, } command = self._CreateAndInitializeCommand( target_pool_cmds.RemoveTargetPoolInstance, 'removetargetpoolinstance', set_flags=set_flags) calls = [] if self.api.version == version.get('v1beta15'): for instance in expected_instances: calls.append(self.mock.Respond('compute.targetPools.removeInstance', {})) elif self.api.version >= version.get('v1beta16'): calls.append(self.mock.Respond('compute.targetPools.removeInstance', {})) command.Handle(expected_target_pool) actual_instances = [] if self.api.version == version.get('v1beta15'): for call in calls: request = call.GetRequest() self.assertEqual('POST', request.method) self.assertEqual(expected_project, request.parameters['project']) self.assertEqual(expected_region, request.parameters['region']) body = json.loads(request.body) instance = body['instance'] # Parse zone/instance from the request body actual_instances.append(instance) elif self.api.version >= version.get('v1beta16'): request = calls[0].GetRequest() self.assertEqual('POST', request.method) self.assertEqual(expected_project, request.parameters['project']) self.assertEqual(expected_region, request.parameters['region']) body = json.loads(request.body) for instance in body['instances']: instance_url = instance['instance'] actual_instances.append(instance_url) # Sort request instances, since there is no guarranteed order of execution. expected_instance_urls = [] for expected_instance in expected_instances: zone, _, instance = expected_instance.split('/') expected_instance_urls.append(unicode( command.NormalizePerZoneResourceName( command._project, zone, 'instances', instance))) self.assertEqual(sorted(actual_instances), sorted(expected_instance_urls))
def Handle(self, target_pool_name): """Remove the instance from the target pool. Args: target_pool_name: The name of the target_pool to update. Returns: The result of removing an instance from the target_pool. """ self._AutoDetectRegion() self._AutoDetectZoneForInstances() target_pool_context = self._context_parser.ParseContextOrPrompt( 'targetPools', target_pool_name) if not self._flags.instances and not self._flags.instance: raise gcutil_errors.CommandError('Please specify --instances.') if self._flags.instance: gcutil_logging.LOGGER.warn( '--instance flag is deprecated; use --instances to remove one or more' ' instances') instances = [self._flags.instance] else: instances = self._flags.instances requests = [] kwargs = self._PrepareRequestArgs(target_pool_context) instance_urls = [] for zone_instance in instances: try: path = self._context_parser.NormalizeOrPrompt( 'instances', zone_instance) except ValueError: zone, instance = self.ParseZoneInstancePair(zone_instance) path = self.NormalizePerZoneResourceName( self._project, zone, 'instances', instance) instance_urls.append(path) if self.api.version == version.get('v1beta15'): for instance in instance_urls: remove_instance_request_resource = {'instance': instance} requests.append(self.api.target_pools.removeInstance( body=remove_instance_request_resource, **kwargs)) elif self.api.version >= version.get('v1beta16'): remove_instance_request_resource = { 'instances': [{'instance': instance_url} for instance_url in instance_urls] } requests.append(self.api.target_pools.removeInstance( body=remove_instance_request_resource, **kwargs)) # This may be multiple API calls. return self.ExecuteRequests(requests)
def Handle(self, *target_instance_names): """Delete the specified target instances. Args: *target_instance_names: The names of the target instances to delete. Returns: Tuple (results, exceptions) - results of deleting the target instances. """ if self.api.version < version.get('v1'): raise gcutil_errors.UnsupportedCommand( 'This command is not supported in service version %s.' % self.api.version) self._AutoDetectZone() requests = [] for name in target_instance_names: target_instance_context = self._context_parser.ParseContextOrPrompt( 'targetInstances', name) requests.append( self.api.target_instances.delete( **self._PrepareRequestArgs(target_instance_context))) results, exceptions = self.ExecuteRequests(requests) return (self.MakeListResult(results, 'operationList'), exceptions)
def CreateApi(api_version): """Creates mock API for a given Google Compute Engine API version. Args: api_version: Version of the API demanded. For example: 'v1beta16'. Returns: Tuple (mock, api). mock is an instance of MockServer which can be used to program responses for specific requests, api is an instance of Google Compute Engine API (google-api-python-client). """ discovery_path = os.path.join( os.path.dirname(__file__), 'compute', '{version}.json'.format(version=api_version)) with open(discovery_path) as discovery_file: discovery_document = discovery_file.read() discovery_json = json.loads(discovery_document) parser = mock_api_parser.Parser(discovery_json) methods = parser.Parse() mock = mock_api_server.MockServer(methods) api = discovery.build_from_document( discovery_document, requestBuilder=mock.BuildRequest) return mock, gce_api.ComputeApi(api, version.get(discovery_json.get('version')), gce_api.GetSetOfApiMethods(discovery_json))
def __init__(self, api, api_version, methods): self.version = api_version self.methods = methods def GetCollectionOrNone(api, name): return getattr(api, name)() if hasattr(api, name) else None self.addresses = GetCollectionOrNone(api, 'addresses') self.disks = api.disks() self.disk_types = GetCollectionOrNone(api, 'diskTypes') self.firewalls = api.firewalls() self.forwarding_rules = GetCollectionOrNone(api, 'forwardingRules') self.global_operations = api.globalOperations() self.http_health_checks = GetCollectionOrNone(api, 'httpHealthChecks') self.images = api.images() self.instances = api.instances() if api_version < version.get('v1'): self.kernels = api.kernels() self.machine_types = api.machineTypes() self.networks = api.networks() self.projects = api.projects() self.region_operations = GetCollectionOrNone(api, 'regionOperations') self.regions = GetCollectionOrNone(api, 'regions') self.routes = api.routes() self.snapshots = api.snapshots() self.target_pools = GetCollectionOrNone(api, 'targetPools') self.target_instances = GetCollectionOrNone(api, 'targetInstances') self.zone_operations = api.zoneOperations() self.zones = api.zones()
def CreateApi(api_version): """Creates mock API for a given Google Compute Engine API version. Args: api_version: Version of the API demanded. For example: 'v1'. Returns: Tuple (mock, api). mock is an instance of MockServer which can be used to program responses for specific requests, api is an instance of Google Compute Engine API (google-api-python-client). """ discovery_path = os.path.join( os.path.dirname(__file__), 'compute', '{version}.json'.format(version=api_version)) with open(discovery_path) as discovery_file: discovery_document = discovery_file.read() discovery_json = json.loads(discovery_document) parser = mock_api_parser.Parser(discovery_json) methods = parser.Parse() mock = mock_api_server.MockServer(methods) api = discovery.build_from_document( discovery_document, requestBuilder=mock.BuildRequest) return mock, gce_api.ComputeApi(api, version.get(discovery_json.get('version')), gce_api.GetSetOfApiMethods(discovery_json))
def Handle(self, target_instance_name): """Add the specified target instance. Args: target_instance_name: The name of the target instance to add. Returns: The result of inserting the target instance. """ if self.api.version < version.get('v1'): raise gcutil_errors.UnsupportedCommand( 'This command is not supported in service version %s.' % self.api.version) self._GetZoneOrPrompt() target_instance_context = self._context_parser.ParseContextOrPrompt( 'targetInstances', target_instance_name) target_instance_resource = { 'kind': self._GetResourceApiKind('targetInstance'), 'name': target_instance_context['targetInstance'], 'description': self._flags.description, 'natPolicy': self._flags.nat_policy, 'instance': self._context_parser.NormalizeOrPrompt( 'instances', self._flags.instance) } kwargs = {'zone': target_instance_context['zone']} target_instance_request = (self.api.target_instances.insert( project=target_instance_context['project'], body=target_instance_resource, **kwargs)) return target_instance_request.execute()
def ListAggregatedFunc(self): """Returns the function for listing target instances across all zones.""" if self.api.version < version.get('v1'): raise gcutil_errors.UnsupportedCommand( 'This command is not supported in service version %s.' % self.api.version) else: return self.api.target_instances.aggregatedList
def ListFunc(self): """Returns the fuction for listing kernels.""" if self.api.version >= version.get('v1'): raise gcutil_errors.UnsupportedCommand( 'listkernels is no longer supported in service version v1. ' 'Please use --service_version=v1beta15 or ' '--service_version=v1beta16 in order to use listtkernels.') return self.api.kernels.list
def Handle(self, image_name, root_source_tarball): """Add the specified image. Args: image_name: The name of the image to add. root_source_tarball: Tarball in Google Storage containing the desired root directory for the resulting image. Returns: The result of inserting the image. """ image_context = self._context_parser.ParseContextOrPrompt('images', image_name) image_resource = { 'kind': self._GetResourceApiKind('image'), 'name': image_context['image'], 'description': self._flags.description, 'sourceType': 'RAW', } if root_source_tarball: # Accept gs:// URLs. if root_source_tarball.startswith('gs://'): root_source_tarball = ('http://storage.googleapis.com/' + root_source_tarball[len('gs://'):]) image_resource['rawDisk'] = { 'source': root_source_tarball, 'containerType': 'TAR', } if self.api.version <= version.get('v1beta16'): if self._flags['preferred_kernel'].present: if self._flags.preferred_kernel: image_resource['preferredKernel'] = ( self._context_parser.NormalizeOrPrompt( 'kernels', self._flags.preferred_kernel)) else: kernel = self._presenter.PromptForKernel(self.api.kernels) if kernel is not None: image_resource['preferredKernel'] = kernel['selfLink'] else: if self._flags.preferred_kernel: raise gcutil_errors.UnsupportedCommand( '--preferred_kernel is deprecated in v1. You may still specify ' 'a preferred kernel by using --service_version=v1beta16') image_request = self.api.images.insert(project=image_context['project'], body=image_resource) return image_request.execute()
def Handle(self, image_name, root_source_tarball=None): """Add the specified image. Args: image_name: The name of the image to add. root_source_tarball: Tarball in Google Storage containing the desired root directory for the resulting image. Returns: The result of inserting the image. """ image_context = self._context_parser.ParseContextOrPrompt( 'images', image_name) # Source Tarball and Source Disk are mutually exclusive parameters. if self.api.version >= version.get('v1'): if root_source_tarball and self._flags.source_disk: raise app.UsageError( 'You cannot specify both root_source_tarball and ' 'source_disk. Only one or the other.') if not root_source_tarball and not self._flags.source_disk: raise app.UsageError( 'You must specify either a root_source_tarball or ' 'a source_disk.') elif not root_source_tarball: raise app.UsageError('You must specify a root_source_tarball.') image_resource = { 'kind': self._GetResourceApiKind('image'), 'name': image_context['image'], 'description': self._flags.description, 'sourceType': 'RAW', } if root_source_tarball: # Accept gs:// URLs. if root_source_tarball.startswith('gs://'): root_source_tarball = ('http://storage.googleapis.com/' + root_source_tarball[len('gs://'):]) image_resource['rawDisk'] = { 'source': root_source_tarball, 'containerType': 'TAR', } elif self._flags.source_disk: self._AutoDetectZone() disk_url = self._context_parser.NormalizeOrPrompt( 'disks', self._flags.source_disk) image_resource['sourceDisk'] = disk_url image_request = self.api.images.insert( project=image_context['project'], body=image_resource) return image_request.execute()
def Handle(self, image_name, root_source_tarball=None): """Add the specified image. Args: image_name: The name of the image to add. root_source_tarball: Tarball in Google Storage containing the desired root directory for the resulting image. Returns: The result of inserting the image. """ image_context = self._context_parser.ParseContextOrPrompt('images', image_name) # Source Tarball and Source Disk are mutually exclusive parameters. if self.api.version >= version.get('v1'): if root_source_tarball and self._flags.source_disk: raise app.UsageError('You cannot specify both root_source_tarball and ' 'source_disk. Only one or the other.') if not root_source_tarball and not self._flags.source_disk: raise app.UsageError('You must specify either a root_source_tarball or ' 'a source_disk.') elif not root_source_tarball: raise app.UsageError('You must specify a root_source_tarball.') image_resource = { 'kind': self._GetResourceApiKind('image'), 'name': image_context['image'], 'description': self._flags.description, 'sourceType': 'RAW', } if root_source_tarball: # Accept gs:// URLs. if root_source_tarball.startswith('gs://'): root_source_tarball = ('http://storage.googleapis.com/' + root_source_tarball[len('gs://'):]) image_resource['rawDisk'] = { 'source': root_source_tarball, 'containerType': 'TAR', } elif self._flags.source_disk: self._AutoDetectZone() disk_url = self._context_parser.NormalizeOrPrompt( 'disks', self._flags.source_disk) image_resource['sourceDisk'] = disk_url image_request = self.api.images.insert(project=image_context['project'], body=image_resource) return image_request.execute()
def _DoTestAddImageGeneratesCorrectRequest( self, requested_source, expected_source, submitted_kernel, expected_kernel, requested_image, expected_image, project_flag, expected_project): expected_description = 'test image' expected_type = 'RAW' set_flags = { 'project': project_flag, 'description': expected_description, } if self.version <= version.get('v1beta16'): set_flags['preferred_kernel'] = submitted_kernel command = self._CreateAndInitializeCommand( image_cmds.AddImage, 'addimage', self.version, set_flags) call = self.mock.Respond( 'compute.images.insert', { 'kind': 'compute#operation', }) unused_result = command.Handle(requested_image, requested_source) request = call.GetRequest() self.assertEquals('POST', request.method) parameters = request.parameters body = json.loads(request.body) self.assertEqual(parameters['project'], expected_project) self.assertEqual(body['name'], expected_image) self.assertEqual(body['description'], expected_description) if command.api.version < version.get('v1'): self.assertEqual(body['preferredKernel'], expected_kernel) self.assertEqual(body['sourceType'], expected_type) self.assertEqual(body['rawDisk']['source'], expected_source)
def testDeprecatedFlags(self): if self.version <= version.get('v1beta16'): return set_flags = { 'project': 'test', 'description': 'description', 'preferred_kernel': 'kernel', } command = self._CreateAndInitializeCommand( image_cmds.AddImage, 'addimage', self.version, set_flags) self.assertRaises(gcutil_errors.UnsupportedCommand, command.Handle, 'image', 'source')
def testCreateImageFromArchiveAndDiskThrowsUsageError(self): if self.version < version.get('v1'): return set_flags = { 'project': 'test', 'description': 'description', 'source_disk': 'disk', 'zone': 'zone', } command = self._CreateAndInitializeCommand( image_cmds.AddImage, 'addimage', self.version, set_flags) self.assertRaises(app.UsageError, command.Handle, 'image', 'source')
def testAddImageFromDiskGeneratesCorrectRequest(self): if self.version < version.get('v1'): return test_cases = [{ 'requested_image': 'test_image', 'expected_image': 'test_image', 'project_flag': 'test_project', 'expected_project': 'test_project', 'source_disk': 'test_disk', 'expected_source_disk': ( 'https://www.googleapis.com/compute/' + self.version + '/projects/test_project/zones/dev-central1-std/disks/test_disk'), 'zone': 'dev-central1-std', }] for test_case in test_cases: self._DoTestAddImageFromDiskGeneratesCorrectRequest(**test_case)
def Handle(self, *args, **kwargs): """The point of entry to the command. This dispatches the subclass' HandleMove method. """ if self.api.version != version.get('v1'): raise gcutil_errors.UnsupportedCommand( 'Moving instances is supported only in service version v1.') self._project = utils.GetProjectId(self._project, self.api) self._project_resource = self.api.projects.get( project=self._project).execute() if self.api.addresses: self._address_list = utils.AllAggregated( self.api.addresses.aggregatedList, self._project) self.HandleMove(*args, **kwargs) print 'The move completed successfully.'
def Handle(self, *args, **kwargs): """The point of entry to the command. This dispatches the subclass' HandleMove method. """ if self.api.version > version.get('v1beta16'): raise gcutil_errors.UnsupportedCommand( 'Moving instances is not supported in v1 yet. You may still use this ' 'subcommand by specifying --service_version=v1beta15 or ' '--service_version=v1beta16.') self._project_resource = self.api.projects.get( project=self._project).execute() if self.api.addresses: self._address_list = utils.AllAggregated( self.api.addresses.aggregatedList, self._project) self.HandleMove(*args, **kwargs) print 'The move completed successfully.'
def _VerifyAndGetTargetFromFlags( self, target_pool_flag, target_instance_flag): """Gets forwarding rule target from flag values. Args: target_pool_flag: the value of --target_pool flag target_instance_flag: the value of --target_instance flag Returns: (target_pool, target_instance) pair, with one and only one field set. """ if (target_pool_flag is None) == (target_instance_flag is None): raise gcutil_errors.CommandError('Please specify exactly one of ' '--target_pool or --target_instance.') elif target_pool_flag: return target_pool_flag, None else: if self.api.version < version.get('v1'): raise gcutil_errors.CommandError( 'Version does not support target instance.') return None, target_instance_flag
def Handle(self, kernel_name): """Get the specified kernel. Args: kernel_name: The name of the kernel to get. Returns: The result of getting the kernel. """ if self.api.version >= version.get("v1"): raise gcutil_errors.UnsupportedCommand( "getkernel is no longer supported in service version v1. " "Please use --service_version=v1beta16" "in order to use getkernel." ) kernel_context = self._context_parser.ParseContextOrPrompt("kernels", kernel_name) kernel_request = self.api.kernels.get(project=kernel_context["project"], kernel=kernel_context["kernel"]) return kernel_request.execute()
def Handle(self, target_instance_name): """Add the specified target instance. Args: target_instance_name: The name of the target instance to add. Returns: The result of inserting the target instance. """ if self.api.version < version.get('v1'): raise gcutil_errors.UnsupportedCommand( 'This command is not supported in service version %s.' % self.api.version) self._GetZoneOrPrompt() target_instance_context = self._context_parser.ParseContextOrPrompt( 'targetInstances', target_instance_name) target_instance_resource = { 'kind': self._GetResourceApiKind('targetInstance'), 'name': target_instance_context['targetInstance'], 'description': self._flags.description, 'natPolicy': self._flags.nat_policy, 'instance': self._context_parser.NormalizeOrPrompt('instances', self._flags.instance) } kwargs = {'zone': target_instance_context['zone']} target_instance_request = (self.api.target_instances.insert( project=target_instance_context['project'], body=target_instance_resource, **kwargs)) return target_instance_request.execute()
def Handle(self, target_instance_name): """Get the specified target instance. Args: target_instance_name: The name of the target instance to get. Returns: The result of getting the target instance. """ if self.api.version < version.get('v1'): raise gcutil_errors.UnsupportedCommand( 'This command is not supported in service version %s.' % self.api.version) self._AutoDetectZone() target_instance_context = self._context_parser.ParseContextOrPrompt( 'targetInstances', target_instance_name) target_instance_request = self.api.target_instances.get( **self._PrepareRequestArgs(target_instance_context)) return target_instance_request.execute()
def Handle(self, *target_instance_names): """Delete the specified target instances. Args: *target_instance_names: The names of the target instances to delete. Returns: Tuple (results, exceptions) - results of deleting the target instances. """ if self.api.version < version.get('v1'): raise gcutil_errors.UnsupportedCommand( 'This command is not supported in service version %s.' % self.api.version) self._AutoDetectZone() requests = [] for name in target_instance_names: target_instance_context = self._context_parser.ParseContextOrPrompt( 'targetInstances', name) requests.append(self.api.target_instances.delete( **self._PrepareRequestArgs(target_instance_context))) results, exceptions = self.ExecuteRequests(requests) return (self.MakeListResult(results, 'operationList'), exceptions)
def Handle(self, *disk_names): """Add the specified disks. Args: *disk_names: The names of the disks to add. Returns: A tuple of (results, exceptions). Raises: CommandError: If the command is unsupported in this API version. UsageError: If no disk names are specified. """ if not disk_names: raise app.UsageError('Please specify at least one disk name.') if self._flags.source_image and self._flags.source_snapshot: raise app.UsageError('You must specify either a source_image or a' 'source_snapshot but not both.') perf_min = PERFORMANCE_WARNING_SIZE_GB[self._flags.disk_type] if (not self._flags.source_image and self._flags.size_gb and self._flags.size_gb < perf_min): LOGGER.warn(('You have selected a volume size of under %s GB. ' 'This may result in reduced performance. ' 'For sizing and performance guidelines, see ' 'https://developers.google.com/compute/docs/disks' '#pdperformance.') % PERFORMANCE_WARNING_SIZE_GB[self._flags.disk_type]) self._PromptForZoneOnlyOnce() kind = self._GetResourceApiKind('disk') source_image = None if self._flags.source_image: source_image = self._context_parser.NormalizeOrPrompt( 'images', command_base.ResolveImageTrackOrImage( self.api.images, self._flags.project, self._flags.source_image, lambda image: self._presenter.PresentElement(image['selfLink']))) source_snapshot = None if self._flags.source_snapshot: source_snapshot = self._context_parser.NormalizeOrPrompt( 'snapshots', self._flags.source_snapshot) requests = [] for name in disk_names: disk_context = self._context_parser.ParseContextOrPrompt('disks', name) disk = { 'kind': kind, 'name': disk_context['disk'], 'description': self._flags.description, } kwargs = { 'zone': disk_context['zone'] } if source_snapshot is not None: disk['sourceSnapshot'] = source_snapshot if self._flags.size_gb: disk['sizeGb'] = self._flags.size_gb elif source_image is not None: kwargs['sourceImage'] = source_image if self._flags.size_gb: disk['sizeGb'] = self._flags.size_gb else: disk_type_default = str(DEFAULT_DISK_SIZE_GB[self._flags.disk_type]) disk['sizeGb'] = (self._flags.size_gb or disk_type_default) if self.api.version >= version.get('v1') and self._flags.disk_type: disk['type'] = self._context_parser.NormalizeOrPrompt( 'diskTypes', self._flags.disk_type) requests.append(self.api.disks.insert(project=disk_context['project'], body=disk, **kwargs)) wait_for_operations = ( self._flags.wait_until_complete or self._flags.synchronous_mode) (results, exceptions) = self.ExecuteRequests( requests, wait_for_operations=wait_for_operations) if self._flags.wait_until_complete: awaiting = (result for result in results if result['kind'] == 'compute#disk') results = [] for result in awaiting: if 'error' not in result: result = self._WaitUntilDiskIsComplete(result) results.append(result) list_type = 'diskList' if self._flags.synchronous_mode else 'operationList' return (self.MakeListResult(results, list_type), exceptions)
def _DoTestAddDisks(self, service_version, disks, source_snapshot=None, size=None, source_image=None, wait_until_complete=None): expected_kind = 'compute#disk' expected_project = 'test_project' expected_description = 'test disk' expected_zone = 'copernicus-moon-base' provisioning_calls = 1 set_flags = { 'zone': expected_zone, 'project': expected_project, 'size_gb': size, 'source_image': source_image, 'description': expected_description, 'wait_until_complete': wait_until_complete, 'sleep_between_polls': 0.1, 'source_snapshot': source_snapshot } expected_disk_type = 'pd-ssd' set_flags['disk_type'] = expected_disk_type command = self._CreateAndInitializeCommand( disk_cmds.AddDisk, 'adddisk', service_version, set_flags) # If an image is specified, we will simply fall through the image resolver. if source_image: mock_lists.MockImageListForCustomerAndStandardProjects(command, self.mock) if wait_until_complete: # Spend some queries in provisioning state. provisioning = [provisioning_calls] def GetResponse(unused_uri, unused_http_method, parameters, unused_body): if provisioning[0]: status = 'PROVISIONING' provisioning[0] -= 1 else: status = 'READY' return self.mock.MOCK_RESPONSE( { 'kind': 'compute#disk', 'name': parameters['disk'], 'zone': command.NormalizeGlobalResourceName(expected_project, 'zones', parameters['zone']), 'status': status }, False) getcall = self.mock.RespondF('compute.disks.get', GetResponse) def DiskResponse(unused_uri, unused_http_method, parameters, body): return self.mock.MOCK_RESPONSE( { 'kind': 'compute#disk', 'name': json.loads(body)['name'], 'zone': command.NormalizeGlobalResourceName(expected_project, 'zones', parameters['zone']), 'selfLink': command.NormalizePerZoneResourceName( expected_project, parameters['zone'], 'disks', json.loads(body)['name']), 'status': 'PROVISIONING' }, False) diskcall = self.mock.RespondF('compute.disks.insert', DiskResponse) # Make the call and ensure that nothing went wrong. results, exceptions = command.Handle(*disks) self.assertEqual([], exceptions) results = results['items'] self.assertEqual(len(results), len(disks)) # If we waited for completion, validate the "get" calls. if wait_until_complete: get_requests = getcall.GetAllRequests() self.assertEqual(provisioning_calls + len(disks), len(get_requests)) for request in get_requests: self.assertEqual(expected_zone, request.parameters['zone']) self.assertTrue(request.parameters['disk'] in disks) # Validate the "insert" calls. remaining_disks = disks for request in diskcall.GetAllRequests(): parameters = request.parameters body = json.loads(request.body) self.assertEqual(expected_project, parameters['project']) self.assertEqual(expected_kind, body['kind']) self.assertEqual(expected_description, body['description']) if self.version >= version.get('v1'): expected_normalized_disk_type = command.NormalizePerZoneResourceName( expected_project, expected_zone, 'diskTypes', expected_disk_type) self.assertEqual(expected_normalized_disk_type, body['type']) self.assertEqual(expected_zone, parameters['zone']) self.assertFalse('zone' in body) if size: self.assertEqual(size, body['sizeGb']) if source_snapshot: self.assertTrue(body['sourceSnapshot'].endswith(source_snapshot)) elif source_image: self.assertTrue(parameters['sourceImage'].endswith(source_image)) elif not size: self.assertEqual('100', body['sizeGb']) self.assertTrue(body['name'] in remaining_disks) remaining_disks = [disk for disk in remaining_disks if disk != body['name']]
def testApiVersion(self): api_version = version.get(self.version) self.assertTrue(api_version is not None) self.assertEqual(self.version.split('_')[-1], api_version._name)
def CreateComputeApi( http, api_version, download=False, server=None): """Builds the Google Compute Engine API to use. Args: http: a httplib2.Http like object for communication. api_version: the version of the API to create. download: bool. Download the discovery document from the discovery service. server: URL of the API service host. Returns: The ComputeApi object to use. Raises: gcutil_errors.CommandError: If loading the discovery doc fails. """ # Use default server if none provided. default_server = 'https://www.googleapis.com/' server = server or default_server # Load the discovery document. discovery_document = None # Try to download the discovery document if download or server != default_server: url = '{server}/discovery/v1/apis/compute/{version}/rest'.format( server=server.rstrip('/'), version=api_version) response, content = http.request(url) if response.status == 200: discovery_document = content else: raise gcutil_errors.CommandError( 'Could not load discovery document from %s:\n%s' % ( url, content)) else: # Try to load locally discovery_path = os.path.join( os.path.dirname(__file__), 'compute', '%s.json' % api_version) try: with open(discovery_path) as discovery_file: discovery_document = discovery_file.read() except IOError as err: raise gcutil_errors.CommandError( 'Could not load discovery document from %s:\n%s' % ( discovery_path, err)) try: discovery_document = json.loads(discovery_document) except ValueError: raise errors.InvalidJsonError() api = discovery.build_from_document( discovery_document, http=http, model=model.JsonModel()) api = WrapApiIfNeeded(api) return ComputeApi( api, version.get(discovery_document.get('version')), GetSetOfApiMethods(discovery_document))
def CreateMockApi(): return gce_api.ComputeApi(MockApi(), version.get('v1beta15'), None)
def CreateMockApi(service_version='v1'): return gce_api.ComputeApi(MockApi(), version.get(service_version), None)
def ListAggregatedFunc(self): """Returns the function for listing forwarding rules across all regions.""" if self.api.version >= version.get('v1beta15'): return self.api.forwarding_rules.aggregatedList
def ListAggregatedFunc(self): """Returns the function for listing target pools across all regions.""" if self.api.version >= version.get('v1beta15'): return self.api.target_pools.aggregatedList
def _DoTestAddDisks(self, service_version, disks, source_snapshot=None, size=None, source_image=None, wait_until_complete=None): expected_kind = 'compute#disk' expected_project = 'test_project' expected_description = 'test disk' expected_zone = 'copernicus-moon-base' provisioning_calls = 1 set_flags = { 'zone': expected_zone, 'project': expected_project, 'size_gb': size, 'source_image': source_image, 'description': expected_description, 'wait_until_complete': wait_until_complete, 'sleep_between_polls': 0.1, 'source_snapshot': source_snapshot } expected_disk_type = 'pd-ssd' set_flags['disk_type'] = expected_disk_type command = self._CreateAndInitializeCommand(disk_cmds.AddDisk, 'adddisk', service_version, set_flags) # If an image is specified, we will simply fall through the image resolver. if source_image: mock_lists.MockImageListForCustomerAndStandardProjects( command, self.mock) if wait_until_complete: # Spend some queries in provisioning state. provisioning = [provisioning_calls] def GetResponse(unused_uri, unused_http_method, parameters, unused_body): if provisioning[0]: status = 'PROVISIONING' provisioning[0] -= 1 else: status = 'READY' return self.mock.MOCK_RESPONSE( { 'kind': 'compute#disk', 'name': parameters['disk'], 'zone': command.NormalizeGlobalResourceName( expected_project, 'zones', parameters['zone']), 'status': status }, False) getcall = self.mock.RespondF('compute.disks.get', GetResponse) def DiskResponse(unused_uri, unused_http_method, parameters, body): return self.mock.MOCK_RESPONSE( { 'kind': 'compute#disk', 'name': json.loads(body)['name'], 'zone': command.NormalizeGlobalResourceName( expected_project, 'zones', parameters['zone']), 'selfLink': command.NormalizePerZoneResourceName( expected_project, parameters['zone'], 'disks', json.loads(body)['name']), 'status': 'PROVISIONING' }, False) diskcall = self.mock.RespondF('compute.disks.insert', DiskResponse) # Make the call and ensure that nothing went wrong. results, exceptions = command.Handle(*disks) self.assertEqual([], exceptions) results = results['items'] self.assertEqual(len(results), len(disks)) # If we waited for completion, validate the "get" calls. if wait_until_complete: get_requests = getcall.GetAllRequests() self.assertEqual(provisioning_calls + len(disks), len(get_requests)) for request in get_requests: self.assertEqual(expected_zone, request.parameters['zone']) self.assertTrue(request.parameters['disk'] in disks) # Validate the "insert" calls. remaining_disks = disks for request in diskcall.GetAllRequests(): parameters = request.parameters body = json.loads(request.body) self.assertEqual(expected_project, parameters['project']) self.assertEqual(expected_kind, body['kind']) self.assertEqual(expected_description, body['description']) if self.version >= version.get('v1'): expected_normalized_disk_type = command.NormalizePerZoneResourceName( expected_project, expected_zone, 'diskTypes', expected_disk_type) self.assertEqual(expected_normalized_disk_type, body['type']) self.assertEqual(expected_zone, parameters['zone']) self.assertFalse('zone' in body) if size: self.assertEqual(size, body['sizeGb']) if source_snapshot: self.assertTrue( body['sourceSnapshot'].endswith(source_snapshot)) elif source_image: self.assertTrue( parameters['sourceImage'].endswith(source_image)) elif not size: self.assertEqual('100', body['sizeGb']) self.assertTrue(body['name'] in remaining_disks) remaining_disks = [ disk for disk in remaining_disks if disk != body['name'] ]
def CreateMockApi(service_version='v1beta16'): return gce_api.ComputeApi(MockApi(), version.get(service_version), None)