// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.config.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";

option csharp_namespace = "Google.Cloud.Config.V1";
option go_package = "cloud.google.com/go/config/apiv1/configpb;configpb";
option java_multiple_files = true;
option java_outer_classname = "ConfigProto";
option java_package = "com.google.cloud.config.v1";
option php_namespace = "Google\\Cloud\\Config\\V1";
option ruby_package = "Google::Cloud::ConfigService::V1";
option (google.api.resource_definition) = {
  type: "iam.googleapis.com/ServiceAccount"
  pattern: "projects/{project}/serviceAccounts/{service_account}"
};
option (google.api.resource_definition) = {
  type: "cloudbuild.googleapis.com/WorkerPool"
  pattern: "projects/{project}/locations/{location}/workerPools/{worker_pool}"
};

// Infrastructure Manager is a managed service that automates the deployment and
// management of Google Cloud infrastructure resources.
service Config {
  option (google.api.default_host) = "config.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Lists [Deployment][google.cloud.config.v1.Deployment]s in a given project
  // and location.
  rpc ListDeployments(ListDeploymentsRequest)
      returns (ListDeploymentsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/deployments"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details about a [Deployment][google.cloud.config.v1.Deployment].
  rpc GetDeployment(GetDeploymentRequest) returns (Deployment) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/deployments/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a [Deployment][google.cloud.config.v1.Deployment].
  rpc CreateDeployment(CreateDeploymentRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/deployments"
      body: "deployment"
    };
    option (google.api.method_signature) = "parent,deployment,deployment_id";
    option (google.longrunning.operation_info) = {
      response_type: "Deployment"
      metadata_type: "OperationMetadata"
    };
  }

  // Updates a [Deployment][google.cloud.config.v1.Deployment].
  rpc UpdateDeployment(UpdateDeploymentRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{deployment.name=projects/*/locations/*/deployments/*}"
      body: "deployment"
    };
    option (google.api.method_signature) = "deployment,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Deployment"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes a [Deployment][google.cloud.config.v1.Deployment].
  rpc DeleteDeployment(DeleteDeploymentRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/deployments/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "Deployment"
      metadata_type: "OperationMetadata"
    };
  }

  // Lists [Revision][google.cloud.config.v1.Revision]s of a deployment.
  rpc ListRevisions(ListRevisionsRequest) returns (ListRevisionsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/deployments/*}/revisions"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details about a [Revision][google.cloud.config.v1.Revision].
  rpc GetRevision(GetRevisionRequest) returns (Revision) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/deployments/*/revisions/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Gets details about a [Resource][google.cloud.config.v1.Resource] deployed
  // by Infra Manager.
  rpc GetResource(GetResourceRequest) returns (Resource) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/deployments/*/revisions/*/resources/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists [Resource][google.cloud.config.v1.Resource]s in a given revision.
  rpc ListResources(ListResourcesRequest) returns (ListResourcesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*/deployments/*/revisions/*}/resources"
    };
    option (google.api.method_signature) = "parent";
  }

  // Exports Terraform state file from a given deployment.
  rpc ExportDeploymentStatefile(ExportDeploymentStatefileRequest)
      returns (Statefile) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/deployments/*}:exportState"
      body: "*"
    };
  }

  // Exports Terraform state file from a given revision.
  rpc ExportRevisionStatefile(ExportRevisionStatefileRequest)
      returns (Statefile) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/deployments/*/revisions/*}:exportState"
      body: "*"
    };
  }

  // Imports Terraform state file in a given deployment. The state file does not
  // take effect until the Deployment has been unlocked.
  rpc ImportStatefile(ImportStatefileRequest) returns (Statefile) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*/deployments/*}:importState"
      body: "*"
    };
    option (google.api.method_signature) = "parent,lock_id";
  }

  // Deletes Terraform state file in a given deployment.
  rpc DeleteStatefile(DeleteStatefileRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*/deployments/*}:deleteState"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }

  // Locks a deployment.
  rpc LockDeployment(LockDeploymentRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*/deployments/*}:lock"
      body: "*"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "Deployment"
      metadata_type: "OperationMetadata"
    };
  }

  // Unlocks a locked deployment.
  rpc UnlockDeployment(UnlockDeploymentRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{name=projects/*/locations/*/deployments/*}:unlock"
      body: "*"
    };
    option (google.api.method_signature) = "name,lock_id";
    option (google.longrunning.operation_info) = {
      response_type: "Deployment"
      metadata_type: "OperationMetadata"
    };
  }

  // Exports the lock info on a locked deployment.
  rpc ExportLockInfo(ExportLockInfoRequest) returns (LockInfo) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/deployments/*}:exportLock"
    };
    option (google.api.method_signature) = "name";
  }
}

// A Deployment is a group of resources and configs managed and provisioned by
// Infra Manager.
message Deployment {
  option (google.api.resource) = {
    type: "config.googleapis.com/Deployment"
    pattern: "projects/{project}/locations/{location}/deployments/{deployment}"
  };

  // Possible states of a deployment.
  enum State {
    // The default value. This value is used if the state is omitted.
    STATE_UNSPECIFIED = 0;

    // The deployment is being created.
    CREATING = 1;

    // The deployment is healthy.
    ACTIVE = 2;

    // The deployment is being updated.
    UPDATING = 3;

    // The deployment is being deleted.
    DELETING = 4;

    // The deployment has encountered an unexpected error.
    FAILED = 5;

    // The deployment is no longer being actively reconciled.
    // This may be the result of recovering the project after deletion.
    SUSPENDED = 6;

    // The deployment has been deleted.
    DELETED = 7;
  }

  // Possible errors that can occur with deployments.
  enum ErrorCode {
    // No error code was specified.
    ERROR_CODE_UNSPECIFIED = 0;

    // The revision failed. See Revision for more details.
    REVISION_FAILED = 1;

    // Cloud Build failed due to a permission issue.
    CLOUD_BUILD_PERMISSION_DENIED = 3;

    // Cloud Build job associated with a deployment deletion could not be
    // started.
    DELETE_BUILD_API_FAILED = 5;

    // Cloud Build job associated with a deployment deletion was started but
    // failed.
    DELETE_BUILD_RUN_FAILED = 6;

    // Cloud Storage bucket creation failed due to a permission issue.
    BUCKET_CREATION_PERMISSION_DENIED = 7;

    // Cloud Storage bucket creation failed due to an issue unrelated to
    // permissions.
    BUCKET_CREATION_FAILED = 8;
  }

  // Possible lock states of a deployment.
  enum LockState {
    // The default value. This value is used if the lock state is omitted.
    LOCK_STATE_UNSPECIFIED = 0;

    // The deployment is locked.
    LOCKED = 1;

    // The deployment is unlocked.
    UNLOCKED = 2;

    // The deployment is being locked.
    LOCKING = 3;

    // The deployment is being unlocked.
    UNLOCKING = 4;

    // The deployment has failed to lock.
    LOCK_FAILED = 5;

    // The deployment has failed to unlock.
    UNLOCK_FAILED = 6;
  }

  // Blueprint to deploy.
  oneof blueprint {
    // A blueprint described using Terraform's HashiCorp Configuration Language
    // as a root module.
    TerraformBlueprint terraform_blueprint = 6;
  }

  // Resource name of the deployment.
  // Format: `projects/{project}/locations/{location}/deployments/{deployment}`
  string name = 1;

  // Output only. Time when the deployment was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the deployment was last modified.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // User-defined metadata for the deployment.
  map<string, string> labels = 4;

  // Output only. Current state of the deployment.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Revision name that was most recently applied.
  // Format: `projects/{project}/locations/{location}/deployments/{deployment}/
  // revisions/{revision}`
  string latest_revision = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Additional information regarding the current state.
  string state_detail = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Error code describing errors that may have occurred.
  ErrorCode error_code = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Location of artifacts from a DeleteDeployment operation.
  ApplyResults delete_results = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Cloud Build instance UUID associated with deleting this
  // deployment.
  string delete_build = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Location of Cloud Build logs in Google Cloud Storage,
  // populated when deleting this deployment. Format: `gs://{bucket}/{object}`.
  string delete_logs = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Errors encountered when deleting this deployment.
  // Errors are truncated to 10 entries, see `delete_results` and `error_logs`
  // for full details.
  repeated TerraformError tf_errors = 13
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Location of Terraform error logs in Google Cloud Storage.
  // Format: `gs://{bucket}/{object}`.
  string error_logs = 14 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. User-defined location of Cloud Build logs and artifacts in Google
  // Cloud Storage. Format: `gs://{bucket}/{folder}`
  //
  // A default bucket will be bootstrapped if the field is not set or empty.
  // Default bucket format: `gs://<project number>-<region>-blueprint-config`
  // Constraints:
  // - The bucket needs to be in the same project as the deployment
  // - The path cannot be within the path of `gcs_source`
  // - The field cannot be updated, including changing its presence
  optional string artifacts_gcs_bucket = 15
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. User-specified Service Account (SA) credentials to be used when
  // actuating resources.
  // Format: `projects/{projectID}/serviceAccounts/{serviceAccount}`
  optional string service_account = 16 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "iam.googleapis.com/ServiceAccount"
    }
  ];

  // By default, Infra Manager will return a failure when
  // Terraform encounters a 409 code (resource conflict error) during actuation.
  // If this flag is set to true, Infra Manager will instead
  // attempt to automatically import the resource into the Terraform state (for
  // supported resource types) and continue actuation.
  //
  // Not all resource types are supported, refer to documentation.
  optional bool import_existing_resources = 17;

  // Optional. The user-specified Cloud Build worker pool resource in which the
  // Cloud Build job will execute. Format:
  // `projects/{project}/locations/{location}/workerPools/{workerPoolId}`.
  // If this field is unspecified, the default Cloud Build worker pool will be
  // used.
  optional string worker_pool = 19 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "cloudbuild.googleapis.com/WorkerPool"
    }
  ];

  // Output only. Current lock state of the deployment.
  LockState lock_state = 20 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// TerraformBlueprint describes the source of a Terraform root module which
// describes the resources and configs to be deployed.
message TerraformBlueprint {
  // Location of the source configs.
  oneof source {
    // Required. URI of an object in Google Cloud Storage.
    // Format: `gs://{bucket}/{object}`
    //
    // URI may also specify an object version for zipped objects.
    // Format: `gs://{bucket}/{object}#{version}`
    string gcs_source = 1 [(google.api.field_behavior) = REQUIRED];

    // Required. URI of a public Git repo.
    GitSource git_source = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // Input variable values for the Terraform blueprint.
  map<string, TerraformVariable> input_values = 4;
}

// A Terraform input variable.
message TerraformVariable {
  // Input variable value.
  google.protobuf.Value input_value = 5;
}

// Outputs and artifacts from applying a deployment.
message ApplyResults {
  // Location of a blueprint copy and other manifests in Google Cloud Storage.
  // Format: `gs://{bucket}/{object}`
  string content = 1;

  // Location of artifacts (e.g. logs) in Google Cloud Storage.
  // Format: `gs://{bucket}/{object}`
  string artifacts = 2;

  // Map of output name to output info.
  map<string, TerraformOutput> outputs = 3;
}

// Describes a Terraform output.
message TerraformOutput {
  // Identifies whether Terraform has set this output as a potential
  // sensitive value.
  bool sensitive = 1;

  // Value of output.
  google.protobuf.Value value = 2;
}

message ListDeploymentsRequest {
  // Required. The parent in whose context the Deployments are listed. The
  // parent value is in the format:
  // 'projects/{project_id}/locations/{location}'.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // When requesting a page of resources, 'page_size' specifies number of
  // resources to return. If unspecified or set to 0, all resources will be
  // returned.
  int32 page_size = 2;

  // Token returned by previous call to 'ListDeployments' which specifies the
  // position in the list from where to continue listing the resources.
  string page_token = 3;

  // Lists the Deployments that match the filter expression. A filter
  // expression filters the resources listed in the response. The expression
  // must be of the form '{field} {operator} {value}' where operators: '<', '>',
  // '<=', '>=', '!=', '=', ':' are supported (colon ':' represents a HAS
  // operator which is roughly synonymous with equality). {field} can refer to a
  // proto or JSON field, or a synthetic field. Field names can be camelCase or
  // snake_case.
  //
  // Examples:
  // - Filter by name:
  //   name = "projects/foo/locations/us-central1/deployments/bar
  //
  // - Filter by labels:
  //   - Resources that have a key called 'foo'
  //     labels.foo:*
  //   - Resources that have a key called 'foo' whose value is 'bar'
  //     labels.foo = bar
  //
  // - Filter by state:
  //   - Deployments in CREATING state.
  //     state=CREATING
  string filter = 4;

  // Field to use to sort the list.
  string order_by = 5;
}

message ListDeploymentsResponse {
  // List of [Deployment][google.cloud.config.v1.Deployment]s.
  repeated Deployment deployments = 1;

  // Token to be supplied to the next ListDeployments request via `page_token`
  // to obtain the next set of results.
  string next_page_token = 2;

  // Locations that could not be reached.
  repeated string unreachable = 3;
}

message GetDeploymentRequest {
  // Required. The name of the deployment. Format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];
}

// A request to list Revisions passed to a 'ListRevisions' call.
message ListRevisionsRequest {
  // Required. The parent in whose context the Revisions are listed. The parent
  // value is in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];

  // When requesting a page of resources, `page_size` specifies number of
  // resources to return. If unspecified or set to 0, all resources will be
  // returned.
  int32 page_size = 2;

  // Token returned by previous call to 'ListRevisions' which specifies the
  // position in the list from where to continue listing the resources.
  string page_token = 3;

  // Lists the Revisions that match the filter expression. A filter
  // expression filters the resources listed in the response. The expression
  // must be of the form '{field} {operator} {value}' where operators: '<', '>',
  // '<=', '>=', '!=', '=', ':' are supported (colon ':' represents a HAS
  // operator which is roughly synonymous with equality). {field} can refer to a
  // proto or JSON field, or a synthetic field. Field names can be camelCase or
  // snake_case.
  //
  // Examples:
  // - Filter by name:
  //   name = "projects/foo/locations/us-central1/deployments/dep/revisions/bar
  //
  // - Filter by labels:
  //   - Resources that have a key called 'foo'
  //     labels.foo:*
  //   - Resources that have a key called 'foo' whose value is 'bar'
  //     labels.foo = bar
  //
  // - Filter by state:
  //   - Revisions in CREATING state.
  //     state=CREATING
  string filter = 4;

  // Field to use to sort the list.
  string order_by = 5;
}

// A response to a 'ListRevisions' call. Contains a list of Revisions.
message ListRevisionsResponse {
  // List of [Revision][google.cloud.config.v1.Revision]s.
  repeated Revision revisions = 1;

  // A token to request the next page of resources from the 'ListRevisions'
  // method. The value of an empty string means that there are no more resources
  // to return.
  string next_page_token = 2;

  // Locations that could not be reached.
  repeated string unreachable = 3;
}

// A request to get a Revision from a 'GetRevision' call.
message GetRevisionRequest {
  // Required. The name of the Revision in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}/revisions/{revision}'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "config.googleapis.com/Revision" }
  ];
}

message CreateDeploymentRequest {
  // Required. The parent in whose context the Deployment is created. The parent
  // value is in the format: 'projects/{project_id}/locations/{location}'.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. The Deployment ID.
  string deployment_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. [Deployment][google.cloud.config.v1.Deployment] resource to be
  // created.
  Deployment deployment = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID so that if you must retry your request, the server will know to
  // ignore the request if it has already been completed. The server will
  // guarantee that for at least 60 minutes since the first request.
  //
  // For example, consider a situation where you make an initial request and the
  // request times out. If you make the request again with the same request ID,
  // the server can check if original operation with the same request ID was
  // received, and if so, will ignore the second request. This prevents clients
  // from accidentally creating duplicate commitments.
  //
  // The request ID must be a valid UUID with the exception that zero UUID is
  // not supported (00000000-0000-0000-0000-000000000000).
  string request_id = 4 [(google.api.field_behavior) = OPTIONAL];
}

message UpdateDeploymentRequest {
  // Optional. Field mask used to specify the fields to be overwritten in the
  // Deployment resource by the update.
  //
  // The fields specified in the update_mask are relative to the resource, not
  // the full request. A field will be overwritten if it is in the mask. If the
  // user does not provide a mask then all fields will be overwritten.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Required. [Deployment][google.cloud.config.v1.Deployment] to update.
  //
  // The deployment's `name` field is used to identify the resource to be
  // updated. Format:
  // `projects/{project}/locations/{location}/deployments/{deployment}`
  Deployment deployment = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID so that if you must retry your request, the server will know to
  // ignore the request if it has already been completed. The server will
  // guarantee that for at least 60 minutes since the first request.
  //
  // For example, consider a situation where you make an initial request and the
  // request times out. If you make the request again with the same request ID,
  // the server can check if original operation with the same request ID was
  // received, and if so, will ignore the second request. This prevents clients
  // from accidentally creating duplicate commitments.
  //
  // The request ID must be a valid UUID with the exception that zero UUID is
  // not supported (00000000-0000-0000-0000-000000000000).
  string request_id = 3 [(google.api.field_behavior) = OPTIONAL];
}

message DeleteDeploymentRequest {
  // Policy on how resources actuated by the deployment should be deleted.
  enum DeletePolicy {
    // Unspecified policy, resources will be deleted.
    DELETE_POLICY_UNSPECIFIED = 0;

    // Deletes resources actuated by the deployment.
    DELETE = 1;

    // Abandons resources and only deletes the deployment and its metadata.
    ABANDON = 2;
  }

  // Required. The name of the Deployment in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID so that if you must retry your request, the server will know to
  // ignore the request if it has already been completed. The server will
  // guarantee that for at least 60 minutes after the first request.
  //
  // For example, consider a situation where you make an initial request and the
  // request times out. If you make the request again with the same request ID,
  // the server can check if original operation with the same request ID was
  // received, and if so, will ignore the second request. This prevents clients
  // from accidentally creating duplicate commitments.
  //
  // The request ID must be a valid UUID with the exception that zero UUID is
  // not supported (00000000-0000-0000-0000-000000000000).
  string request_id = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set to true, any revisions for this deployment will also be
  // deleted. (Otherwise, the request will only work if the deployment has no
  // revisions.)
  bool force = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Policy on how resources actuated by the deployment should be
  // deleted. If unspecified, the default behavior is to delete the underlying
  // resources.
  DeletePolicy delete_policy = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the metadata of the long-running operation.
message OperationMetadata {
  // Ephemeral metadata about the state of an operation for a particular
  // resource.
  oneof resource_metadata {
    // Output only. Metadata about the deployment operation state.
    DeploymentOperationMetadata deployment_metadata = 8
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. Time when the operation was created.
  google.protobuf.Timestamp create_time = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the operation finished running.
  google.protobuf.Timestamp end_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Server-defined resource path for the target of the operation.
  string target = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Name of the verb executed by the operation.
  string verb = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Human-readable status of the operation, if any.
  string status_message = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Identifies whether the user has requested cancellation of the
  // operation. Operations that have successfully been cancelled have
  // [Operation.error][] value with a
  // [google.rpc.Status.code][google.rpc.Status.code] of 1, corresponding to
  // `Code.CANCELLED`.
  bool requested_cancellation = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. API version used to start the operation.
  string api_version = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A child resource of a Deployment generated by a 'CreateDeployment' or
// 'UpdateDeployment' call. Each Revision contains metadata pertaining to a
// snapshot of a particular Deployment.
message Revision {
  option (google.api.resource) = {
    type: "config.googleapis.com/Revision"
    pattern: "projects/{project}/locations/{location}/deployments/{deployment}/revisions/{revision}"
  };

  // Actions that generate a revision.
  enum Action {
    // The default value. This value is used if the action is omitted.
    ACTION_UNSPECIFIED = 0;

    // The revision was generated by creating a deployment.
    CREATE = 1;

    // The revision was generated by updating a deployment.
    UPDATE = 2;

    // The revision was deleted.
    DELETE = 3;
  }

  // Possible states of a revision.
  enum State {
    // The default value. This value is used if the state is omitted.
    STATE_UNSPECIFIED = 0;

    // The revision is being applied.
    APPLYING = 1;

    // The revision was applied successfully.
    APPLIED = 2;

    // The revision could not be applied successfully.
    FAILED = 3;
  }

  // Possible errors if Revision could not be created or updated successfully.
  enum ErrorCode {
    // No error code was specified.
    ERROR_CODE_UNSPECIFIED = 0;

    // Cloud Build failed due to a permission issue.
    CLOUD_BUILD_PERMISSION_DENIED = 1;

    // Cloud Build job associated with creating or updating a deployment could
    // not be started.
    APPLY_BUILD_API_FAILED = 4;

    // Cloud Build job associated with creating or updating a deployment was
    // started but failed.
    APPLY_BUILD_RUN_FAILED = 5;
  }

  // Blueprint that was deployed.
  oneof blueprint {
    // Output only. A blueprint described using Terraform's HashiCorp
    // Configuration Language as a root module.
    TerraformBlueprint terraform_blueprint = 6
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Revision name. Format:
  // `projects/{project}/locations/{location}/deployments/{deployment}/
  // revisions/{revision}`
  string name = 1;

  // Output only. Time when the revision was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Time when the revision was last modified.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The action which created this revision
  Action action = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Current state of the revision.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Outputs and artifacts from applying a deployment.
  ApplyResults apply_results = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Additional info regarding the current state.
  string state_detail = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Code describing any errors that may have occurred.
  ErrorCode error_code = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Cloud Build instance UUID associated with this revision.
  string build = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Location of Revision operation logs in
  // `gs://{bucket}/{object}` format.
  string logs = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Errors encountered when creating or updating this deployment.
  // Errors are truncated to 10 entries, see `delete_results` and `error_logs`
  // for full details.
  repeated TerraformError tf_errors = 12
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Location of Terraform error logs in Google Cloud Storage.
  // Format: `gs://{bucket}/{object}`.
  string error_logs = 13 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. User-specified Service Account (SA) to be used as credential
  // to manage resources. Format:
  // `projects/{projectID}/serviceAccounts/{serviceAccount}`
  string service_account = 14 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "iam.googleapis.com/ServiceAccount"
    }
  ];

  // Output only. By default, Infra Manager will return a failure when
  // Terraform encounters a 409 code (resource conflict error) during actuation.
  // If this flag is set to true, Infra Manager will instead
  // attempt to automatically import the resource into the Terraform state (for
  // supported resource types) and continue actuation.
  //
  // Not all resource types are supported, refer to documentation.
  bool import_existing_resources = 15
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The user-specified Cloud Build worker pool resource in which
  // the Cloud Build job will execute. Format:
  // `projects/{project}/locations/{location}/workerPools/{workerPoolId}`.
  // If this field is unspecified, the default Cloud Build worker pool will be
  // used.
  string worker_pool = 17 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "cloudbuild.googleapis.com/WorkerPool"
    }
  ];
}

// Errors encountered during actuation using Terraform
message TerraformError {
  // Address of the resource associated with the error,
  // e.g. `google_compute_network.vpc_network`.
  string resource_address = 1;

  // HTTP response code returned from Google Cloud Platform APIs when Terraform
  // fails to provision the resource. If unset or 0, no HTTP response code was
  // returned by Terraform.
  int32 http_response_code = 2;

  // A human-readable error description.
  string error_description = 3;

  // Original error response from underlying Google API, if available.
  google.rpc.Status error = 4;
}

// A set of files in a Git repository.
message GitSource {
  // Optional. Repository URL.
  // Example: 'https://github.com/kubernetes/examples.git'
  optional string repo = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Subdirectory inside the repository.
  // Example: 'staging/my-package'
  optional string directory = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Git reference (e.g. branch or tag).
  optional string ref = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Ephemeral metadata content describing the state of a deployment operation.
message DeploymentOperationMetadata {
  // The possible steps a deployment may be running.
  enum DeploymentStep {
    // Unspecified deployment step
    DEPLOYMENT_STEP_UNSPECIFIED = 0;

    // Infra Manager is creating a Google Cloud Storage bucket to store
    // artifacts and metadata about the deployment and revision
    PREPARING_STORAGE_BUCKET = 1;

    // Downloading the blueprint onto the Google Cloud Storage bucket
    DOWNLOADING_BLUEPRINT = 2;

    // Initializing Terraform using `terraform init`
    RUNNING_TF_INIT = 3;

    // Running `terraform plan`
    RUNNING_TF_PLAN = 4;

    // Actuating resources using Terraform using `terraform apply`
    RUNNING_TF_APPLY = 5;

    // Destroying resources using Terraform using `terraform destroy`
    RUNNING_TF_DESTROY = 6;

    // Validating the uploaded TF state file when unlocking a deployment
    RUNNING_TF_VALIDATE = 7;

    // Unlocking a deployment
    UNLOCKING_DEPLOYMENT = 8;

    // Operation was successful
    SUCCEEDED = 9;

    // Operation failed
    FAILED = 10;
  }

  // The current step the deployment operation is running.
  DeploymentStep step = 1;

  // Outputs and artifacts from applying a deployment.
  ApplyResults apply_results = 2;

  // Output only. Cloud Build instance UUID associated with this operation.
  string build = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Location of Deployment operations logs in
  // `gs://{bucket}/{object}` format.
  string logs = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Resource represents a Google Cloud Platform resource actuated by IM.
// Resources are child resources of Revisions.
message Resource {
  option (google.api.resource) = {
    type: "config.googleapis.com/Resource"
    pattern: "projects/{project}/locations/{location}/deployments/{deployment}/revisions/{revision}/resources/{resource}"
  };

  // Possible intent of the resource.
  enum Intent {
    // The default value. This value is used if the intent is omitted.
    INTENT_UNSPECIFIED = 0;

    // Infra Manager will create this Resource.
    CREATE = 1;

    // Infra Manager will update this Resource.
    UPDATE = 2;

    // Infra Manager will delete this Resource.
    DELETE = 3;

    // Infra Manager will destroy and recreate this Resource.
    RECREATE = 4;

    // Infra Manager will leave this Resource untouched.
    UNCHANGED = 5;
  }

  // Possible states of a resource.
  enum State {
    // The default value. This value is used if the state is omitted.
    STATE_UNSPECIFIED = 0;

    // Resource has been planned for reconcile.
    PLANNED = 1;

    // Resource is actively reconciling into the intended state.
    IN_PROGRESS = 2;

    // Resource has reconciled to intended state.
    RECONCILED = 3;

    // Resource failed to reconcile.
    FAILED = 4;
  }

  // Output only. Resource name.
  // Format:
  // `projects/{project}/locations/{location}/deployments/{deployment}/revisions/{revision}/resources/{resource}`
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Terraform-specific info if this resource was created using
  // Terraform.
  ResourceTerraformInfo terraform_info = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Map of Cloud Asset Inventory (CAI) type to CAI info (e.g. CAI
  // ID). CAI type format follows
  // https://cloud.google.com/asset-inventory/docs/supported-asset-types
  map<string, ResourceCAIInfo> cai_assets = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Intent of the resource.
  Intent intent = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Current state of the resource.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Terraform info of a Resource.
message ResourceTerraformInfo {
  // TF resource address that uniquely identifies this resource within this
  // deployment.
  string address = 1;

  // TF resource type
  string type = 2;

  // ID attribute of the TF resource
  string id = 3;
}

// CAI info of a Resource.
message ResourceCAIInfo {
  // CAI resource name in the format following
  // https://cloud.google.com/apis/design/resource_names#full_resource_name
  string full_resource_name = 1;
}

// A request to get a Resource from a 'GetResource' call.
message GetResourceRequest {
  // Required. The name of the Resource in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}/revisions/{revision}/resource/{resource}'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "config.googleapis.com/Resource" }
  ];
}

// A request to list Resources passed to a 'ListResources' call.
message ListResourcesRequest {
  // Required. The parent in whose context the Resources are listed. The parent
  // value is in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}/revisions/{revision}'.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "config.googleapis.com/Revision" }
  ];

  // When requesting a page of resources, 'page_size' specifies number of
  // resources to return. If unspecified or set to 0, all resources will be
  // returned.
  int32 page_size = 2;

  // Token returned by previous call to 'ListResources' which specifies the
  // position in the list from where to continue listing the resources.
  string page_token = 3;

  // Lists the Resources that match the filter expression. A filter
  // expression filters the resources listed in the response. The expression
  // must be of the form '{field} {operator} {value}' where operators: '<', '>',
  // '<=',
  // '>=',
  // '!=', '=', ':' are supported (colon ':' represents a HAS operator which is
  // roughly synonymous with equality). {field} can refer to a proto or JSON
  // field, or a synthetic field. Field names can be camelCase or snake_case.
  //
  // Examples:
  // - Filter by name:
  //   name =
  //   "projects/foo/locations/us-central1/deployments/dep/revisions/bar/resources/baz
  string filter = 4;

  // Field to use to sort the list.
  string order_by = 5;
}

// A response to a 'ListResources' call. Contains a list of Resources.
message ListResourcesResponse {
  // List of [Resources][]s.
  repeated Resource resources = 1;

  // A token to request the next page of resources from the 'ListResources'
  // method. The value of an empty string means that there are no more resources
  // to return.
  string next_page_token = 2;

  // Locations that could not be reached.
  repeated string unreachable = 3;
}

// Contains info about a Terraform state file
message Statefile {
  // Output only. Cloud Storage signed URI used for downloading or uploading the
  // state file.
  string signed_uri = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A request to export a state file passed to a 'ExportDeploymentStatefile'
// call.
message ExportDeploymentStatefileRequest {
  // Required. The parent in whose context the statefile is listed. The parent
  // value is in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];

  // Optional. If this flag is set to true, the exported deployment state file
  // will be the draft state. This will enable the draft file to be validated
  // before copying it over to the working state on unlock.
  bool draft = 3 [(google.api.field_behavior) = OPTIONAL];
}

// A request to export a state file passed to a 'ExportRevisionStatefile'
// call.
message ExportRevisionStatefileRequest {
  // Required. The parent in whose context the statefile is listed. The parent
  // value is in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}/revisions/{revision}'.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "config.googleapis.com/Revision" }
  ];
}

// A request to import a state file passed to a 'ImportStatefile' call.
message ImportStatefileRequest {
  // Required. The parent in whose context the statefile is listed. The parent
  // value is in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];

  // Required. Lock ID of the lock file to verify that the user who is importing
  // the state file previously locked the Deployment.
  int64 lock_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional.
  bool skip_draft = 3 [(google.api.field_behavior) = OPTIONAL];
}

// A request to delete a state file passed to a 'DeleteStatefile' call.
message DeleteStatefileRequest {
  // Required. The name of the deployment in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];

  // Required. Lock ID of the lock file to verify that the user who is deleting
  // the state file previously locked the Deployment.
  int64 lock_id = 2 [(google.api.field_behavior) = REQUIRED];
}

// A request to lock a deployment passed to a 'LockDeployment' call.
message LockDeploymentRequest {
  // Required. The name of the deployment in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];
}

// A request to unlock a state file passed to a 'UnlockDeployment' call.
message UnlockDeploymentRequest {
  // Required. The name of the deployment in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];

  // Required. Lock ID of the lock file to be unlocked.
  int64 lock_id = 2 [(google.api.field_behavior) = REQUIRED];
}

// A request to get a state file lock info passed to a 'ExportLockInfo' call.
message ExportLockInfoRequest {
  // Required. The name of the deployment in the format:
  // 'projects/{project_id}/locations/{location}/deployments/{deployment}'.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "config.googleapis.com/Deployment"
    }
  ];
}

// Details about the lock which locked the deployment.
message LockInfo {
  // Unique ID for the lock to be overridden with generation ID in the backend.
  int64 lock_id = 1;

  // Terraform operation, provided by the caller.
  string operation = 2;

  // Extra information to store with the lock, provided by the caller.
  string info = 3;

  // user@hostname when available
  string who = 4;

  // Terraform version
  string version = 5;

  // Time that the lock was taken.
  google.protobuf.Timestamp create_time = 6;
}
