// Copyright 2025 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.gkehub.policycontroller.v1beta;

option csharp_namespace = "Google.Cloud.GkeHub.PolicyController.V1Beta";
option go_package = "cloud.google.com/go/gkehub/policycontroller/apiv1beta/policycontrollerpb;policycontrollerpb";
option java_multiple_files = true;
option java_outer_classname = "PolicyControllerProto";
option java_package = "com.google.cloud.gkehub.policycontroller.v1beta";
option php_namespace = "Google\\Cloud\\GkeHub\\PolicyController\\V1beta";
option ruby_package = "Google::Cloud::GkeHub::PolicyController::V1beta";

// **Policy Controller**: State for a single cluster.
message MembershipState {
  // The set of states Policy Controller can exist in.
  enum LifecycleState {
    // The lifecycle state is unspecified.
    LIFECYCLE_STATE_UNSPECIFIED = 0;

    // The PC does not exist on the given cluster, and no k8s resources of any
    // type that are associated with the PC should exist there. The cluster
    // does not possess a membership with the PCH.
    NOT_INSTALLED = 1;

    // The PCH possesses a Membership, however the PC is not fully installed
    // on the cluster.
    // In this state the hub can be expected to be taking actions to
    // install the PC on the cluster.
    INSTALLING = 2;

    // The PC is fully installed on the cluster and in an operational mode.
    // In this state PCH will be reconciling state with the PC, and
    // the PC will be performing it's operational tasks per that software.
    // Entering a READY state requires that the hub has confirmed the PC is
    // installed and its pods are operational with the version of
    // the PC the PCH expects.
    ACTIVE = 3;

    // The PC is fully installed, but in the process of changing the
    // configuration (including changing the version of PC either up and down,
    // or modifying the manifests of PC) of the resources running on the
    // cluster. The PCH has a Membership, is aware of the version the cluster
    // should be running in, but has not confirmed for itself that the PC is
    // running with that version.
    UPDATING = 4;

    // The PC may have resources on the cluster,
    // but the PCH wishes to remove the Membership.
    // The Membership still exists.
    DECOMMISSIONING = 5;

    // The PC is not operational, and the PCH is unable to act to make it
    // operational.
    // Entering a CLUSTER_ERROR state happens automatically when the PCH
    // determines that a PC installed on the cluster is non-operative or
    // that the cluster does not meet requirements set for the PCH to
    // administer the cluster but has nevertheless been given an instruction to
    // do so (such as 'install').
    CLUSTER_ERROR = 6;

    // In this state, the PC may still be operational,
    // and only the PCH is unable to act.
    // The hub should not issue instructions to change the PC state,
    // or otherwise interfere with the on-cluster resources.
    // Entering a HUB_ERROR state happens automatically when the PCH determines
    // the hub is in an unhealthy state and it wishes to 'take hands off' to
    // avoid corrupting the PC or other data.
    HUB_ERROR = 7;

    // Policy Controller (PC) is installed but suspended. This means that the
    // policies are not enforced, but violations are still recorded (through
    // audit).
    SUSPENDED = 8;

    // PoCo Hub is not taking any action to reconcile cluster objects.  Changes
    // to those objects will not be overwritten by PoCo Hub.
    DETACHED = 9;
  }

  // Currently these include (also serving as map keys):
  // 1. "admission"
  // 2. "audit"
  // 3. "mutation"
  map<string, OnClusterState> component_states = 3;

  // The overall Policy Controller lifecycle state observed by the Hub Feature
  // controller.
  LifecycleState state = 4;

  // The overall content state observed by the Hub Feature controller.
  PolicyContentState policy_content_state = 6;
}

// The state of the policy controller policy content
message PolicyContentState {
  // The state of the template library
  OnClusterState template_library_state = 1;

  // The state of the any bundles included in the chosen
  // version of the manifest
  map<string, OnClusterState> bundle_states = 2;

  // The state of the referential data sync configuration.  This could
  // represent the state of either the syncSet object(s) or the config
  // object, depending on the version of PoCo configured by the user.
  OnClusterState referential_sync_config_state = 3;
}

// **Policy Controller**: Configuration for a single cluster.
// Intended to parallel the PolicyController CR.
message MembershipSpec {
  // Policy Controller configuration for the cluster.
  HubConfig policy_controller_hub_config = 1;

  // Version of Policy Controller installed.
  string version = 2;
}

// Configuration for Policy Controller
message HubConfig {
  // The set of installation specs that the Hub Feature controller may
  // actuate.
  enum InstallSpec {
    // Spec is unknown.
    INSTALL_SPEC_UNSPECIFIED = 0;

    // Request to uninstall Policy Controller.
    INSTALL_SPEC_NOT_INSTALLED = 1;

    // Request to install and enable Policy Controller.
    INSTALL_SPEC_ENABLED = 2;

    // Request to suspend Policy Controller i.e. its webhooks. If Policy
    // Controller is not installed, it will be installed but suspended.
    INSTALL_SPEC_SUSPENDED = 3;

    // Request to stop all reconciliation actions by PoCo Hub controller.
    // This is a breakglass mechanism to stop PoCo Hub from affecting
    // cluster resources.
    INSTALL_SPEC_DETACHED = 4;
  }

  // The install_spec represents the intended state specified by the
  // latest request that mutated install_spec in the feature spec,
  // not the lifecycle state of the
  // feature observed by the Hub feature controller
  // that is reported in the feature state.
  InstallSpec install_spec = 1;

  // Sets the interval for Policy Controller Audit Scans (in seconds).
  // When set to 0, this disables audit functionality altogether.
  optional int64 audit_interval_seconds = 2;

  // The set of namespaces that are excluded from Policy Controller checks.
  // Namespaces do not need to currently exist on the cluster.
  repeated string exemptable_namespaces = 3;

  // Enables the ability to use Constraint Templates that reference to objects
  // other than the object currently being evaluated.
  bool referential_rules_enabled = 4;

  // Logs all denies and dry run failures.
  bool log_denies_enabled = 5;

  // Enables the ability to mutate resources using Policy Controller.
  bool mutation_enabled = 6;

  // Monitoring specifies the configuration of monitoring.
  optional MonitoringConfig monitoring = 8;

  // Specifies the desired policy content on the cluster
  optional PolicyContentSpec policy_content = 9;

  // The maximum number of audit violations to be stored in a constraint.
  // If not set, the internal default (currently 20) will be used.
  optional int64 constraint_violation_limit = 10;

  // Map of deployment configs to deployments ("admission", "audit",
  // "mutation').
  map<string, PolicyControllerDeploymentConfig> deployment_configs = 11;
}

// Deployment-specific configuration.
message PolicyControllerDeploymentConfig {
  // Toleration of a node taint.
  message Toleration {
    // Matches a taint key (not necessarily unique).
    optional string key = 1;

    // Matches a taint operator.
    optional string operator = 2;

    // Matches a taint value.
    optional string value = 3;

    // Matches a taint effect.
    optional string effect = 4;
  }

  // The pod affinity configuration used by a deployment.
  enum Affinity {
    // No affinity configuration has been specified.
    AFFINITY_UNSPECIFIED = 0;

    // Affinity configurations will be removed from the deployment.
    NO_AFFINITY = 1;

    // Anti-affinity configuration will be applied to this deployment.
    // Default for admissions deployment.
    ANTI_AFFINITY = 2;
  }

  // Pod replica count.
  optional int64 replica_count = 1;

  // Container resource requirements.
  optional ResourceRequirements container_resources = 2;

  // Pod anti-affinity enablement. Deprecated: use `pod_affinity` instead.
  optional bool pod_anti_affinity = 3 [deprecated = true];

  // Pod tolerations of node taints.
  repeated Toleration pod_tolerations = 4;

  // Pod affinity configuration.
  Affinity pod_affinity = 5;
}

// ResourceRequirements describes the compute resource requirements.
message ResourceRequirements {
  // Limits describes the maximum amount of compute resources allowed for use by
  // the running container.
  optional ResourceList limits = 1;

  // Requests describes the amount of compute resources reserved for the
  // container by the kube-scheduler.
  optional ResourceList requests = 2;
}

// ResourceList contains container resource requirements.
message ResourceList {
  // Memory requirement expressed in Kubernetes resource units.
  optional string memory = 1;

  // CPU requirement expressed in Kubernetes resource units.
  optional string cpu = 2;
}

// The config specifying which default library templates to install.
message TemplateLibraryConfig {
  // How the template library should be installed
  enum Installation {
    // No installation strategy has been specified.
    INSTALLATION_UNSPECIFIED = 0;

    // Do not install the template library.
    NOT_INSTALLED = 1;

    // Install the entire template library.
    ALL = 2;
  }

  // Configures the manner in which the template library is installed on the
  // cluster.
  Installation installation = 2;
}

// MonitoringConfig specifies the backends Policy Controller should
// export metrics to. For example, to specify metrics should be exported to
// Cloud Monitoring and Prometheus, specify
// backends: ["cloudmonitoring", "prometheus"]
message MonitoringConfig {
  // Supported backend options for monitoring
  enum MonitoringBackend {
    // Backend cannot be determined
    MONITORING_BACKEND_UNSPECIFIED = 0;

    // Prometheus backend for monitoring
    PROMETHEUS = 1;

    // Stackdriver/Cloud Monitoring backend for monitoring
    CLOUD_MONITORING = 2;
  }

  // Specifies the list of backends Policy Controller will export to.
  // An empty list would effectively disable metrics export.
  repeated MonitoringBackend backends = 1;
}

// OnClusterState represents the state of a sub-component of Policy Controller.
message OnClusterState {
  // The lifecycle state of this component.
  MembershipState.LifecycleState state = 1;

  // Surface potential errors or information logs.
  string details = 2;
}

// BundleInstallSpec is the specification configuration for a single managed
// bundle.
message BundleInstallSpec {
  // The set of namespaces to be exempted from the bundle.
  repeated string exempted_namespaces = 2;
}

// PolicyContentSpec defines the user's desired content configuration on the
// cluster.
message PolicyContentSpec {
  // map of bundle name to BundleInstallSpec. The bundle name maps to the
  // `bundleName` key in the `policycontroller.gke.io/constraintData` annotation
  // on a constraint.
  map<string, BundleInstallSpec> bundles = 1;

  // Configures the installation of the Template Library.
  TemplateLibraryConfig template_library = 2;
}
