// 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.gkemulticloud.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/gkemulticloud/v1/common_resources.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.GkeMultiCloud.V1";
option go_package = "cloud.google.com/go/gkemulticloud/apiv1/gkemulticloudpb;gkemulticloudpb";
option java_multiple_files = true;
option java_outer_classname = "AttachedResourcesProto";
option java_package = "com.google.cloud.gkemulticloud.v1";
option php_namespace = "Google\\Cloud\\GkeMultiCloud\\V1";
option ruby_package = "Google::Cloud::GkeMultiCloud::V1";

// An Anthos cluster running on customer own infrastructure.
message AttachedCluster {
  option (google.api.resource) = {
    type: "gkemulticloud.googleapis.com/AttachedCluster"
    pattern: "projects/{project}/locations/{location}/attachedClusters/{attached_cluster}"
  };

  // The lifecycle state of the cluster.
  enum State {
    // Not set.
    STATE_UNSPECIFIED = 0;

    // The PROVISIONING state indicates the cluster is being registered.
    PROVISIONING = 1;

    // The RUNNING state indicates the cluster has been register and is fully
    // usable.
    RUNNING = 2;

    // The RECONCILING state indicates that some work is actively being done on
    // the cluster, such as upgrading software components.
    RECONCILING = 3;

    // The STOPPING state indicates the cluster is being de-registered.
    STOPPING = 4;

    // The ERROR state indicates the cluster is in a broken unrecoverable
    // state.
    ERROR = 5;

    // The DEGRADED state indicates the cluster requires user action to
    // restore full functionality.
    DEGRADED = 6;
  }

  // The name of this resource.
  //
  // Cluster names are formatted as
  // `projects/<project-number>/locations/<region>/attachedClusters/<cluster-id>`.
  //
  // See [Resource Names](https://cloud.google.com/apis/design/resource_names)
  // for more details on Google Cloud Platform resource names.
  string name = 1;

  // Optional. A human readable description of this cluster.
  // Cannot be longer than 255 UTF-8 encoded bytes.
  string description = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. OpenID Connect (OIDC) configuration for the cluster.
  AttachedOidcConfig oidc_config = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The platform version for the cluster (e.g. `1.19.0-gke.1000`).
  //
  // You can list all supported versions on a given Google Cloud region by
  // calling
  // [GetAttachedServerConfig][google.cloud.gkemulticloud.v1.AttachedClusters.GetAttachedServerConfig].
  string platform_version = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The Kubernetes distribution of the underlying attached cluster.
  //
  // Supported values: ["eks", "aks", "generic"].
  string distribution = 16 [(google.api.field_behavior) = REQUIRED];

  // Output only. The region where this cluster runs.
  //
  // For EKS clusters, this is a AWS region. For AKS clusters,
  // this is an Azure region.
  string cluster_region = 22 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. Fleet configuration.
  Fleet fleet = 5 [(google.api.field_behavior) = REQUIRED];

  // Output only. The current state of the cluster.
  State state = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A globally unique identifier for the cluster.
  string uid = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. If set, there are currently changes in flight to the cluster.
  bool reconciling = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which this cluster was registered.
  google.protobuf.Timestamp create_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which this cluster was last updated.
  google.protobuf.Timestamp update_time = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Allows clients to perform consistent read-modify-writes
  // through optimistic concurrency control.
  //
  // Can be sent on update and delete requests to ensure the
  // client has an up-to-date value before proceeding.
  string etag = 11;

  // Output only. The Kubernetes version of the cluster.
  string kubernetes_version = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Annotations on the cluster.
  //
  // This field has the same restrictions as Kubernetes annotations.
  // The total size of all keys and values combined is limited to 256k.
  // Key can have 2 segments: prefix (optional) and name (required),
  // separated by a slash (/).
  // Prefix must be a DNS subdomain.
  // Name must be 63 characters or less, begin and end with alphanumerics,
  // with dashes (-), underscores (_), dots (.), and alphanumerics between.
  map<string, string> annotations = 13 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Workload Identity settings.
  WorkloadIdentityConfig workload_identity_config = 14
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Logging configuration for this cluster.
  LoggingConfig logging_config = 15 [(google.api.field_behavior) = OPTIONAL];

  // Output only. A set of errors found in the cluster.
  repeated AttachedClusterError errors = 20
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Configuration related to the cluster RBAC settings.
  AttachedClustersAuthorization authorization = 21
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Monitoring configuration for this cluster.
  MonitoringConfig monitoring_config = 23
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Proxy configuration for outbound HTTP(S) traffic.
  AttachedProxyConfig proxy_config = 24
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Binary Authorization configuration for this cluster.
  BinaryAuthorization binary_authorization = 25
      [(google.api.field_behavior) = OPTIONAL];
}

// Configuration related to the cluster RBAC settings.
message AttachedClustersAuthorization {
  // Optional. Users that can perform operations as a cluster admin. A managed
  // ClusterRoleBinding will be created to grant the `cluster-admin` ClusterRole
  // to the users. Up to ten admin users can be provided.
  //
  // For more info on RBAC, see
  // https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
  repeated AttachedClusterUser admin_users = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Groups of users that can perform operations as a cluster admin. A
  // managed ClusterRoleBinding will be created to grant the `cluster-admin`
  // ClusterRole to the groups. Up to ten admin groups can be provided.
  //
  // For more info on RBAC, see
  // https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
  repeated AttachedClusterGroup admin_groups = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// Identities of a user-type subject for Attached clusters.
message AttachedClusterUser {
  // Required. The name of the user, e.g. `my-gcp-id@gmail.com`.
  string username = 1 [(google.api.field_behavior) = REQUIRED];
}

// Identities of a group-type subject for Attached clusters.
message AttachedClusterGroup {
  // Required. The name of the group, e.g. `my-group@domain.com`.
  string group = 1 [(google.api.field_behavior) = REQUIRED];
}

// OIDC discovery information of the target cluster.
//
// Kubernetes Service Account (KSA) tokens are JWT tokens signed by the cluster
// API server. This fields indicates how Google Cloud Platform services
// validate KSA tokens in order to allow system workloads (such as GKE Connect
// and telemetry agents) to authenticate back to Google Cloud Platform.
//
// Both clusters with public and private issuer URLs are supported.
// Clusters with public issuers only need to specify the `issuer_url` field
// while clusters with private issuers need to provide both
// `issuer_url` and `oidc_jwks`.
message AttachedOidcConfig {
  // A JSON Web Token (JWT) issuer URI. `issuer` must start with `https://`.
  string issuer_url = 1;

  // Optional. OIDC verification keys in JWKS format (RFC 7517).
  // It contains a list of OIDC verification keys that can be used to verify
  // OIDC JWTs.
  //
  // This field is required for cluster that doesn't have a publicly available
  // discovery endpoint. When provided, it will be directly used
  // to verify the OIDC JWT asserted by the IDP.
  bytes jwks = 2 [(google.api.field_behavior) = OPTIONAL];
}

// AttachedServerConfig provides information about supported
// Kubernetes versions
message AttachedServerConfig {
  option (google.api.resource) = {
    type: "gkemulticloud.googleapis.com/AttachedServerConfig"
    pattern: "projects/{project}/locations/{location}/attachedServerConfig"
  };

  // The resource name of the config.
  string name = 1;

  // List of valid platform versions.
  repeated AttachedPlatformVersionInfo valid_versions = 2;
}

// Information about a supported Attached Clusters platform version.
message AttachedPlatformVersionInfo {
  // Platform version name.
  string version = 1;
}

// AttachedClusterError describes errors found on attached clusters.
message AttachedClusterError {
  // Human-friendly description of the error.
  string message = 1;
}

// Details of a proxy config.
message AttachedProxyConfig {
  // The Kubernetes Secret resource that contains the HTTP(S) proxy
  // configuration. The secret must be a JSON encoded proxy configuration
  // as described in
  KubernetesSecret kubernetes_secret = 1;
}

// Information about a Kubernetes Secret
message KubernetesSecret {
  // Name of the kubernetes secret.
  string name = 1;

  // Namespace in which the kubernetes secret is stored.
  string namespace = 2;
}
