// Copyright 2022 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.edgecontainer.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";

option go_package = "cloud.google.com/go/edgecontainer/apiv1/edgecontainerpb;edgecontainerpb";
option java_multiple_files = true;
option java_outer_classname = "ResourcesProto";
option java_package = "com.google.cloud.edgecontainer.v1";
option (google.api.resource_definition) = {
  type: "cloudkms.googleapis.com/CryptoKey"
  pattern: "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}"
};
option (google.api.resource_definition) = {
  type: "cloudkms.googleapis.com/CryptoKeyVersion"
  pattern: "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/cryptoKeyVersions/{crypto_key_version}"
};

// Represents the accessibility state of a customer-managed KMS key used for
// CMEK integration.
enum KmsKeyState {
  // Unspecified.
  KMS_KEY_STATE_UNSPECIFIED = 0;

  // The key is available for use, and dependent resources should be accessible.
  KMS_KEY_STATE_KEY_AVAILABLE = 1;

  // The key is unavailable for an unspecified reason. Dependent resources may
  // be inaccessible.
  KMS_KEY_STATE_KEY_UNAVAILABLE = 2;
}

// A Google Distributed Cloud Edge Kubernetes cluster.
message Cluster {
  option (google.api.resource) = {
    type: "edgecontainer.googleapis.com/Cluster"
    pattern: "projects/{project}/locations/{location}/clusters/{cluster}"
  };

  // Required. The resource name of the cluster.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "edgecontainer.googleapis.com/Cluster"
    }
  ];

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

  // Output only. The time when the cluster was last updated.
  google.protobuf.Timestamp update_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // Optional. Fleet configuration.
  Fleet fleet = 11 [(google.api.field_behavior) = OPTIONAL];

  // Required. Cluster-wide networking configuration.
  ClusterNetworking networking = 7 [(google.api.field_behavior) = REQUIRED];

  // Required. Immutable. RBAC policy that will be applied and managed by GEC.
  Authorization authorization = 9 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Optional. The default maximum number of pods per node used if a maximum value is not
  // specified explicitly for a node pool in this cluster. If unspecified, the
  // Kubernetes default value will be used.
  int32 default_max_pods_per_node = 8 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The IP address of the Kubernetes API server.
  string endpoint = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The PEM-encoded public certificate of the cluster's CA.
  string cluster_ca_certificate = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Cluster-wide maintenance policy configuration.
  MaintenancePolicy maintenance_policy = 12 [(google.api.field_behavior) = OPTIONAL];
}

// Cluster-wide networking configuration.
message ClusterNetworking {
  // Required. All pods in the cluster are assigned an RFC1918 IPv4 address from these
  // blocks. Only a single block is supported. This field cannot be changed
  // after creation.
  repeated string cluster_ipv4_cidr_blocks = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. All services in the cluster are assigned an RFC1918 IPv4 address from these
  // blocks. Only a single block is supported. This field cannot be changed
  // after creation.
  repeated string services_ipv4_cidr_blocks = 2 [(google.api.field_behavior) = REQUIRED];
}

// Fleet related configuration.
//
// Fleets are a Google Cloud concept for logically organizing clusters,
// letting you use and manage multi-cluster capabilities and apply
// consistent policies across your systems.
message Fleet {
  // Required. The name of the Fleet host project where this cluster will be registered.
  //
  // Project names are formatted as
  // `projects/<project-number>`.
  string project = 1 [(google.api.field_behavior) = REQUIRED];

  // Output only. The name of the managed Hub Membership resource associated to this cluster.
  //
  // Membership names are formatted as
  // `projects/<project-number>/locations/global/membership/<cluster-id>`.
  string membership = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A user principal for an RBAC policy.
message ClusterUser {
  // Required. An active Google username.
  string username = 1 [(google.api.field_behavior) = REQUIRED];
}

// RBAC policy that will be applied and managed by GEC.
message Authorization {
  // Required. User that will be granted the cluster-admin role on the cluster, providing
  // full access to the cluster. Currently, this is a singular field, but will
  // be expanded to allow multiple admins in the future.
  ClusterUser admin_users = 1 [(google.api.field_behavior) = REQUIRED];
}

// A set of Kubernetes nodes in a cluster with common configuration and
// specification.
message NodePool {
  option (google.api.resource) = {
    type: "edgecontainer.googleapis.com/NodePool"
    pattern: "projects/{project}/locations/{location}/clusters/{cluster}/nodePools/{node_pool}"
  };

  // Configuration for CMEK support for edge machine local disk encryption.
  message LocalDiskEncryption {
    // Immutable. The Cloud KMS CryptoKey e.g.
    // projects/{project}/locations/{location}/keyRings/{keyRing}/cryptoKeys/{cryptoKey}
    // to use for protecting node local disks. If not specified, a
    // Google-managed key will be used instead.
    string kms_key = 1 [
      (google.api.field_behavior) = IMMUTABLE,
      (google.api.resource_reference) = {
        type: "cloudkms.googleapis.com/CryptoKey"
      }
    ];

    // Output only. The Cloud KMS CryptoKeyVersion currently in use for protecting node local
    // disks. Only applicable if kms_key is set.
    string kms_key_active_version = 2 [
      (google.api.field_behavior) = OUTPUT_ONLY,
      (google.api.resource_reference) = {
        type: "cloudkms.googleapis.com/CryptoKeyVersion"
      }
    ];

    // Output only. Availability of the Cloud KMS CryptoKey. If not `KEY_AVAILABLE`, then
    // nodes may go offline as they cannot access their local data. This can be
    // caused by a lack of permissions to use the key, or if the key is disabled
    // or deleted.
    KmsKeyState kms_key_state = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Error status returned by Cloud KMS when using this key. This field may be
    // populated only if `kms_key_state` is not `KMS_KEY_STATE_KEY_AVAILABLE`.
    // If populated, this field contains the error status reported by Cloud KMS.
    google.rpc.Status kms_status = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Required. The resource name of the node pool.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "edgecontainer.googleapis.com/NodePool"
    }
  ];

  // Output only. The time when the node pool was created.
  google.protobuf.Timestamp create_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the node pool was last updated.
  google.protobuf.Timestamp update_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // Name of the Google Distributed Cloud Edge zone where this node pool will be
  // created. For example: `us-central1-edge-customer-a`.
  string node_location = 8;

  // Required. The number of nodes in the pool.
  int32 node_count = 6 [(google.api.field_behavior) = REQUIRED];

  // Only machines matching this filter will be allowed to join the node pool.
  // The filtering language accepts strings like "name=<name>", and is
  // documented in more detail in [AIP-160](https://google.aip.dev/160).
  string machine_filter = 7;

  // Optional. Local disk encryption options. This field is only used when enabling CMEK
  // support.
  LocalDiskEncryption local_disk_encryption = 9 [(google.api.field_behavior) = OPTIONAL];
}

// A Google Distributed Cloud Edge machine capable of acting as a Kubernetes
// node.
message Machine {
  option (google.api.resource) = {
    type: "edgecontainer.googleapis.com/Machine"
    pattern: "projects/{project}/locations/{location}/machines/{machine}"
  };

  // Required. The resource name of the machine.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "edgecontainer.googleapis.com/Machine"
    }
  ];

  // Output only. The time when the node pool was created.
  google.protobuf.Timestamp create_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the node pool was last updated.
  google.protobuf.Timestamp update_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // Canonical resource name of the node that this machine is responsible for
  // hosting e.g.
  // projects/{project}/locations/{location}/clusters/{cluster_id}/nodePools/{pool_id}/{node},
  // Or empty if the machine is not assigned to assume the role of a node.
  string hosted_node = 5;

  // The Google Distributed Cloud Edge zone of this machine.
  string zone = 6;

  // Output only. Whether the machine is disabled. If disabled, the machine is unable to
  // enter service.
  bool disabled = 8 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A VPN connection .
message VpnConnection {
  option (google.api.resource) = {
    type: "edgecontainer.googleapis.com/VpnConnection"
    pattern: "projects/{project}/locations/{location}/vpnConnections/{vpn_connection}"
  };

  // Project detail of the VPC network.
  message VpcProject {
    // The project of the VPC to connect to. If not specified, it is the same as
    // the cluster project.
    string project_id = 1;

    // Optional. The service account in the VPC project configured by user. It is used to
    // create/delete Cloud Router and Cloud HA VPNs for VPN connection. If this
    // SA is changed during/after a VPN connection is created, you need to
    // remove the Cloud Router and Cloud VPN resources in |project_id|.
    // It is in the form of
    // service-{project_number}@gcp-sa-edgecontainer.iam.gserviceaccount.com.
    string service_account = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  // The created connection details.
  message Details {
    // The Cloud Router info.
    message CloudRouter {
      // The created Cloud Router name.
      string name = 1;
    }

    // The Cloud VPN info.
    message CloudVpn {
      // The created Cloud VPN gateway name.
      string gateway = 1;
    }

    // The current connection state.
    enum State {
      // Unknown.
      STATE_UNSPECIFIED = 0;

      // Connected.
      STATE_CONNECTED = 1;

      // Still connecting.
      STATE_CONNECTING = 2;

      // Error occurred.
      STATE_ERROR = 3;
    }

    // The state of this connection.
    State state = 1;

    // The error message. This is only populated when state=ERROR.
    string error = 2;

    // The Cloud Router info.
    CloudRouter cloud_router = 3;

    // Each connection has multiple Cloud VPN gateways.
    repeated CloudVpn cloud_vpns = 4;
  }

  // Routing mode.
  enum BgpRoutingMode {
    // Unknown.
    BGP_ROUTING_MODE_UNSPECIFIED = 0;

    // Regional mode.
    REGIONAL = 1;

    // Global mode.
    GLOBAL = 2;
  }

  // Required. The resource name of VPN connection
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "edgecontainer.googleapis.com/VpnConnection"
    }
  ];

  // Output only. The time when the VPN connection was created.
  google.protobuf.Timestamp create_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the VPN connection was last updated.
  google.protobuf.Timestamp update_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Labels associated with this resource.
  map<string, string> labels = 4;

  // NAT gateway IP, or WAN IP address. If a customer has multiple NAT IPs, the
  // customer needs to configure NAT such that only one external IP maps to the
  // GMEC Anthos cluster. This is empty if NAT is not used.
  string nat_gateway_ip = 5;

  // Dynamic routing mode of the VPC network, `regional` or `global`.
  BgpRoutingMode bgp_routing_mode = 6 [deprecated = true];

  // The canonical Cluster name to connect to. It is in the form of
  // projects/{project}/locations/{location}/clusters/{cluster}.
  string cluster = 7 [(google.api.resource_reference) = {
                        type: "edgecontainer.googleapis.com/Cluster"
                      }];

  // The network ID of VPC to connect to.
  string vpc = 8;

  // Optional. Project detail of the VPC network. Required if VPC is in a different
  // project than the cluster project.
  VpcProject vpc_project = 11 [(google.api.field_behavior) = OPTIONAL];

  // Whether this VPN connection has HA enabled on cluster side. If enabled,
  // when creating VPN connection we will attempt to use 2 ANG floating IPs.
  bool enable_high_availability = 9;

  // Output only. The created connection details.
  Details details = 10 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Metadata for a given [google.cloud.location.Location][google.cloud.location.Location].
message LocationMetadata {
  // The set of available Google Distributed Cloud Edge zones in the location.
  // The map is keyed by the lowercase ID of each zone.
  map<string, ZoneMetadata> available_zones = 1;
}

// A Google Distributed Cloud Edge zone where edge machines are located.
message ZoneMetadata {
  // Quota for resources in this zone.
  repeated Quota quota = 1;
}

// Represents quota for Edge Container resources.
message Quota {
  // Name of the quota metric.
  string metric = 1;

  // Quota limit for this metric.
  double limit = 2;

  // Current usage of this metric.
  double usage = 3;
}

// Maintenance policy configuration.
message MaintenancePolicy {
  // Specifies the maintenance window in which maintenance may be performed.
  MaintenanceWindow window = 1;
}

// Maintenance window configuration
message MaintenanceWindow {
  // Configuration of a recurring maintenance window.
  RecurringTimeWindow recurring_window = 1;
}

// Represents an arbitrary window of time that recurs.
message RecurringTimeWindow {
  // The window of the first recurrence.
  TimeWindow window = 1;

  // An RRULE (https://tools.ietf.org/html/rfc5545#section-3.8.5.3) for how
  // this window recurs. They go on for the span of time between the start and
  // end time.
  string recurrence = 2;
}

// Represents an arbitrary window of time.
message TimeWindow {
  // The time that the window first starts.
  google.protobuf.Timestamp start_time = 1;

  // The time that the window ends. The end time must take place after the
  // start time.
  google.protobuf.Timestamp end_time = 2;
}
