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
Пример #2
0
    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()
Пример #4
0
 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].')
Пример #5
0
    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)
Пример #6
0
    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)
Пример #7
0
  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
Пример #8
0
    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)
Пример #9
0
    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
Пример #10
0
    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)
Пример #11
0
    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)