def _PerformRollback(self, deployment_name, error_message): # Print information about the failure. log.warn('There was an error deploying ' + deployment_name + ':\n' + error_message) log.status.Print('`--automatic-rollback-on-error` flag was supplied; ' 'deleting failed deployment...') # Delete the deployment. try: delete_operation = self.client.deployments.Delete( self.messages.DeploymentmanagerDeploymentsDeleteRequest( project=dm_base.GetProject(), deployment=deployment_name, ) ) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT) # TODO(b/37481635): Use gcloud default operation polling. dm_write.WaitForOperation(self.client, self.messages, delete_operation.name, 'delete', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) completed_operation = dm_api_util.GetOperation(self.client, self.messages, delete_operation, dm_base.GetProject()) return completed_operation
def Run(self, args): """Run 'operations wait'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Raises: HttpException: An http error response was received while executing api request. Raises: OperationError: Operation finished with error(s) or timed out. """ failed_ops = [] for operation_name in args.operation_name: try: dm_write.WaitForOperation(self.client, self.messages, operation_name, '', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) except exceptions.OperationError: failed_ops.append(operation_name) if failed_ops: if len(failed_ops) == 1: raise exceptions.OperationError( 'Operation %s failed to complete or has errors.' % failed_ops[0]) else: raise exceptions.OperationError( 'Some operations failed to complete without errors:\n' + '\n'.join(failed_ops)) else: log.status.Print('All operations completed successfully.')
def wait(self, operation, action=None, get=True): """Waits for a DM operation to be completed. Args: operation (Operation): An Operation object from the SDK. action (string): Any operation name to be used in the ticker. If not specified, the operation type is used. get (boolean): wether to retrieve the latest deployment info from the API to obtain the current fingerprint. """ # This saves an API call if the self.get() was called just # before calling this method if get: self.get() action = action or operation.operationType dm_write.WaitForOperation( self.client, self.messages, operation.name, project=self.config['project'], timeout=self.OPERATION_TIMEOUT, operation_description='{} {} (fingerprint {})'.format( action, self.config['name'], base64.urlsafe_b64encode(self.current.fingerprint))) return self.get()
def testOperationTookTooLong(self): # only one poll because we don't poll every second self.WithOperationPolling(operation_type='op', poll_attempts=3, require_final_poll=False) with self.assertRaisesRegex( exceptions.Error, re.compile(r'.*' + OPERATION_NAME + '.*exceeded timeout.*')): dm_write.WaitForOperation(self.client, self.messages, OPERATION_NAME, project=self.Project(), timeout=3) self.AssertErrContains('Waiting for [op-123]') self.AssertErrNotContains('Created endpoint [foo].')
def Run(self, args): """Run 'deployments update'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns a struct containing the list of resources and list of outputs in the deployment. Raises: HttpException: An http error response was received while executing api request. """ deployment_ref = self.resources.Parse( args.deployment_name, params={'project': properties.VALUES.core.project.GetOrFail}, collection='deploymentmanager.deployments') if not args.IsSpecified('format') and args. async: args.format = flags.OPERATION_FORMAT patch_request = False deployment = self.messages.Deployment(name=deployment_ref.deployment, ) if not (args.config is None and args.template is None and args.composite_type is None): deployment.target = importer.BuildTargetConfig( self.messages, config=args.config, template=args.template, composite_type=args.composite_type, properties=args.properties) elif (self.ReleaseTrack() in [base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA] and args.manifest_id): deployment.target = importer.BuildTargetConfigFromManifest( self.client, self.messages, dm_base.GetProject(), deployment_ref.deployment, args.manifest_id, args.properties) # Get the fingerprint from the deployment to update. try: current_deployment = self.client.deployments.Get( self.messages.DeploymentmanagerDeploymentsGetRequest( project=dm_base.GetProject(), deployment=deployment_ref.deployment)) if args.fingerprint: deployment.fingerprint = dm_util.DecodeFingerprint( args.fingerprint) else: # If no fingerprint is present, default to an empty fingerprint. # TODO(b/34966984): Remove the empty default after cleaning up all # deployments that has no fingerprint deployment.fingerprint = current_deployment.fingerprint or b'' # Get the credential from the deployment to update. if self.ReleaseTrack() in [base.ReleaseTrack.ALPHA ] and args.credential: deployment.credential = dm_util.CredentialFrom( self.messages, args.credential) # Update the labels of the deployment deployment.labels = self._GetUpdatedDeploymentLabels( args, current_deployment) # If no config or manifest_id are specified, but try to update labels, # only add patch_request header when directly updating a non-previewed # deployment no_manifest = (self.ReleaseTrack() is base.ReleaseTrack.GA) or not args.manifest_id patch_request = not args.config and no_manifest and (bool( args.update_labels) or bool(args.remove_labels)) if args.description is None: deployment.description = current_deployment.description elif not args.description or args.description.isspace(): deployment.description = None else: deployment.description = args.description except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT) if patch_request: args.format = flags.DEPLOYMENT_FORMAT try: # Necessary to handle API Version abstraction below parsed_delete_flag = Update._delete_policy_flag_map.GetEnumForChoice( args.delete_policy).name if self.ReleaseTrack() in [ base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA ]: parsed_create_flag = ( Update._create_policy_v2beta_flag_map.GetEnumForChoice( args.create_policy).name) else: parsed_create_flag = ( Update._create_policy_flag_map.GetEnumForChoice( args.create_policy).name) request = self.messages.DeploymentmanagerDeploymentsUpdateRequest( deploymentResource=deployment, project=dm_base.GetProject(), deployment=deployment_ref.deployment, preview=args.preview, createPolicy=( self.messages.DeploymentmanagerDeploymentsUpdateRequest. CreatePolicyValueValuesEnum(parsed_create_flag)), deletePolicy=( self.messages.DeploymentmanagerDeploymentsUpdateRequest. DeletePolicyValueValuesEnum(parsed_delete_flag))) client = self.client client.additional_http_headers['X-Cloud-DM-Patch'] = patch_request operation = client.deployments.Update(request) # Fetch and print the latest fingerprint of the deployment. updated_deployment = dm_api_util.FetchDeployment( self.client, self.messages, dm_base.GetProject(), deployment_ref.deployment) if patch_request: if args. async: log.warning( 'Updating Deployment metadata is synchronous, --async flag ' 'is ignored.') log.status.Print( 'Update deployment metadata completed successfully.') return updated_deployment dm_util.PrintFingerprint(updated_deployment.fingerprint) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT) if args. async: return operation else: op_name = operation.name try: operation = dm_write.WaitForOperation( self.client, self.messages, op_name, 'update', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) dm_util.LogOperationStatus(operation, 'Update') except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT) return dm_api_util.FetchResourcesAndOutputs( self.client, self.messages, dm_base.GetProject(), deployment_ref.deployment, self.ReleaseTrack() is base.ReleaseTrack.ALPHA)
def Run(self, args): """Run 'deployments update'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns a struct containing the list of resources and list of outputs in the deployment. Raises: HttpException: An http error response was received while executing api request. """ deployment = dm_base.GetMessages().Deployment( name=args.deployment_name, ) if args.config: deployment.target = importer.BuildTargetConfig( dm_base.GetMessages(), args.config, args.properties) elif (self.ReleaseTrack() in [base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA] and args.manifest_id): deployment.target = importer.BuildTargetConfigFromManifest( dm_base.GetClient(), dm_base.GetMessages(), dm_base.GetProject(), args.deployment_name, args.manifest_id, args.properties) # Get the fingerprint from the deployment to update. try: current_deployment = dm_base.GetClient().deployments.Get( dm_base.GetMessages().DeploymentmanagerDeploymentsGetRequest( project=dm_base.GetProject(), deployment=args.deployment_name)) # Update the labels of the deployment if self.ReleaseTrack() in [base.ReleaseTrack.ALPHA]: update_labels = labels_util.GetUpdateLabelsDictFromArgs(args) remove_labels = labels_util.GetRemoveLabelsListFromArgs(args) current_labels = current_deployment.labels deployment.labels = dm_labels.UpdateLabels( current_labels, dm_base.GetMessages().DeploymentLabelEntry, update_labels, remove_labels) # If no config or manifest_id are specified, but try to update labels, # only get current manifest when it is not a preveiw request if not args.config and not args.manifest_id: if args.update_labels or args.remove_labels: if not args.preview: current_manifest = dm_v2_util.ExtractManifestName( current_deployment) deployment.target = importer.BuildTargetConfigFromManifest( dm_base.GetClient(), dm_base.GetMessages(), dm_base.GetProject(), args.deployment_name, current_manifest) # If no fingerprint is present, default to an empty fingerprint. # This empty default can be removed once the fingerprint change is # fully implemented and all deployments have fingerprints. deployment.fingerprint = current_deployment.fingerprint or '' if args.description is None: deployment.description = current_deployment.description elif not args.description or args.description.isspace(): deployment.description = None else: deployment.description = args.description except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) try: operation = dm_base.GetClient().deployments.Update( dm_base.GetMessages( ).DeploymentmanagerDeploymentsUpdateRequest( deploymentResource=deployment, project=dm_base.GetProject(), deployment=args.deployment_name, preview=args.preview, createPolicy=(dm_base.GetMessages( ).DeploymentmanagerDeploymentsUpdateRequest. CreatePolicyValueValuesEnum( args.create_policy)), deletePolicy=(dm_base.GetMessages( ).DeploymentmanagerDeploymentsUpdateRequest. DeletePolicyValueValuesEnum( args.delete_policy)), )) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) if args. async: return operation else: op_name = operation.name try: dm_write.WaitForOperation(op_name, 'update', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) log.status.Print('Update operation ' + op_name + ' completed successfully.') except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) return dm_v2_util.FetchResourcesAndOutputs(dm_base.GetClient(), dm_base.GetMessages(), dm_base.GetProject(), args.deployment_name)
def Run(self, args): """Run 'deployments delete'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns boolean indicating whether insert operation succeeded. Raises: HttpException: An http error response was received while executing api request. """ prompt_message = ('The following deployments will be deleted:\n- ' + '\n- '.join(args.deployment_name)) if not args.quiet: if not console_io.PromptContinue(message=prompt_message, default=False): raise exceptions.OperationError('Deletion aborted by user.') operations = [] errors = [] for deployment_name in args.deployment_name: deployment_ref = self.resources.Parse( deployment_name, params={'project': properties.VALUES.core.project.GetOrFail}, collection='deploymentmanager.deployments') try: operation = self.client.deployments.Delete( self.messages.DeploymentmanagerDeploymentsDeleteRequest( project=dm_base.GetProject(), deployment=deployment_ref.deployment, deletePolicy=(Delete._delete_policy_flag_map. GetEnumForChoice(args.delete_policy)), ) ) if args.async: operations.append(operation) else: op_name = operation.name try: # TODO(b/62720778): Refactor to use waiter.CloudOperationPoller operation = dm_write.WaitForOperation( self.client, self.messages, op_name, 'delete', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) dm_util.LogOperationStatus(operation, 'Delete') except exceptions.OperationError as e: errors.append(exceptions.OperationError( u'Delete operation {0} failed.\n{1}'.format(op_name, e))) completed_operation = self.client.operations.Get( self.messages.DeploymentmanagerOperationsGetRequest( project=dm_base.GetProject(), operation=op_name, ) ) operations.append(completed_operation) except apitools_exceptions.HttpError as error: errors.append(api_exceptions.HttpException( error, dm_api_util.HTTP_ERROR_FORMAT)) if errors: raise core_exceptions.MultiError(errors) return operations
def Run(self, args): """Run 'deployments create'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns a struct containing the list of resources and list of outputs in the deployment. Raises: HttpException: An http error response was received while executing api request. ConfigError: Config file could not be read or parsed, or the deployment creation operation encountered an error. """ deployment = dm_base.GetMessages().Deployment( name=args.deployment_name, target=importer.BuildTargetConfig(dm_base.GetMessages(), args.config, args.properties), ) if self.ReleaseTrack() in [base.ReleaseTrack.ALPHA]: label_dict = labels_util.GetUpdateLabelsDictFromArgs(args) label_entry = [] if label_dict: label_entry = [ dm_base.GetMessages().DeploymentLabelEntry(key=k, value=v) for k, v in sorted(label_dict.iteritems()) ] deployment.labels = label_entry if args.description: deployment.description = args.description try: operation = dm_base.GetClient().deployments.Insert( dm_base.GetMessages( ).DeploymentmanagerDeploymentsInsertRequest( project=dm_base.GetProject(), deployment=deployment, preview=args.preview, )) # Fetch and print the latest fingerprint of the deployment. fingerprint = dm_v2_util.FetchDeploymentFingerprint( dm_base.GetClient(), dm_base.GetMessages(), dm_base.GetProject(), args.deployment_name) dm_util.PrintFingerprint(fingerprint) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) if args. async: return operation else: op_name = operation.name try: dm_write.WaitForOperation(op_name, operation_description='create', project=dm_base.GetProject(), timeout=OPERATION_TIMEOUT) log.status.Print('Create operation ' + op_name + ' completed successfully.') except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) return dm_v2_util.FetchResourcesAndOutputs(dm_base.GetClient(), dm_base.GetMessages(), dm_base.GetProject(), args.deployment_name)
def Run(self, args): """Run 'deployments delete'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns boolean indicating whether insert operation succeeded. Raises: HttpException: An http error response was received while executing api request. """ prompt_message = ('The following deployments will be deleted:\n- ' + '\n- '.join(args.deployment_name)) if not args.quiet: if not console_io.PromptContinue(message=prompt_message, default=False): raise exceptions.OperationError('Deletion aborted by user.') operations = [] for deployment_name in args.deployment_name: try: operation = dm_base.GetClient().deployments.Delete( dm_base.GetMessages( ).DeploymentmanagerDeploymentsDeleteRequest( project=dm_base.GetProject(), deployment=deployment_name, deletePolicy=(dm_base.GetMessages( ).DeploymentmanagerDeploymentsDeleteRequest. DeletePolicyValueValuesEnum( args.delete_policy)), )) except apitools_exceptions.HttpError as error: raise api_exceptions.HttpException( error, dm_v2_util.HTTP_ERROR_FORMAT) if args. async: operations.append(operation) else: op_name = operation.name try: dm_write.WaitForOperation(op_name, 'delete', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) log.status.Print('Delete operation ' + op_name + ' completed successfully.') except exceptions.OperationError as e: log.error(u'Delete operation {0} failed.\n{1}'.format( op_name, e)) except apitools_exceptions.HttpError as error: raise api_exceptions.HttpException( error, dm_v2_util.HTTP_ERROR_FORMAT) try: completed_operation = dm_base.GetClient().operations.Get( dm_base.GetMessages( ).DeploymentmanagerOperationsGetRequest( project=dm_base.GetProject(), operation=op_name, )) except apitools_exceptions.HttpError as error: raise api_exceptions.HttpException( error, dm_v2_util.HTTP_ERROR_FORMAT) operations.append(completed_operation) return operations
def Run(self, args): """Run 'deployments cancel-preview'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns boolean indicating whether cancel preview operation succeeded. Raises: HttpException: An http error response was received while executing api request. """ if args.fingerprint: fingerprint = dm_util.DecodeFingerprint(args.fingerprint) else: # If no fingerprint is present, default to an empty fingerprint. # TODO(b/34966984): Remove the empty default after cleaning up all # deployments that has no fingerprint fingerprint = dm_v2_util.FetchDeploymentFingerprint( dm_base.GetClient(), dm_base.GetMessages(), dm_base.GetProject(), args.deployment_name, ) or '' try: operation = dm_base.GetClient().deployments.CancelPreview( dm_base.GetMessages( ).DeploymentmanagerDeploymentsCancelPreviewRequest( project=dm_base.GetProject(), deployment=args.deployment_name, deploymentsCancelPreviewRequest=dm_base.GetMessages(). DeploymentsCancelPreviewRequest(fingerprint=fingerprint, ), )) # Fetch and print the latest fingerprint of the deployment. new_fingerprint = dm_v2_util.FetchDeploymentFingerprint( dm_base.GetClient(), dm_base.GetMessages(), dm_base.GetProject(), args.deployment_name) dm_util.PrintFingerprint(new_fingerprint) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) if args. async: return operation else: op_name = operation.name try: dm_write.WaitForOperation(op_name, 'cancel-preview', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) log.status.Print('Cancel preview operation ' + op_name + ' completed successfully.') except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) try: # Fetch a list of the canceled resources. response = dm_base.GetClient().resources.List( dm_base.GetMessages( ).DeploymentmanagerResourcesListRequest( project=dm_base.GetProject(), deployment=args.deployment_name, )) # TODO(user): Pagination return response.resources if response.resources else [] except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT)
def Run(self, args): """Run 'deployments stop'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns boolean indicating whether stop operation succeeded. Raises: HttpException: An http error response was received while executing api request. """ if args.fingerprint: fingerprint = dm_util.DecodeFingerprint(args.fingerprint) else: # If no fingerprint is present, default to an empty fingerprint. # TODO(b/34966984): Remove the empty default after cleaning up all # deployments that has no fingerprint fingerprint = dm_api_util.FetchDeploymentFingerprint( self.client, self.messages, dm_base.GetProject(), args.deployment_name) or b'' try: operation = self.client.deployments.Stop( self.messages.DeploymentmanagerDeploymentsStopRequest( project=dm_base.GetProject(), deployment=args.deployment_name, deploymentsStopRequest=( self.messages.DeploymentsStopRequest( fingerprint=fingerprint)), )) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT) if args. async: return operation else: op_name = operation.name try: operation = dm_write.WaitForOperation( self.client, self.messages, op_name, 'stop', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) dm_util.LogOperationStatus(operation, 'Stop') except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT) try: # Fetch a list of the stopped resources. response = self.client.resources.List( self.messages.DeploymentmanagerResourcesListRequest( project=dm_base.GetProject(), deployment=args.deployment_name, )) # TODO(b/36055861): Pagination return response.resources if response.resources else [] except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
def Run(self, args): """Run 'deployments create'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns a struct containing the list of resources and list of outputs in the deployment. Raises: HttpException: An http error response was received while executing api request. ConfigError: Config file could not be read or parsed, or the deployment creation operation encountered an error. """ deployment_ref = self.resources.Parse( args.deployment_name, params={'project': properties.VALUES.core.project.GetOrFail}, collection='deploymentmanager.deployments') if (not args.IsSpecified('format')) and (args.async): args.format = flags.OPERATION_FORMAT deployment = self.messages.Deployment( name=deployment_ref.deployment, target=importer.BuildTargetConfig(self.messages, config=args.config, template=args.template, composite_type=args.composite_type, properties=args.properties) ) self._SetMetadata(args, deployment) try: operation = self.client.deployments.Insert( self.messages.DeploymentmanagerDeploymentsInsertRequest( project=dm_base.GetProject(), deployment=deployment, preview=args.preview, ) ) # Fetch and print the latest fingerprint of the deployment. fingerprint = dm_api_util.FetchDeploymentFingerprint( self.client, self.messages, dm_base.GetProject(), deployment_ref.deployment) dm_util.PrintFingerprint(fingerprint) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT) if args.async: return operation else: op_name = operation.name try: dm_write.WaitForOperation(self.client, self.messages, op_name, operation_description='create', project=dm_base.GetProject(), timeout=OPERATION_TIMEOUT) log.status.Print('Create operation ' + op_name + ' completed successfully.') except apitools_exceptions.HttpError as error: # TODO(b/37911296): Use gcloud default error handling. raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT) except dm_exceptions.OperationError as error: response = self._HandleOperationError(error, args, operation, dm_base.GetProject(), deployment_ref) if getattr(args, 'automatic_rollback', False): args.format = flags.OPERATION_FORMAT return response return dm_api_util.FetchResourcesAndOutputs( self.client, self.messages, dm_base.GetProject(), deployment_ref.deployment, self.ReleaseTrack() is base.ReleaseTrack.ALPHA)
def Run(self, args): """Run 'deployments cancel-preview'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If --async=true, returns Operation to poll. Else, returns boolean indicating whether cancel preview operation succeeded. Raises: HttpException: An http error response was received while executing api request. """ # Get the fingerprint from the previewing deployment to cancel. try: current_deployment = dm_base.GetClient().deployments.Get( dm_base.GetMessages().DeploymentmanagerDeploymentsGetRequest( project=dm_base.GetProject(), deployment=args.deployment_name)) # If no fingerprint is present, default to an empty fingerprint. # This empty default can be removed once the fingerprint change is # fully implemented and all deployments have fingerprints. fingerprint = current_deployment.fingerprint or '' except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) try: operation = dm_base.GetClient().deployments.CancelPreview( dm_base.GetMessages( ).DeploymentmanagerDeploymentsCancelPreviewRequest( project=dm_base.GetProject(), deployment=args.deployment_name, deploymentsCancelPreviewRequest=dm_base.GetMessages(). DeploymentsCancelPreviewRequest(fingerprint=fingerprint, ), )) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) if args. async: return operation else: op_name = operation.name try: dm_write.WaitForOperation(op_name, 'cancel-preview', dm_base.GetProject(), timeout=OPERATION_TIMEOUT) log.status.Print('Cancel preview operation ' + op_name + ' completed successfully.') except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT) try: # Fetch a list of the canceled resources. response = dm_base.GetClient().resources.List( dm_base.GetMessages( ).DeploymentmanagerResourcesListRequest( project=dm_base.GetProject(), deployment=args.deployment_name, )) # TODO(user): Pagination return response.resources if response.resources else [] except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error, dm_v2_util.HTTP_ERROR_FORMAT)