def testDelete_MultiServiceAllVersions(self): """Same as above, with multiple services whose versions are all deleted.""" self._ExpectListAllServicesAndVersions() services = [service_util.Service(self.Project(), 'service2'), service_util.Service(self.Project(), 'service3')] versions = [version_util.Version(self.Project(), 'service1', 'v1'), version_util.Version(self.Project(), 'service1', 'v2')] self.ExpectDeleteServicesAndVersions(services, versions) self.Run('app versions delete v1 v2 v5') self.AssertServiceMessages(services) self.AssertVersionMessages(versions)
def testDelete_OneServiceOnlyVersions(self): """Test `delete` command where all versions deleted in a service.""" self._ExpectListAllVersionsForServices(['service3']) services = [service_util.Service(self.Project(), 'service3')] self.ExpectDeleteServicesAndVersions(services=services) self.Run('app versions delete v5 --service=service3') self.AssertServiceMessages(services)
def Run(self, args): client = appengine_api_client.GetApiClientForTrack(self.ReleaseTrack()) if args.service: service = client.GetServiceResource(args.service) traffic_split = {} if service.split: for split in service.split.allocations.additionalProperties: traffic_split[split.key] = split.value services = [service_util.Service(client.project, service.id, traffic_split)] else: services = client.ListServices() all_versions = client.ListVersions(services) if args.version not in {v.id for v in all_versions}: if args.service: raise VersionsMigrateError('Version [{0}/{1}] does not exist.'.format( args.service, args.version)) else: raise VersionsMigrateError('Version [{0}] does not exist.'.format( args.version)) service_names = {v.service for v in all_versions if v.id == args.version} def WillBeMigrated(v): return (v.service in service_names and v.traffic_split and v.traffic_split > 0 and v.id != args.version) # All versions that will stop receiving traffic. versions_to_migrate = list(six.moves.filter(WillBeMigrated, all_versions)) for version in versions_to_migrate: short_name = '{0}/{1}'.format(version.service, version.id) promoted_name = '{0}/{1}'.format(version.service, args.version) log.status.Print('Migrating all traffic from version ' '[{0}] to [{1}]'.format( short_name, promoted_name)) console_io.PromptContinue(cancel_on_no=True) errors = {} for service in sorted(set([v.service for v in versions_to_migrate])): allocations = {args.version: 1.0} try: operations_util.CallAndCollectOpErrors( client.SetTrafficSplit, service, allocations, shard_by='ip', migrate=True) except (operations_util.MiscOperationError) as err: errors[service] = str(err) if errors: error_string = ('Issues migrating all traffic of ' 'service(s): [{0}]\n\n{1}'.format( ', '.join(list(errors.keys())), '\n\n'.join(list(errors.values())))) raise VersionsMigrateError(error_string)
def ListServices(self): """Lists all services for the given application. Returns: A list of service_util.Service objects. """ request = self.messages.AppengineAppsModulesListRequest( name=self._FormatApp(self.project)) response = requests.MakeRequest(self.client.apps_modules.List, request) services = [] for s in response.modules: traffic_split = {} for split in s.split.allocations.additionalProperties: traffic_split[split.key] = split.value service = service_util.Service(self.project, s.id, traffic_split) services.append(service) return services
def ListServices(self): """Lists all services for the given application. Returns: A list of service_util.Service objects. """ request = self.messages.AppengineAppsServicesListRequest( parent=self._FormatApp()) services = [] for service in list_pager.YieldFromList( self.client.apps_services, request, field='services', batch_size=100, batch_size_attribute='pageSize'): traffic_split = {} if service.split: for split in service.split.allocations.additionalProperties: traffic_split[split.key] = split.value services.append( service_util.Service(self.project, service.id, traffic_split)) return services