diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a3e2fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log + +# Ignore any .tfvars files that are generated automatically for each Terraform run. Most +# .tfvars files are managed as part of configuration and so should be included in +# version control. +# +# example.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* diff --git a/README.md b/README.md index 853464b..32f11c4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,362 @@ -# evmos-gcp -Google Kubernetes Engine (GKE) clusters on GCP, utilizing ArgoCD for multi-cluster application management, setting up monitoring, crafting a robust CI pipeline, and public exposure of services. +# Evmos Validator on Google Kubernetes Engine + +Evmos GCP aims to provide a configured EVMOS `Testnet` validator, a Google Kubernetes Engine (GKE) environement and a CI/CP pipeline for automation purposes. + + +## Summary Table + +- [Features](##features) +- [Prerequisites](#prerequisites) +- [GKE Cluster Creation on GCP](#gke-cluster-creation-on-gcp) +- [ArgoCD Installation](#argocd-instalation) +- [Creation of a private GKE cluster](#creation-of-a-private-gke-cluster) +- [Multi-Cluster Management with ArgoCD](#multi-cluster-management-with-argocd) +- [Monitoring Setup](#monitoring-setup) +- [Deployment of the Evmos Application](#deployement-of-the-evmos-application) +- [Continuous Integration (CI) Pipeline](#continuous-integration-ci-pipeline) +- [Troubleshooting](#troubleshooting) +- [Sources](#sources) +- [Join Evmos Validator's Community](#join-evmos-validators-community) + +## Features + +`k8s` directory +- Terraform manifests to deploy GKE clusters on Goocle Cloud Platform (GCP): + * Public cluster (could be used to run sentry nodes) + * Private cluster to keep validator(s) isolated + * Gateway controller or Athos Service Mesh Gateway + * Monitoring with Promethus and Grafana + +`Evmos` directory +- `manfiests` for deployment of the Evmos validator. Watched by ArgoCD +- `testnet-validator` Dockerfile with a set of script following different fashions of setting a testnet validator + +`ArgoCD` directory +- ArgoCD install for Continuous Deployment + - ArgoCD for multi-cluster application management + +Instructions to set CI/CD Pipelines with Google CloudBuild script and associated template + + +# Prerequisites + +## Install Terraform +Download and install Terraform from the official website: https://www.terraform.io/downloads.html + +## Google Cloud Platform Setup +Create a Google Cloud Project, if you don't have one already. +Enable the Kubernetes Engine API for your project. +Create a Service Account with the necessary permissions for Terraform to manage resources in your GCP project. + +## Configure Gcloud SDK + +Install https://cloud.google.com/sdk/gcloud/ +Install gke-gcloud-auth-plugin for use with kubectl by following the instructions (here)[https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke] + +## Install Kubectl, Gcloud CLI, gke-gcloud-auth-plugin & Argo CLI +```bash +sudo apt-get install apt-transport-https ca-certificates gnupg curl sudo +echo "deb [signed-by=/usr/share/keyrings/cloud.google.asc] https://packages.cloud.google.com/apt cloud-sdk main" \ + | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list + +sudo apt-get update +sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin +sudo apt-get install kubectl +``` +Configure kubectl +[GCloud doucentation on kubctl auth changes](https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke?hl=en) + +```bash +gcloud container clusters get-credentials $(terraform output -raw kubernetes_cluster_name) --region $(terraform output -raw region) +``` +Install ArgoCLI: https://github.com/argoproj/argo-workflows/releases/latest + +# GKE Cluster Creation on GCP + +Creates a VPC and subnet for the GKE cluster. This is highly recommended to keep GKE clusters isolated. +Terraform apply +```bash +cd k8s/public-cluster +terraform init +terraform apply +``` + +Verify with gcloud CLI +```bash +gcloud container clusters describe $(terraform output -raw kubernetes_cluster_name) --region europe-west1 --format='default(locations)' +``` +Expected output should be similar to this + locations: + - europe-west1-b + - europe-west1-c + - europe-west1-d + + +## Install Kubernetes Dashboard (optional) + +```bash +kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml +``` + +Use kubectl port forwaring to access the Web UI + +## Admin user setup +```bash +kubectl apply -f kubernetes-dashboard-admin.rbac.yaml +``` + +Generate Token +```bash +kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep service-controller-token | awk '{print $1}') +``` + +# ArgoCD Instalation + + +Run Terraform code in argocd directory +```bash +cd argocd +terraform init +terraform apply +``` +For more a secure setup exposed to the public use + +## Config ArgoCD API access (for test/demo only) + +Openning ArgoCD to Public LoadBalancer with no Access Control is a security risk +Use for short term demonstration purpose or use port forwarding instead ! +```bash +gcloud auth login +kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}' +kubectl get svc argocd-server -n argocd -o jsonpath='{.status.loadBalancer.ingress[0].ip}' +kubectl get all -n argocd +``` + +## Test ArgoCD setup with a basic Nginx app + +Let's use a simple Nginx Deployment Test on ArgoCD's GKE cluster +Fetch argocd password and login to the cli + +```bash +kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d +``` +Create a new ArgoCD deployment of test nginx app +```bash +argocd app create argocd-demo --repo https://github.com/gregsio/argocd-demo --path yamls --dest-namespace default --dest-server https://kubernetes.default.svc +``` + +# Creation of a private GKE cluster +```bash +cd k8s/private-cluster +terraform init +terraform apply +``` + +# Multi-Cluster Management with ArgoCD + +## Add a New GKE Private Cluster to ArgoCD + +```bash +gcloud container clusters list --region=us-central1 +kubectl config get-contexts +argocd cluster add gke_evmos-gcp_us-central1_gke-private-us +argocd cluster list +``` + the ouput should show both cluster as follow + + SERVER NAME VERSION STATUS MESSAGE PROJECT + https://34.16.114.206 gke_evmos-us-central1_gke-private-us1 1.27 Successful + https://kubernetes.default.svc in-cluster 1.27 Successful + +## Install the Nginx test App on the private GKE cluster + +```bash + argocd app create argocd-demo + \--repo https://github.com/gregsio/argocd-demo + \--path yamls + \ --dest-namespace default + \--dest-server https://34.16.114.206 +``` +# Monitoring Setup + +## Kubernetes Cluster Monitoring + +Clone kube-prometheus + +```bash +git clone https://github.com/prometheus-operator/kube-prometheus.git +cd kube-prometheus +``` +Install Promotheus & Graphana in a `monitoring` namespace +```bash +kubectl apply --server-side -f manifests/setup +kubectl wait \\n\t--for condition=Established \\n\t--all CustomResourceDefinition \\n\t--namespace=monitoring +kubectl apply -f manifests/ +``` + +## Access Grafana or Promotheus WEB UI + +Access via port forwarding: + +```bash +kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090 +kubectl --namespace monitoring port-forward svc/grafana 3000 +``` +# Deployement of the Evmos Application + +The Evmos/testnet directory contains a custom set of scripts and a Dockerfile to configure an *Evmos* testnet node using any of the following approaches: + +- Fecthing Genesis file (default setup) +- Snapshot sync +- State sync + +Update the k8s/manifests/statfulset.yaml if you want to use a different script at startup +The 3 scripts are in the container's PATH. + +## Monitoring + + Follow this instructions: [Graphana Cosmos Dashboard](https://github.com/zhangyelong/cosmos-dashboard) + +The testet-validator Docker container is already configure with the following thanks to the `evmos/tesnet-validator/testnet_node.sh` script. +```bash + sed -i 's/prometheus = false/prometheus = true/' "$CONFIG" + sed -i 's/prometheus-retention-time = "0"/prometheus-retention-time = "1000000000000"/g' "$APP_TOML" +``` + +The tendermint metrics, is accessible on port is 26660 as configured by `evmos/manifests/service.yaml` & `evmos/manifests/statefulset.yaml` + +The Prometheus config requires an update to [add aditional targets](https://github.com/zhangyelong/cosmos-dashboard#configure-prometheus-targets) + + +## Use ArgoCD for Continuous Deployment(CD Pipeline) + +ArgoCD continuously monitors the git repository for any changes that happen and then pulls the changes. It compares the current state of the deployed application with the desired state in the git repository and then applies the changes by automatically deploying the manifest on the GKE cluster. + + +Create the *Evmos* application in ArgoCD via ArgoCD CLI + +```bash +argocd app create evmos \ + --repo https://github.com/gregsio/evmos-gcp \ + --path evmos/manifests \ + --revision dev \ + --dest-namespace evmostestnet \ + --dest-server https://kubernetes.default.svc +``` + +Deployement Workflow: + +0. Fork this repo +1. Build the Docker image using the provided Dockerfile +2. Push it to a remote Docker repository +3. Update the *image* reference in the *manifests/statefulset.yaml* and commit +4. Sync the *Evmos* application with ArgoCD UI + +You can also activate ArgoCD auto sync, so k8s manifets are applied. + +To automate the steps detailed in this section keep reading... + +# Continuous Integration (CI) Pipeline + +- The Infrastructure code (k8s directory) such as VPCs setup and GKE clusters setup is automated using *TerraformCloud*. + +- The Continuous Integration of the Evmos validator application is done using *Google CloudBuild*. + +Continuous Integration WorkFlow + +When a developper make a change to the code, and pushes it to the application repository, +Cloud build then invokes triggers either manually or automatically by the events on the repository such as pushes or pull requests. + +Once the trigger gets invoked by any events, cloud build then executes the instructions written in the build config file (cloudbuild.yaml) such as building the docker image from Dockerfile provided and pushing it to the artifact registry configured. +Once the image with the new tag got pushed to the registry, it will get updated in the Kubernetes manifest repository. + + +## Evmos Validator CI Pipeline +This section automates the steps outlined in "Semi-automated Deployement Workflow". +2 CI files are provided to achieve this: +- `evmos/manifests/statefulset.yaml.tpl` +- `evmos/testnet/cloudbuild.yaml` + +Prerequistes: +- Move the code under evmos/testnet to a *separate* GitHub *source repository* (hard requirement) + +### Configuring Cloud Build GitHub Trigger + +To set up the GitHub trigger we first need to connect to the *source repository* and then configure a trigger. The steps involved in connecting the cloud build to the source repository are given [here](https://cloud.google.com/build/docs/automating-builds/create-manage-triggers#connect_repo). + +Once the repository got connected we can configure a trigger by following the steps given [here](https://cloud.google.com/build/docs/automating-builds/create-manage-triggers#build_trigger). + +You should now have a cloud build trigger that is connected to your *source repository* + +Go to CloudBuild GCP console +- Add the three environmental variables we are using in the cloud build steps +- Associate a custom service account, see further info on `user-specified service accounts` setup [here](https://cloud.google.com/build/docs/securing-builds/configure-user-specified-service-accounts) + +``` +"roles/iam.serviceAccountUser", +"roles/logging.logWriter", +"roles/secretmanager.secretAccessor", +"roles/artifactregistry.writer" +``` + +**SUBSTITUTION VARIABLES** [more info here](https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values) +`_ARTIFACT_REPO` your *source repository* name +`_CD_BRANCH` your *source repository* branch +`IMAGE_TAG` set to `$BRANCH_NAME#*` + +'_ARTIFACT_REPO’ is used to set the artifact repository name. we can pass the repository name based on our environment like dev, stage, prod, or on your personal choice. +The variable ‘_CD_BRANCH’ refers to the branch of the second git repository i.e the Kubernetes manifest repository. + +The third variable ‘_IMAGE_TAG’ will be used to assign a custom tag based out of branch name or release tag + +![diagram](assets/ci-diagram.png) + +## K8s Clusters CI Pipeline + +With Terrform Cloud the Terrafrom state files will be safely stored encrypted at rest and GCP credentials will be safely stored as well, more info on [HashiCorp documentation](https://developer.hashicorp.com/terraform/cloud-docs/workspaces/variables/managing-variables#sensitive-values) + + +- See prerequisites section [here](https://developer.hashicorp.com/terraform/tutorials/cloud/kubernetes-consul-vault-pipeline#prerequisites) +- Configure 2 different Terraform Cloud workspaces & GitHub repositories pointing respectively to `k8s/private-cluster` & `k8s/public-cluster +- Configure run triggers, see documentation (here)[https://developer.hashicorp.com/terraform/tutorials/cloud/cloud-run-triggers#configure-a-run-trigger] + + +# Troubleshooting + +## Master Authorized Network +When creating a private cluster with a [private endpoint](https://cloud.google.com/kubernetes-engine/docs/how-to/authorized-networks#benefits_with_private_clusters) (`enable_private_endpoint = true`), +your cluster will **not** have a publicly addressable endpoint. + +When using this setting, any CIDR ranges listed in the `master_authorized_networks` configuration *must* come from your private IP space. +If you include a CIDR block outside your private space, you might see this error: + +``` +Error: Error waiting for creating GKE cluster: Invalid master authorized networks: network "73.89.231.174/32" is not a reserved network, which is required for private endpoints. + + on .terraform/modules/gke-cluster-dev.gke/terraform-google-kubernetes-engine-9.2.0/modules/beta-private-cluster/cluster.tf line 22, in resource "google_container_cluster" "primary": + 22: resource "google_container_cluster" "primary" { +``` + +To resolve this error, update your configuration to either: + +* Enable a public endpoint (with `enable_private_endpoint = false`) +* Update your `master_authorized_networks` configuration to only use CIDR blocks from your private IP space. + + +# Sources + +- [Terraform Google modules](https://github.com/terraform-google-modules) +- [Terraform Google Kubernetes Engine module](https://github.com/terraform-google-modules/terraform-google-kubernetes-engine) +- [Why Deploy with Terrafrom?](https://developer.hashicorp.com/terraform/tutorials/kubernetes/gke#why-deploy-with-terraform) + +## Evmos's documentation + +- [Validator Minimum Requirements](https://docs.evmos.org/validate/#minimum-requirements) +- [Run a Validator](https://docs.evmos.org/validate/setup-and-configuration/run-a-validator) +- [Common Problems](https://docs.evmos.org/validate/setup-and-configuration/run-a-validator#common-problems) +- [Testnet Documentation](https://docs.evmos.org/validate/testnet) +- [Testnet Faucet](https://faucet.evmos.dev/) + +# Join Evmos Validator's Community + +- [Evmos Discord Channel](https://discord.com/invite/evmos) \ No newline at end of file diff --git a/argocd/.terraform.lock.hcl b/argocd/.terraform.lock.hcl new file mode 100644 index 0000000..536e0ae --- /dev/null +++ b/argocd/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/helm" { + version = "2.11.0" + constraints = "2.11.0" + hashes = [ + "h1:zxfRtgpWrVZwjkIBuI+7jc52+u1QBA/k7LQZiCiq3Z8=", + "zh:013857c88f3e19a4b162344e21dc51891c4ac8b600da8391f7fb2b6d234961e1", + "zh:044fffa233a93cdcf8384afbe9e1ab6c9d0b5b176cbae56ff465eb9611302975", + "zh:208b7cdd4fa3a1b25ae817dc00a9198ef98be0ddc3a577b5b72bc0f006afb997", + "zh:3e8b33f56cfe387277572a92037a1ca1cbe4e3aa6b5c19a8c2431193b07f7865", + "zh:7dd663d5619bd71676899b05b19d36f585189fdabc6b0b03c23579524a8fd9bf", + "zh:ae5329cb3e5bf0b86b02e823aac3ef3bd0d4b1618ff013cd0076dca0be8322e4", + "zh:ba6201695b55d51bedacdb017cb8d03d7a8ada51d0168ac44fef3fa791a85ab4", + "zh:c61285c8b1ba10f50cf94c9dcf98f2f3b720f14906a18be71b9b422279b5d806", + "zh:d522d388246f38b9f329c511ec579b516d212670b954f9dab64efb27e51862af", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f92546e26b670da61437ae2cbd038427c9374ce5f7a78df52193397da90bd997", + "zh:f9ad1407e5c0d5e3474094491025bf100828e8c1a01acdf9591d7dd1eb59f961", + ] +} diff --git a/argocd/argocd-install.tf b/argocd/argocd-install.tf new file mode 100644 index 0000000..2fc330e --- /dev/null +++ b/argocd/argocd-install.tf @@ -0,0 +1,10 @@ +resource "helm_release" "argocd" { + name = "argocd" + repository = "https://argoproj.github.io/argo-helm" + chart = "argo-cd" + namespace = "argocd" + create_namespace = true + version = "3.35.4" + values = [file("./values/argocd.yaml")] +} +# helm install argocd -n argocd -f values/argocd.yaml \ No newline at end of file diff --git a/argocd/provider.tf b/argocd/provider.tf new file mode 100644 index 0000000..0b46b14 --- /dev/null +++ b/argocd/provider.tf @@ -0,0 +1,15 @@ +provider "helm" { + kubernetes { + config_path = "~/.kube/config" + } +} +terraform { + required_version = ">= 1.0.0" + + required_providers { + helm = { + source = "hashicorp/helm" + version = "= 2.11.0" + } + } +} \ No newline at end of file diff --git a/argocd/testapp/.terraform.lock.hcl b/argocd/testapp/.terraform.lock.hcl new file mode 100644 index 0000000..629159f --- /dev/null +++ b/argocd/testapp/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.23.0" + hashes = [ + "h1:xyFc77aYkPoU4Xt1i5t0B1IaS8TbTtp9aCSuQKDayII=", + "zh:10488a12525ed674359585f83e3ee5e74818b5c98e033798351678b21b2f7d89", + "zh:1102ba5ca1a595f880e67102bbf999cc8b60203272a078a5b1e896d173f3f34b", + "zh:1347cf958ed3f3f80b3c7b3e23ddda3d6c6573a81847a8ee92b7df231c238bf6", + "zh:2cb18e9f5156bc1b1ee6bc580a709f7c2737d142722948f4a6c3c8efe757fa8d", + "zh:5506aa6f28dcca2a265ccf8e34478b5ec2cb43b867fe6d93b0158f01590fdadd", + "zh:6217a20686b631b1dcb448ee4bc795747ebc61b56fbe97a1ad51f375ebb0d996", + "zh:8accf916c00579c22806cb771e8909b349ffb7eb29d9c5468d0a3f3166c7a84a", + "zh:9379b0b54a0fa030b19c7b9356708ec8489e194c3b5e978df2d31368563308e5", + "zh:aa99c580890691036c2931841e88e7ee80d59ae52289c8c2c28ea0ac23e31520", + "zh:c57376d169875990ac68664d227fb69cd0037b92d0eba6921d757c3fd1879080", + "zh:e6068e3f94f6943b5586557b73f109debe19d1a75ca9273a681d22d1ce066579", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/argocd/testapp/evmos.tf b/argocd/testapp/evmos.tf new file mode 100644 index 0000000..1c0a316 --- /dev/null +++ b/argocd/testapp/evmos.tf @@ -0,0 +1,26 @@ +provider "argocd" { + server_addr = "http://34.77.174.77" +} + +resource "kubernetes_manifest" "evmos_app" { + manifest = { + apiVersion = "argoproj.io/v1alpha1" + kind = "Application" + metadata = { + name = "evmos" + namespace = "evmos" + } + spec = { + project = "default" + source = { + repoURL = "https://github.com/gregsio/argocd-demo" + targetRevision = "HEAD" + path = "yamls" + } + destination = { + server = "https://kubernetes.default.svc" + namespace = "default" + } + } + } +} diff --git a/argocd/testapp/evmos.yaml b/argocd/testapp/evmos.yaml new file mode 100644 index 0000000..535bc3e --- /dev/null +++ b/argocd/testapp/evmos.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: evmos +spec: + project: default + source: + repoURL: 'https://github.com/justmeandopensource/argocd-demo' + targetRevision: dev + path: yamls + destination: + server: 'https://kubernetes.default.svc' + namespace: 'default' +#https://github.com/gregsio/evmos-gcp.git \ No newline at end of file diff --git a/argocd/values/argocd.yaml b/argocd/values/argocd.yaml new file mode 100644 index 0000000..74fa564 --- /dev/null +++ b/argocd/values/argocd.yaml @@ -0,0 +1,11 @@ +--- +global: + image: + tag: v2.6.6 + +dex: + enabled: false + +server: + extraArgs: + - --insecure \ No newline at end of file diff --git a/assets/ci-diagram.png b/assets/ci-diagram.png new file mode 100644 index 0000000..209b7db Binary files /dev/null and b/assets/ci-diagram.png differ diff --git a/evmos/manifests/deployment.yaml b/evmos/manifests/deployment.yaml new file mode 100644 index 0000000..82b38f9 --- /dev/null +++ b/evmos/manifests/deployment.yaml @@ -0,0 +1,64 @@ +# apiVersion: apps/v1 +# kind: Deployment +# metadata: +# name: evmos +# spec: +# replicas: 1 +# selector: +# matchLabels: +# app: evmos +# template: +# metadata: +# labels: +# app: evmos +# spec: +# strategy: +# type: recreate +# initContainers: +# - name: volume-permissions +# image: busybox +# command: ["sh", "-c", "chown -R 1000:1000 /evmos"] +# volumeMounts: +# - name: evmosnode0 +# mountPath: /evmos +# volumes: +# - name: evmosnode0 +# persistentVolumeClaim: +# claimName: evmosnode0 +# containers: +# - name: evmosnode0 +# securityContext: +# allowPrivilegeEscalation: false +# capabilities: +# drop: +# - ALL +# privileged: false +# readOnlyRootFilesystem: true +# runAsNonRoot: true +# runAsUser: 1000 +# image: gregsaram/evmos:1.4.0 +# resources: +# requests: +# memory: "64Mi" +# cpu: "250m" +# limits: +# memory: "128Mi" +# cpu: "500m" +# args: +# - /bin/sh +# - -c +# - 'echo n | /usr/bin/local_node.sh --no-install' +# ports: +# - containerPort: 26656 +# name: p2p +# - containerPort: 26657 +# name: tmtrpc +# - containerPort: 8545 +# name: ethrpc +# - containerPort: 8546 +# name: websocket +# - containerPort: 1317 +# name: telemetry +# volumeMounts: +# - mountPath: /evmos +# name: evmosnode0 diff --git a/evmos/manifests/gateway.yaml b/evmos/manifests/gateway.yaml new file mode 100644 index 0000000..3f8f8f4 --- /dev/null +++ b/evmos/manifests/gateway.yaml @@ -0,0 +1,36 @@ +# apiVersion: gateway.networking.k8s.io/v1beta1 +# kind: Gateway +# metadata: +# name: jsonrpc-gateway +# namespace: evmos +# spec: +# gatewayClassName: gke-l7-rilb +# listeners: +# - name: http +# protocol: HTTP +# port: 8545 +# allowedRoutes: +# kinds: +# - kind: HTTPRoute +# selector: +# matchLabels: +# app: evmos +# namespaces: +# from: All +# --- +# apiVersion: gateway.networking.k8s.io/v1beta1 +# kind: HTTPRoute +# metadata: +# name: jsonrpc-route +# namespace: evmos +# labels: +# app: evmos +# spec: +# rules: +# - matches: +# - path: +# type: Prefix +# value: / +# forwardTo: +# - serviceName: evmos +# port: 8545 diff --git a/evmos/manifests/persistentvolume.yaml b/evmos/manifests/persistentvolume.yaml new file mode 100644 index 0000000..1e16255 --- /dev/null +++ b/evmos/manifests/persistentvolume.yaml @@ -0,0 +1,32 @@ +# apiVersion: v1 +# kind: PersistentVolumeClaim +# metadata: +# name: evmosnode0 +# spec: +# selector: +# matchLabels: +# evmos-pv: "true" +# accessModes: +# - ReadWriteOnce +# resources: +# requests: +# storage: 20Gi +# storageClassName: standard-rwo +# status: {} +# --- +# apiVersion: v1 +# kind: PersistentVolume +# metadata: +# name: evmos-pv +# labels: +# evmos-pv: "true" +# spec: +# capacity: +# storage: 20Gi +# accessModes: +# - ReadWriteOnce +# persistentVolumeReclaimPolicy: Retain +# storageClassName: standard-rwo +# ## Change volume type for production hostPath stores on node's filesystem +# hostPath: +# path: /evmos diff --git a/evmos/manifests/service.yaml b/evmos/manifests/service.yaml new file mode 100644 index 0000000..6113bd6 --- /dev/null +++ b/evmos/manifests/service.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: Service +metadata: + name: evmos +spec: + clusterIP: None + ports: + - name: p2p + protocol: TCP + port: 26656 + targetPort: 26656 + - name: tmtrpc + protocol: TCP + port: 26657 + targetPort: 26657 + - name: ethrpc + protocol: TCP + port: 8545 + targetPort: 8545 + - name: websocket + protocol: TCP + port: 8546 + targetPort: 8546 + - name: telemetry + protocol: TCP + port: 1317 + targetPort: 1317 + - name: promotheus + protocol: TCP + port: 26660 + targetPort: 26660 + selector: + app: evmos + +##how about 9090 ?? + + # the gRPC server (default port: 9090), + # the REST server (default port: 1317), + # the CometBFT RPC endpoint (default port: 26657). diff --git a/evmos/manifests/statefulset.yaml b/evmos/manifests/statefulset.yaml new file mode 100644 index 0000000..292593f --- /dev/null +++ b/evmos/manifests/statefulset.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: validator +spec: + selector: + matchLabels: + app: evmos + serviceName: "evmos" + replicas: 1 + template: + metadata: + labels: + app: evmos + spec: + #terminationGracePeriodSeconds: 10 + containers: + - name: evmosnode + securityContext: + fsGroup: 0 + runAsUser: 0 + runAsGroup: 0 + allowPrivilegeEscalation: true + capabilities: + drop: + - ALL + privileged: true + readOnlyRootFilesystem: false # to be changed in prod + runAsNonRoot: false + image: gregsaram/evmos:15.0.0-rc2-testnet-0.2 + resources: + requests: + memory: "20Gi" + cpu: "2" + limits: + memory: "25Gi" + cpu: "4" + args: ["sh", "-c", "/usr/bin/testnet_node.sh -y & sleep 84000s"] + ports: + - containerPort: 26656 + name: p2p + - containerPort: 26657 + name: tmtrpc + - containerPort: 8545 + name: ethrpc + - containerPort: 8546 + name: websocket + - containerPort: 1317 + name: telemetry + - containerPort: 26660 + name: promotheus + volumeMounts: + - name: evmos-vol + mountPath: /evmos + volumeClaimTemplates: + - metadata: + name: evmos-vol + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 20Gi diff --git a/evmos/manifests/statefulset.yaml.tpl b/evmos/manifests/statefulset.yaml.tpl new file mode 100644 index 0000000..ec24b12 --- /dev/null +++ b/evmos/manifests/statefulset.yaml.tpl @@ -0,0 +1,60 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: validator +spec: + selector: + matchLabels: + app: evmos + serviceName: "evmos" + replicas: 1 + template: + metadata: + labels: + app: evmos + spec: + #terminationGracePeriodSeconds: 10 + containers: + - name: evmosnode + securityContext: + fsGroup: 0 + runAsUser: 0 + runAsGroup: 0 + allowPrivilegeEscalation: true + capabilities: + drop: + - ALL + privileged: true + readOnlyRootFilesystem: false # to be changed in prod + runAsNonRoot: false + image: us-docker.pkg.dev/GOOGLE_CLOUD_PROJECT/evmos/evmosdtestnet:COMMIT_SHA + resources: + requests: + memory: "20Gi" + cpu: "2" + limits: + memory: "25Gi" + cpu: "4" + args: ["sh", "-c", "/usr/bin/testnet_node.sh -y & sleep 84000s"] + ports: + - containerPort: 26656 + name: p2p + - containerPort: 26657 + name: tmtrpc + - containerPort: 8545 + name: ethrpc + - containerPort: 8546 + name: websocket + - containerPort: 1317 + name: telemetry + volumeMounts: + - name: evmos-vol + mountPath: /evmos + volumeClaimTemplates: + - metadata: + name: evmos-vol + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 20Gi diff --git a/evmos/tesnet-validator/Dockerfile b/evmos/tesnet-validator/Dockerfile new file mode 100644 index 0000000..1838890 --- /dev/null +++ b/evmos/tesnet-validator/Dockerfile @@ -0,0 +1,22 @@ + +FROM tharsishq/evmos:v15.0.0-rc2 +WORKDIR /root +USER root + +RUN apk add lz4-libs + +COPY testnet_node.sh /usr/bin/testnet_node.sh +RUN chmod +x /usr/bin/testnet_node.sh + +COPY statesync.sh /usr/bin/statesync.sh +RUN chmod +x /usr/bin/statesync.sh + +COPY snapshot.sh /usr/bin/snapshot.sh +RUN chmod +x /usr/bin/snapshot.sh + +# USER 1000 +WORKDIR /evmos + +EXPOSE 26656 26657 1317 9090 8545 8546 + +CMD ["evmosd"] diff --git a/evmos/tesnet-validator/README.md b/evmos/tesnet-validator/README.md new file mode 100644 index 0000000..744943c --- /dev/null +++ b/evmos/tesnet-validator/README.md @@ -0,0 +1,40 @@ +## Evmos testnet + +Evmosd Dockerile and coniguration scripts based tharsishq/evmos:v15.0.0-rc2 +This is intended to run on Kubernetes (k8s), see manifests directory for more info on the k8s setup. + +The steps involved in setting up the CI/CD pipeline are listed below: + +1. Setting up the Continuous Integration Pipeline + +1.1 Configuring the GitHub repositories. + +1.2 Configuring Cloud Build GitHub Trigger + +2. Setting up the Continuous Delivery Pipeline + +2.1 Configuring the GKE cluster + +2.2 Configuring ArgoCD on GKE + + +Pre-Requisites: + + Two code repositories, one containing application code and the other containing Kubernetes manifest files and deployment templates. Here we have used GitHub repositories for demonstration. + Cloud build configured with GitHub application code repository to execute a build based on the events in the repository. + Artifact Registry to store the images built from cloud build. + A GKE cluster for running the Docker images of the applications and an ArgoCD server used for continuous delivery. + + +WorkFlow: + +1. Continuous Integration(CI Pipeline): + + A Developer makes the changes in the code, fixes the bugs, and pushes it to the application repository. + Cloud build then invokes triggers either manually or automatically by the events on the repository such as pushes or pull requests. + Once the trigger gets invoked by any events, cloud build then executes the instructions written in the build config file (cloudbuild.yaml) such as building the docker image from Dockerfile provided and pushing it to the artifact registry configured. + Once the image with the new tag got pushed to the registry, it will get updated in the Kubernetes manifest repository. + +2. Continuous Deployment(CD Pipeline) + + ArgoCD continuously monitors the git repository for any changes that happen and then pulls the changes. It compares the current state of the deployed application with the desired state in the git repository and then applies the changes by automatically deploying the manifest on the GKE cluster. \ No newline at end of file diff --git a/evmos/tesnet-validator/cloudbuild.yaml b/evmos/tesnet-validator/cloudbuild.yaml new file mode 100644 index 0000000..f41fe59 --- /dev/null +++ b/evmos/tesnet-validator/cloudbuild.yaml @@ -0,0 +1,40 @@ +#### Building Docker Image #### +steps: +- name: 'gcr.io/cloud-builders/docker' + args: [ 'build', '-t', 'us-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REPO}/evmosdtestnet:$SHORT_SHA', '-t', 'us-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REPO}/evmosdtestnet:${_IMAGE_TAG}', '.' ] + +#### Pushing Docker Image #### +- name: 'gcr.io/cloud-builders/docker' + entrypoint: /bin/sh + args: + - -c + - | + docker push us-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REPO}/evmosdtestnet:$SHORT_SHA + docker push us-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REPO}/evmosdtestnet:${_IMAGE_TAG} + +# This step generates the new manifest +- name: 'gcr.io/cloud-builders/gcloud' + entrypoint: /bin/sh + secretEnv: ['GIT_ACCESS_TOKEN'] + args: + - '-c' + - | + git clone https://gregsio:$$GIT_ACCESS_TOKEN@github.com/gregsio/evmos-gcp.git -b ${_CD_BRANCH} + echo "Updating image tag version ..." + cd evmos-gcp/k8s/maniests + sed "s/GOOGLE_CLOUD_PROJECT/$PROJECT_ID/g" statefulset.yaml.tpl | \ + sed "s/COMMIT_SHA/${SHORT_SHA}/g" > deployment.yaml + echo "Pushing changes to k8s manifest repo ..." + git config --global user.name "gregs" + git config --global user.email "github@gregs.io" + git add -A + git commit -m "[Cloud Builder] Updated image tag us-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REPO}/evmosdtestnet:$SHORT_SHA" + git push https://gregsio:$$GIT_ACCESS_TOKEN@github.com//evmos-gcp.git ${_CD_BRANCH} + +availableSecrets: + secretManager: + - versionName: projects/$PROJECT_NUMBER/secrets/github-access-token/versions/latest + env: 'GIT_ACCESS_TOKEN' + +# options: +# logging: CLOUD_LOGGING_ONLY diff --git a/evmos/tesnet-validator/genesis_edit.py b/evmos/tesnet-validator/genesis_edit.py new file mode 100644 index 0000000..a38938e --- /dev/null +++ b/evmos/tesnet-validator/genesis_edit.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +import ijson +import json +import os +import sys + +def process_json(file_path): + backup_path = f"{file_path}.bak" + os.rename(file_path, backup_path) + + with open(backup_path, 'rb') as input_file: + objects = ijson.items(input_file, '') + for obj in objects: + obj['app_state']['staking']['params']['bond_denom'] = 'aevmos' + obj['app_state']['crisis']['constant_fee']['denom'] = 'aevmos' + obj['app_state']['gov']['deposit_params']['min_deposit'][0]['denom'] = 'aevmos' + #obj['app_state']['gov']['params']['min_deposit'][0]['denom'] = 'aevmos' + obj['app_state']['evm']['params']['evm_denom'] = 'aevmos' + obj['app_state']['inflation']['params']['mint_denom'] = 'aevmos' + with open(file_path, 'w') as output_file: + json.dump(obj, output_file, ensure_ascii=False, indent=2) + +if __name__ == "__main__": + if len(sys.argv) != 2: + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + process_json(sys.argv[1]) diff --git a/evmos/tesnet-validator/snapshot.sh b/evmos/tesnet-validator/snapshot.sh new file mode 100644 index 0000000..409d212 --- /dev/null +++ b/evmos/tesnet-validator/snapshot.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +set -e +trap 'echo "Error on line $LINENO";' ERR + +CHAINID="${CHAIN_ID:-evmos_9000-4}" +MONIKER="testnetvalidator-gregsio" + +# Remember to change to other types of keyring like 'file' in-case exposing to outside world, +# otherwise your balance will be wiped quickly +# The keyring test does not require private key to steal tokens from you +KEYRING="test" +KEYALGO="eth_secp256k1" +LOGLEVEL="info" +HOMEDIR="/evmos/evmosd" +CONFIGDIR="$HOMEDIR/config" +DATADIR="$HOMEDIR/data" + +SNAPSHOTNAME="evmos_18472724.tar.lz4" + +# Path variables +CONFIG="$CONFIGDIR/config.toml" +APP_TOML="$CONFIGDIR/app.toml" +GENESIS="$CONFIGDIR/genesis.json" + +for cmd in jq curl lz4 evmosd; do + command -v $cmd >/dev/null 2>&1 || { echo >&2 "$cmd is required but it's not installed. Aborting."; exit 1; } +done + + +# Setup client config +evmosd config chain-id "$CHAINID" --home "$HOMEDIR" +evmosd config keyring-backend "$KEYRING" --home "$HOMEDIR" + +update_or_add() { + key=$1 + value=$2 + # Check if the instruction exists + if grep -q "^$key = " $CONFIG; then + # If the instruction exists, update it using sed + sed -i -e "s/^$key = .*/$key = $value/" $CONFIG + else + # If the instruction doesn't exist, add it using echo + echo "$key = $value" >> $CONFIG + fi +} + +# Configuration for snapshot sync +update_or_add "pruning" "\"custom\"" "$APP_TOML" +update_or_add "pruning-keep-recent" "100" "$APP_TOML" +update_or_add "pruning-keep-every" "0" "$APP_TOML" +update_or_add "pruning-interval" "10" "$APP_TOML" +sed -i 's/indexer = kv/indexer = null/g' "$CONFIG" + +# Enable prometheus metrics and all APIs for dev node +sed -i 's/prometheus = false/prometheus = true/' "$CONFIG" +sed -i 's/prometheus-retention-time = "0"/prometheus-retention-time = "1000000000000"/g' "$APP_TOML" +sed -i 's/enabled = false/enabled = true/g' "$APP_TOML" +sed -i 's/enable = false/enable = true/g' "$APP_TOML" +# Don't enable memiavl by default +grep -q -F '[memiavl]' "$APP_TOML" && sed -i '/\[memiavl\]/,/^\[/ s/enable = true/enable = false/' "$APP_TOML" + +# Stream the snapshot into database location. + +curl -o - -L https://snapshots.polkachu.com/testnet-snapshots/evmos/${SNAPSHOTNAME} \ + | lz4 -c -d - \ + | tar -x -C $HOMEDIR \ + || { echo "snapshot ${SNAPSHOTNAME} not available, use the latest one. check https://polkachu.com/testnets/evmos/snapshots"; exit 1; } + +cp ${DATADIR}/priv_validator_state.json ${CONFIGDIR}/priv_validator_state.json + +evmosd tendermint unsafe-reset-all --home $HOME/.evmosd --keep-addr-book + +echo "evmosd tx staking create-validator ..." +evmosd tx staking create-validator \ +--amount=1000000atevmos \ +--pubkey=$(evmosd tendermint show-validator) \ +--moniker="${MONIKER}" \ +--chain-id='evmos_9000-4' \ +--commission-rate="0.05" \ +--commission-max-rate="0.10" \ +--commission-max-change-rate="0.01" \ +--min-self-delegation="1000000" \ +--gas="auto" \ +--gas-prices="0.025atevmos" \ +--from='mykey' \ +--home="${HOMEDIR}" diff --git a/evmos/tesnet-validator/statesync.sh b/evmos/tesnet-validator/statesync.sh new file mode 100755 index 0000000..b4f2a05 --- /dev/null +++ b/evmos/tesnet-validator/statesync.sh @@ -0,0 +1,130 @@ +#!/bin/bash +# used to exit on first error (any non-zero exit code) +set -e +trap 'echo "Error on line $LINENO";' ERR + +CHAINID="${CHAIN_ID:-evmos_9000-4}" +MONIKER="testnetvalidator-gregsio" +# Remember to change to other types of keyring like 'file' in-case exposing to outside world, +# otherwise your balance will be wiped quickly +# The keyring test does not require private key to steal tokens from you +KEYRING="test" +KEYALGO="eth_secp256k1" +LOGLEVEL="info" + +# Set dedicated home directory for the evmosd instance +#HOMEDIR="~/.evmosd" +HOMEDIR="/evmos/evmosd" +CONFIGDIR="$HOMEDIR/config" + +# Path variables +CONFIG=$CONFIGDIR/config.toml +APP_TOML=$CONFIGDIR/app.toml +GENESIS=$CONFIGDIR/genesis.json + +# Parse input flags +install=true +overwrite="" + +for cmd in jq curl evmosd; do + command -v $cmd >/dev/null 2>&1 || { echo >&2 "$cmd is required but it's not installed. Aborting."; exit 1; } +done + +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -y) + echo "Flag -y passed -> Overwriting the previous chain data." + overwrite="y" + shift # Move past the flag + ;; + -n) + echo "Flag -n passed -> Not overwriting the previous chain data." + overwrite="n" + shift # Move past the argument + ;; + *) + echo "Unknown flag passed: $key -> Exiting script!" + exit 1 + ;; + esac +done + +if [[ $overwrite = "" ]]; then + if [ -d "$HOMEDIR" ]; then + printf "\nAn existing folder at '%s' was found. You can choose to delete this folder and start a new local node with new keys from genesis. When declined, the existing local node is started. \n" "$HOMEDIR" + echo "Overwrite the existing configuration and start a new local node? [y/n]" + read -r overwrite + else + overwrite="y" + fi +fi + +if [[ $overwrite == "y" || $overwrite == "Y" ]]; then + # Remove the previous folder + rm -rf "$HOMEDIR" + + # Setup client config + evmosd config chain-id "$CHAINID" --home "$HOMEDIR" + evmosd config keyring-backend "$KEYRING" --home "$HOMEDIR" + + # Polkachu endpoint - see https://polkachu.com/testnets/evmos/state_sync + SNAP_RPC="https://evmos-testnet-rpc.polkachu.com:443" + LATEST_HEIGHT=$(curl -s "$SNAP_RPC/block" | jq -r .result.block.header.height); \ + BLOCK_HEIGHT=$((LATEST_HEIGHT - 2000)); \ + TRUST_HASH=$(curl -s "$SNAP_RPC/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash) + + # Import keys from mnemonics + # myKey address 0x7cb61d4117ae31a12e393a1cfa3bac666481d02e | evmos10jmp6sgh4cc6zt3e8gw05wavvejgr5pwjnpcky + VAL_KEY="mykey" + VAL_MNEMONIC="gesture inject test cycle original hollow east ridge hen combine junk child bacon zero hope comfort vacuum milk pitch cage oppose unhappy lunar seat" + echo "$VAL_MNEMONIC" | evmosd keys add "$VAL_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$HOMEDIR" + + # Store the validator address in a variable to use it later + node_address=$(evmosd keys show -a "$VAL_KEY" --keyring-backend "$KEYRING" --home "$HOMEDIR") + + # Set moniker and chain-id for Evmos (Moniker can be anything, chain-id must be an integer) + echo "init" + evmosd init $MONIKER --chain-id "$CHAINID" --home "$HOMEDIR" + + # Allocate genesis accounts (cosmos formatted addresses) + evmosd add-genesis-account "$(evmosd keys show "$VAL_KEY" -a --keyring-backend "$KEYRING" --home "$HOMEDIR")" 100000000000000000000000000aevmos --keyring-backend "$KEYRING" --home "$HOMEDIR" + + # Enable prometheus metrics and all APIs for dev node + sed -i 's/prometheus = false/prometheus = true/' "$CONFIG" + sed -i 's/prometheus-retention-time = "0"/prometheus-retention-time = "1000000000000"/g' "$APP_TOML" + sed -i 's/enabled = false/enabled = true/g' "$APP_TOML" + sed -i 's/enable = false/enable = true/g' "$APP_TOML" + # Don't enable memiavl by default + grep -q -F '[memiavl]' "$APP_TOML" && sed -i '/\[memiavl\]/,/^\[/ s/enable = true/enable = false/' "$APP_TOML" + + # Config updates + echo "config" + sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \ + s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$SNAP_RPC,$SNAP_RPC\"| ; \ + s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \ + s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $CONFIG + + update_or_add() { + key=$1 + value=$2 + + # Check if the instruction exists + if grep -q "^$key = " $CONFIG; then + # If the instruction exists, update it using sed + sed -i -e "s/^$key = .*/$key = $value/" $CONFIG + else + # If the instruction doesn't exist, add it using echo + echo "$key = $value" >> $CONFIG + fi + } + + # Update or add the configuration instructions + update_or_add "pruning" "\"custom\"" + update_or_add "pruning-keep-every" "2000" + update_or_add "snapshot-interval" "2000" + update_or_add "snapshot-keep-recent" "5" + + echo "reset" + evmosd tendermint unsafe-reset-all --home $HOMEDIR --keep-addr-book +fi \ No newline at end of file diff --git a/evmos/tesnet-validator/testnet_node.sh b/evmos/tesnet-validator/testnet_node.sh new file mode 100755 index 0000000..567e14e --- /dev/null +++ b/evmos/tesnet-validator/testnet_node.sh @@ -0,0 +1,178 @@ +#!/bin/bash + +CHAINID="${CHAIN_ID:-evmos_9000-4}" +MONIKER="testnetvalidator-gregsio" +# Remember to change to other types of keyring like 'file' in-case exposing to outside world, +# otherwise your balance will be wiped quickly +# The keyring test does not require private key to steal tokens from you +KEYRING="test" +KEYALGO="eth_secp256k1" +LOGLEVEL="info" +# Set dedicated home directory for the evmosd instance +HOMEDIR="/evmos/evmosd" +CONFIGDIR="$HOMEDIR/config" + +# to trace evm +#TRACE="--trace" +TRACE="" + +# Path variables +CONFIG=$HOMEDIR/config/config.toml +APP_TOML=$HOMEDIR/config/app.toml +GENESIS=$HOMEDIR/config/genesis.json +TMP_GENESIS=$HOMEDIR/config/tmp_genesis.json + +# validate dependencies are installed +command -v jq >/dev/null 2>&1 || { + echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/" + exit 1 +} + +command -v wget >/dev/null 2>&1 || { + echo >&2 "wget not installed." + exit 1 +} + +# used to exit on first error (any non-zero exit code) +set -e + +# Parse input flags +install=true +overwrite="" + +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -y) + echo "Flag -y passed -> Overwriting the previous chain data." + overwrite="y" + shift # Move past the flag + ;; + -n) + echo "Flag -n passed -> Not overwriting the previous chain data." + overwrite="n" + shift # Move past the argument + ;; + *) + echo "Unknown flag passed: $key -> Exiting script!" + exit 1 + ;; + esac +done + +# User prompt if neither -y nor -n was passed as a flag +# and an existing local node configuration is found. +if [[ $overwrite = "" ]]; then + if [ -d "$HOMEDIR" ]; then + printf "\nAn existing folder at '%s' was found. You can choose to delete this folder and start a new local node with new keys from genesis. When declined, the existing local node is started. \n" "$HOMEDIR" + echo "Overwrite the existing configuration and start a new local node? [y/n]" + read -r overwrite + else + overwrite="y" + fi +fi + +# Setup local node if overwrite is set to Yes, otherwise skip setup +if [[ $overwrite == "y" || $overwrite == "Y" ]]; then + # Remove the previous folder + rm -rf "$HOMEDIR" + + # Set client config + echo "client config" + evmosd config keyring-backend "$KEYRING" --home "$HOMEDIR" + evmosd config chain-id "$CHAINID" --home "$HOMEDIR" + + # myKey address 0x7cb61d4117ae31a12e393a1cfa3bac666481d02e | evmos10jmp6sgh4cc6zt3e8gw05wavvejgr5pwjnpcky + VAL_KEY="mykey" + VAL_MNEMONIC="gesture inject test cycle original hollow east ridge hen combine junk child bacon zero hope comfort vacuum milk pitch cage oppose unhappy lunar seat" + + echo "VAL_KEY $VAL_KEY" + # Import keys from mnemonics + echo "$VAL_MNEMONIC" | evmosd keys add "$VAL_KEY" --recover --keyring-backend "$KEYRING" --algo "$KEYALGO" --home "$HOMEDIR" + + # Store the validator address in a variable to use it later + node_address=$(evmosd keys show -a "$VAL_KEY" --keyring-backend "$KEYRING" --home "$HOMEDIR") + + # Set moniker and chain-id for Evmos (Moniker can be anything, chain-id must be an integer) + evmosd tendermint unsafe-reset-all --home "$HOMEDIR" + evmosd init $MONIKER --chain-id "$CHAINID" --home "$HOMEDIR" + + # Download Genesis file for testnet evmos_9000-4 +# wget -O ${GENESIS} https://archive.evmos.dev/evmos_9000-4/genesis.json + wget -O ${GENESIS} https://snapshots.polkachu.com/testnet-genesis/evmos/genesis.json + + # Update persistent_peers and seeds for testnet setup + PEERS=`curl -sL https://raw.githubusercontent.com/evmos/testnets/main/evmos_9000-4/peers.txt | sort -r | head -n 10 | awk '{print $1}' | paste -s -d, -` + sed -i.bak -e "s/^persistent_peers *=.*/persistent_peers = \"$PEERS\"/" ${CONFIG} + + SEEDS=`curl -sL https://raw.githubusercontent.com/evmos/testnets/main/evmos_9000-4/seeds.txt | awk '{print $1}' | paste -s -d, -` + sed -i '/^seeds =/s/^/#/; /^#seeds =/a seeds = "'"$SEEDS"'"' ${CONFIG} + + # enable prometheus metrics and all APIs for dev node + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' 's/prometheus = false/prometheus = true/' "$CONFIG" + sed -i '' 's/prometheus-retention-time = 0/prometheus-retention-time = 1000000000000/g' "$APP_TOML" + sed -i '' 's/enabled = false/enabled = true/g' "$APP_TOML" + sed -i '' 's/enable = false/enable = true/g' "$APP_TOML" + # Don't enable memiavl by default + grep -q -F '[memiavl]' "$APP_TOML" && sed -i '' '/\[memiavl\]/,/^\[/ s/enable = true/enable = false/' "$APP_TOML" + else + sed -i 's/prometheus = false/prometheus = true/' "$CONFIG" + sed -i 's/prometheus-retention-time = "0"/prometheus-retention-time = "1000000000000"/g' "$APP_TOML" + sed -i 's/enabled = false/enabled = true/g' "$APP_TOML" + sed -i 's/enable = false/enable = true/g' "$APP_TOML" + # Don't enable memiavl by default + grep -q -F '[memiavl]' "$APP_TOML" && sed -i '/\[memiavl\]/,/^\[/ s/enable = true/enable = false/' "$APP_TOML" + fi + + # Edit genesys file in python to parse the JSON file in a streaming manner + # Less memory intensive + # echo "editing genesis" + # /usr/bin/genesis_edit.py $GENESIS + + # Run this to ensure everything worked and that the genesis file is setup correctly + echo "validating genesis" + evmosd validate-genesis --home "$HOMEDIR" +fi + + echo "evmosd tx staking create-validator ..." + evmosd tx staking create-validator \ + --amount=1000000atevmos \ + --pubkey=$(evmosd tendermint show-validator) \ + --moniker="${MONIKER}" \ + --chain-id='evmos_9000-4' \ + --commission-rate="0.05" \ + --commission-max-rate="0.10" \ + --commission-max-change-rate="0.01" \ + --min-self-delegation="1000000" \ + --gas="auto" \ + --gas-prices="0.025atevmos" \ + --from='mykey' \ + --home="${HOMEDIR}" + +# evmosd tx staking create-validator \ +# --amount=1000000000atevmos \ +# --pubkey=$(evmosd tendermint show-validator) \ +# --moniker="EvmosWhale" \ +# --chain-id=evmos_9000-4 \ +# --commission-rate="0.10" \ +# --commission-max-rate="0.20" \ +# --commission-max-change-rate="0.01" \ +# --min-self-delegation="1000000" \ +# --gas="auto" \ +# --gas-prices="0.025atevmos" \ +# --from='mykey' + +# Start the node +evmosd start \ + --metrics "$TRACE" \ + --log_level $LOGLEVEL \ + --json-rpc.api eth,txpool,personal,net,debug,web3 \ + --home "$HOMEDIR" + + +evmosd start \ + --metrics "" \ + --log_level info \ + --json-rpc.api eth,txpool,personal,net,debug,web3 \ + --home "/evmos/evmosd" diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..af3e896 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,4 @@ +# Examples + +Curated inspiration sources following industry standards. +Should be used to further improve the current state of evmos-gcp. \ No newline at end of file diff --git a/examples/asm/README.md b/examples/asm/README.md new file mode 100644 index 0000000..1ff0897 --- /dev/null +++ b/examples/asm/README.md @@ -0,0 +1,212 @@ +# Istio Service Mesh + +You can use [Istio](https://istio.io) to enable [service mesh features](https://cloud.google.com/service-mesh/docs/overview) such as traffic management, observability, and security. Istio can be provisioned using Anthos Service Mesh (ASM), the Open Source Software (OSS) istioctl tool, or via other Istio providers. You can then label individual namespaces for sidecar injection and configure an Istio gateway to replace the frontend-external load balancer. + +# Provision a GKE Cluster + +Create a GKE cluster with at least 4 nodes, machine type `e2-standard-4`, [GKE Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity), and the [Kubernetes Gateway API resources](https://cloud.google.com/kubernetes-engine/docs/how-to/deploying-gateways): + +_Note: using the classic `istio-ingressgateway` instead of Gateway API is another option not covered in this component._ + +```bash +PROJECT_ID="" +ZONE="" +CLUSTER_NAME="onlineboutique" + +gcloud container clusters create ${CLUSTER_NAME} \ + --project=${PROJECT_ID} \ + --zone=${ZONE} \ + --machine-type=e2-standard-4 \ + --num-nodes=4 \ + --workload-pool ${PROJECT_ID}.svc.id.goog \ + --gateway-api "standard" +``` + +# Provision and Configure Istio Service Mesh + +## Provision managed `Anthos Service Mesh` via Fleet feature API + +ASM provides a managed service mesh experience that includes Managed Control Plane (MCP) and Managed Data Plane (MDP) upgrades. + +The recommended way to [install ASM](https://cloud.google.com/service-mesh/docs/managed/provision-managed-anthos-service-mesh) is using the fleet feature API: + +```bash +# Enable ASM and Fleet APIs +gcloud services enable mesh.googleapis.com --project ${PROJECT_ID} + +# Register GKE cluster with Fleet +gcloud container fleet memberships register ${CLUSTER_NAME} \ + --gke-cluster ${ZONE}/${CLUSTER_NAME} \ + --enable-workload-identity + +FLEET_PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format 'value(projectNumber)') +# Apply mesh_id label to clusters that should be added to the service mesh +gcloud container clusters update --project ${PROJECT_ID} ${CLUSTER_NAME} \ + --zone ${ZONE} --update-labels="mesh_id=proj-$FLEET_PROJECT_NUMBER" + +# Enable managed Anthos Service Mesh on the cluster +gcloud container fleet mesh update --project ${PROJECT_ID} \ + --management automatic \ + --memberships ${CLUSTER_NAME} + +# Enable sidecar injection for Kubernetes namespace where workload is deployed +kubectl label namespace default istio-injection- istio.io/rev=asm-managed --overwrite +``` +_Note: You can ignore any label "istio-injection" not found errors. The istio-injection=enabled annotation would also work but ASM prefers revision labels._ + +Follow the [Managed ASM Verification](https://cloud.google.com/service-mesh/docs/managed/provision-managed-anthos-service-mesh#verify_the_control_plane_has_been_provisioned) steps to confirm it is working. + +## Provision OSS `Istio` via istioctl + +Alternatively you can install OSS Istio by following the [getting started guide](https://istio.io/latest/docs/setup/getting-started/): + +```bash +# Install istio 1.17 or above +istioctl install --set profile=minimal -y + +# Enable sidecar injection for Kubernetes namespace(s) where microservices-demo is deployed +kubectl label namespace default istio-injection=enabled + +# Make sure the istiod injection webhook port 15017 is accessible via GKE master nodes +# Otherwise your replicaset-controller may be blocked when trying to create new pods with: +# Error creating: Internal error occurred: failed calling +# webhook "namespace.sidecar-injector.istio.io" ... context deadline exceeded +gcloud compute firewall-rules list --filter="name~gke-[0-9a-z-]*-master" +NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED +gke-onlineboutique-c94d71e8-master gke-vpc INGRESS 1000 tcp:10250,tcp:443 False + +# Update firewall rule (or create a new one) to allow webhook port 15017 +gcloud compute firewall-rules update gke-onlineboutique-c94d71e8-master \ + --allow tcp:10250,tcp:443,tcp:15017 +``` + +# Deploy and Validate Online Boutique with `Istio` + +## Deploy via Kustomize component + +Once the service mesh and namespace injection are configured, you can then deploy the Istio manifests using Kustomize. You should also include the [service-accounts component](../service-accounts) if you plan on using AuthorizationPolicies. + +From the `kustomize/` folder at the root level of this repository, execute these commands: +```bash +kustomize edit add component components/service-accounts +kustomize edit add component components/service-mesh-istio +``` + +This will update the `kustomize/kustomization.yaml` file which could be similar to: +```yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- base +components: +- components/service-accounts +- components/service-mesh-istio +``` + +_Note: `service-mesh-istio` component includes the same delete patch as the `non-public-frontend` component. Trying to use both those components in your kustomization.yaml file will result in an error._ + +You can locally render these manifests by running `kubectl kustomize .` or deploying them by running `kubectl apply -k .` + +The output should be similar to: +``` +serviceaccount/adservice created +serviceaccount/cartservice created +serviceaccount/checkoutservice created +serviceaccount/currencyservice created +serviceaccount/emailservice created +serviceaccount/frontend created +serviceaccount/loadgenerator created +serviceaccount/paymentservice created +serviceaccount/productcatalogservice created +serviceaccount/recommendationservice created +serviceaccount/shippingservice created +service/adservice created +service/cartservice created +service/checkoutservice created +service/currencyservice created +service/emailservice created +service/frontend created +service/paymentservice created +service/productcatalogservice created +service/recommendationservice created +service/redis-cart created +service/shippingservice created +deployment.apps/adservice created +deployment.apps/cartservice created +deployment.apps/checkoutservice created +deployment.apps/currencyservice created +deployment.apps/emailservice created +deployment.apps/frontend created +deployment.apps/loadgenerator created +deployment.apps/paymentservice created +deployment.apps/productcatalogservice created +deployment.apps/recommendationservice created +deployment.apps/redis-cart created +deployment.apps/shippingservice created +gateway.gateway.networking.k8s.io/istio-gateway created +httproute.gateway.networking.k8s.io/frontend-route created +serviceentry.networking.istio.io/allow-egress-google-metadata created +serviceentry.networking.istio.io/allow-egress-googleapis created +virtualservice.networking.istio.io/frontend created +``` + +# Verify Online Boutique Deployment + +Run `kubectl get pods,gateway,svc` to see pods and gateway are in a healthy and ready state. + +The output should be similar to: +``` +NAME READY STATUS RESTARTS AGE +pod/adservice-6cbd9794f9-8c4gv 2/2 Running 0 47s +pod/cartservice-667bbd5f6-84j8v 2/2 Running 0 47s +pod/checkoutservice-547557f445-bw46n 2/2 Running 0 47s +pod/currencyservice-6bd8885d9c-2cszv 2/2 Running 0 47s +pod/emailservice-64997dcf97-8fpsd 2/2 Running 0 47s +pod/frontend-c54778dcf-wbgmr 2/2 Running 0 46s +pod/istio-gateway-istio-8577b948c6-cxl8j 1/1 Running 0 45s +pod/loadgenerator-ccfd4d598-jh6xj 2/2 Running 0 46s +pod/paymentservice-79b77cd7c-6hth7 2/2 Running 0 46s +pod/productcatalogservice-5f75795545-nk5wv 2/2 Running 0 46s +pod/recommendationservice-56dd4c7df5-gnwwr 2/2 Running 0 46s +pod/redis-cart-799c85c644-pxsvt 2/2 Running 0 46s +pod/shippingservice-64f8df74f5-7wllf 2/2 Running 0 45s + +NAME CLASS ADDRESS READY AGE +gateway.gateway.networking.k8s.io/istio-gateway istio 35.247.123.146 True 45s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/adservice ClusterIP 10.68.231.142 9555/TCP 49s +service/cartservice ClusterIP 10.68.184.25 7070/TCP 49s +service/checkoutservice ClusterIP 10.68.177.213 5050/TCP 49s +service/currencyservice ClusterIP 10.68.249.87 7000/TCP 49s +service/emailservice ClusterIP 10.68.205.123 5000/TCP 49s +service/frontend ClusterIP 10.68.94.203 80/TCP 48s +service/istio-gateway-istio LoadBalancer 10.68.147.158 35.247.123.146 15021:30376/TCP,80:30332/TCP 45s +service/kubernetes ClusterIP 10.68.0.1 443/TCP 65m +service/paymentservice ClusterIP 10.68.114.19 50051/TCP 48s +service/productcatalogservice ClusterIP 10.68.240.153 3550/TCP 48s +service/recommendationservice ClusterIP 10.68.117.97 8080/TCP 48s +service/redis-cart ClusterIP 10.68.189.126 6379/TCP 48s +service/shippingservice ClusterIP 10.68.221.62 50051/TCP 48s + +``` +Find the IP address of your Istio gateway and visit the application frontend in a web browser. + +```sh +INGRESS_HOST="$(kubectl get gateway istio-gateway \ + -o jsonpath='{.status.addresses[*].value}')" +curl -v "http://$INGRESS_HOST" +``` + +# Additional service mesh demos using Online Boutique + +- [Canary deployment](https://github.com/GoogleCloudPlatform/istio-samples/tree/master/istio-canary-gke) +- [Security (mTLS, JWT, Authorization)](https://github.com/GoogleCloudPlatform/istio-samples/tree/master/security-intro) +- [Cloud Operations (Stackdriver)](https://github.com/GoogleCloudPlatform/istio-samples/tree/master/istio-stackdriver) +- [Stackdriver metrics (Open source Istio)](https://github.com/GoogleCloudPlatform/istio-samples/tree/master/stackdriver-metrics) + +# Related Resources + +- [Deploying classic istio-ingressgateway in ASM](https://cloud.google.com/service-mesh/docs/gateways#deploy_gateways) +- [Uninstall Istio via istioctl](https://istio.io/latest/docs/setup/install/istioctl/#uninstall-istio) +- [Uninstall Anthos Service Mesh](https://cloud.google.com/service-mesh/docs/uninstall) diff --git a/examples/asm/allow-egress-googleapis.yaml b/examples/asm/allow-egress-googleapis.yaml new file mode 100644 index 0000000..50410b2 --- /dev/null +++ b/examples/asm/allow-egress-googleapis.yaml @@ -0,0 +1,46 @@ +# Copyright 2018 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. + +apiVersion: networking.istio.io/v1alpha3 +kind: ServiceEntry +metadata: + name: allow-egress-googleapis +spec: + hosts: + - "accounts.google.com" # Used to get token + - "*.googleapis.com" + ports: + - number: 80 + protocol: HTTP + name: http + - number: 443 + protocol: HTTPS + name: https +--- +apiVersion: networking.istio.io/v1alpha3 +kind: ServiceEntry +metadata: + name: allow-egress-google-metadata +spec: + hosts: + - metadata.google.internal + addresses: + - 169.254.169.254 # GCE metadata server + ports: + - number: 80 + name: http + protocol: HTTP + - number: 443 + name: https + protocol: HTTPS diff --git a/examples/asm/frontend-gateway.yaml b/examples/asm/frontend-gateway.yaml new file mode 100644 index 0000000..4f62844 --- /dev/null +++ b/examples/asm/frontend-gateway.yaml @@ -0,0 +1,42 @@ +# Copyright 2018 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. + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: istio-gateway +spec: + gatewayClassName: istio + listeners: + - name: http + port: 80 + protocol: HTTP + allowedRoutes: + namespaces: + from: Same +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: frontend-route +spec: + parentRefs: + - name: istio-gateway + rules: + - matches: + - path: + value: / + backendRefs: + - name: frontend + port: 80 diff --git a/examples/asm/frontend.yaml b/examples/asm/frontend.yaml new file mode 100644 index 0000000..23cd648 --- /dev/null +++ b/examples/asm/frontend.yaml @@ -0,0 +1,27 @@ +# Copyright 2018 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. + +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: frontend +spec: + hosts: + - "frontend.default.svc.cluster.local" + http: + - route: + - destination: + host: frontend + port: + number: 80 diff --git a/examples/asm/kustomization.yaml b/examples/asm/kustomization.yaml new file mode 100644 index 0000000..2399e65 --- /dev/null +++ b/examples/asm/kustomization.yaml @@ -0,0 +1,28 @@ +# 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. + +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component +resources: + - allow-egress-googleapis.yaml + - frontend-gateway.yaml + - frontend.yaml +patches: +# frontend - delete frontend-external service (same as non-public-frontend component) +- patch: |- + apiVersion: v1 + kind: Service + metadata: + name: frontend-external + $patch: delete diff --git a/examples/gke-fleets-with-argocd/README.md b/examples/gke-fleets-with-argocd/README.md new file mode 100644 index 0000000..7c6a69e --- /dev/null +++ b/examples/gke-fleets-with-argocd/README.md @@ -0,0 +1,233 @@ +# 🚲 GKE Poc Toolkit Demo: GKE Fleet setup with ArgoCD +This demo shows you how to bootstrap a Fleet of GKE clusters using ArgoCD as your gitops engine. +Services in play: +* [Argocd](https://argo-cd.readthedocs.io/en/stable/) +* [Argo Rollouts](https://argoproj.github.io/argo-rollouts/) +* [GKE](https://cloud.google.com/kubernetes-engine/docs) +* [Multi Cluster Services](https://cloud.google.com/kubernetes-engine/docs/concepts/multi-cluster-services) +* [Multi Cluster Ingress](https://cloud.google.com/kubernetes-engine/docs/concepts/multi-cluster-ingress) +* [Anthos Service Mesh w/ Managed Control Plane](https://cloud.google.com/service-mesh/docs/overview#managed_anthos_service_mesh) + + + +![diagram](assets/diagram.png) + +## Pre-reqs +If you don't have these tools already, please install: +* [ArgoCD CLI](https://argo-cd.readthedocs.io/en/stable/cli_installation/) +* Install the [Github CLI](https://github.com/cli/cli), make sure you are authenticated, and set your git defaults. +```bash +gh auth login +git config --global user.email "you@example.com" +git config --global user.name "Your Name" +``` + +## Fleet Infra setup + +1. **Initiliaze the GKE POC Toolkit (gkekitctl init).** +```bash +export GKE_PROJECT_ID= +export OS="darwin" # choice of darwin or amd64 +gcloud config set project $GKE_PROJECT_ID +gcloud auth login +gcloud auth application-default login + +ROOT_DIR=`pwd` +mkdir gke-poc-toolkit && cd "$_" +VERSION=$(curl -s https://api.github.com/repos/GoogleCloudPlatform/gke-poc-toolkit/releases/latest | grep browser_download_url | cut -d "/" -f 8 | tail -1) +curl -sLSf -o ./gkekitctl https://github.com/GoogleCloudPlatform/gke-poc-toolkit/releases/download/${VERSION}/gkekitctl-${OS} && chmod +x ./gkekitctl + +./gkekitctl init +``` + +2. **Clone the demo repo and copy folders that house dry configs for this demo.** +```bash +cd ${ROOT_DIR} +git clone https://github.com/GoogleCloudPlatform/gke-poc-toolkit-demos.git +cp -rf gke-poc-toolkit-demos/gke-fleets-with-argocd/argo-repo-sync ./ +cp -rf gke-poc-toolkit-demos/gke-fleets-with-argocd/argo-cd-gke ./ +cp -rf gke-poc-toolkit-demos/gke-fleets-with-argocd/scripts ./ +cp -rf gke-poc-toolkit-demos/gke-fleets-with-argocd/config.yaml ./gke-poc-toolkit/config.yaml +rm -rf gke-poc-toolkit-demos +``` + +3. **Export vars and add them to your GKE POC toolkit config.yaml.** +``` bash +cd ${ROOT_DIR}/gke-poc-toolkit +if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' -e "s/clustersProjectId: \"my-project\"/clustersProjectId: \"${GKE_PROJECT_ID}\"/g" config.yaml + sed -i '' -e "s/governanceProjectId: \"my-project\"/governanceProjectId: \"${GKE_PROJECT_ID}\"/g" config.yaml + sed -i '' -e "s/vpcProjectId: \"my-host-project\"/vpcProjectId: \"${GKE_PROJECT_ID}\"/g" config.yaml +else + sed -i -e "s/clustersProjectId: \"my-project\"/clustersProjectId: \"${GKE_PROJECT_ID}\"/g" config.yaml + sed -i -e "s/governanceProjectId: \"my-project\"/governanceProjectId: \"${GKE_PROJECT_ID}\"/g" config.yaml + sed -i -e "s/vpcProjectId: \"my-host-project\"/vpcProjectId: \"${GKE_PROJECT_ID}\"/g" config.yaml +fi +``` + +4. **Run the gkekitctl create command from this directory.** This will take about 15 minutes to run. +```bash +./gkekitctl create --config config.yaml +``` + +5. **Connect to your newly-created GKE clusters** + +```bash +gcloud container clusters get-credentials mccp-central-01 --region us-central1 --project ${GKE_PROJECT_ID} +``` + +6. **We highly recommend installing [kubectx and kubens](https://github.com/ahmetb/kubectx) to switch kubectl contexts between clusters with ease. Once done, you can validate you clusters like so.** +```bash +kubectx mccp-central-01=gke_${GKE_PROJECT_ID}_us-central1_mccp-central-01 +kubectl get nodes +``` + +*Expected output for each cluster*: +```bash +NAME STATUS ROLES AGE VERSION +gke-mccp-central-01-linux-gke-toolkit-poo-12b0fa78-grhw Ready 11m v1.21.6-gke.1500 +gke-mccp-central-01-linux-gke-toolkit-poo-24d712a2-jm5g Ready 11m v1.21.6-gke.1500 +gke-mccp-central-01-linux-gke-toolkit-poo-6fb11d07-h6xb Ready 11m v1.21.6-gke.1500 +``` +7. **Now we are going to delete the app clusters you created for a better demo flow** + - Don't worry - we will demonstrate the use of ArgoCD to re-create these clusters in subsequent steps, as well as rolling out our applications across those clusters! +```bash +## Ensure the mccp cluster is the ingress config controller +gcloud container fleet ingress update --config-membership=mccp-central-01-membership -q + +## Unregister the app clusters from the Fleet +gcloud container fleet memberships delete gke-std-west01-membership --project ${GKE_PROJECT_ID} -q +gcloud container fleet memberships delete gke-std-east01-membership --project ${GKE_PROJECT_ID} -q + +## Delete the app clusters +gcloud container clusters delete gke-std-west01 --region us-west1 --project ${GKE_PROJECT_ID} -q --async +gcloud container clusters delete gke-std-east01 --region us-east1 --project ${GKE_PROJECT_ID} -q --async +``` +## Fleet Cluster setup +So far we have the infrastructure laid out and now need to set up the multi cluster controller cluster with argocd, GKE Fleet components, and some other tooling needed for the demo. + +1. **Hydrate those configs with our project specific variable by running the Fleet prep script** +First you need to create a github PAT token with repo permissions. Here is a link that explains how: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token. + + Take a moment to familiarize yourself with the `fleet_prep.sh` script. It will perform the following steps: + - Reserve a static IP addresses for the ArgoCD UI + - Create Endpoint (i.e. a cloud.goog domain) for ArgoCD, and associate the reserved IP to that Endpoints + - Create Google-Managed SSL certs for the ArgoCD UI + - Create a GKE Ingress for ArgoCD UI referencing the previously created objects + - Create an argocd-fleet-admin Google Service Account + - Reserve a static IP address for the ASM Gatway + - Create Endpoints for applications (rollout-demo and whereami), and associate the reserved IP to those Endpoints + - Create ArgoCD AppProject object + - Generate an ArgoCD initial password, and add mccp-central-01 cluster to ArgoCD + - Hydrate configs and push to GitHub repo + - Specify that repo as being watched by ArgoCD + - Provide required IAM roles / permissions to the ArgoCD Service Account + +```bash +cd ${ROOT_DIR} +# Create a var for your PAT token +PAT_TOKEN="" +# Name for the private github repo that will be created +REPO="" +./scripts/fleet_prep.sh -p ${GKE_PROJECT_ID} -r ${REPO} -t ${PAT_TOKEN} +# Get your temp argocd admin password +kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo +# Login to Argocd +argocd login "argocd.endpoints.${GKE_PROJECT_ID}.cloud.goog" --username admin +# Update your argocd admin password. +argocd account update-password --grpc-web +``` + +## Promoting Application Clusters to the Fleet +Now that we have the multi cluster controller cluster setup, we need to create and promote a GKE cluster to the Fleet that will run applications. Since the multi cluster networking configs have been hydrating, adding a cluster with the env=prod label on the argocd cluster secret will ensure the new cluster syncs all the baseline tooling it needs, including ASM Gateways. We have also labeled this first cluster as a wave one cluster. The wave will be leveraged once apps start getting added. + +1. **Run the application cluster add script** +```bash +./scripts/fleet_cluster_add.sh -p ${GKE_PROJECT_ID} -n gke-ap-west01 -l us-west1 -c "172.16.10.0/28" -t "autopilot" -w one +``` + +2. **Browse to the Argocd UI and you will see that the configs in subfolders in the app-clusters-config folder are installing. This state is all driven by the app clusters tooling application set which targets clusters labeled as prod.** + +## Creating a new app from the app template +One application cluster is ready to serve apps. Now all we need to do is create configs for a new app and push them up to the Argocd sync repo and all the prep we have done will simply allow this app to start serving traffic through the ASM gateway. + +1. **Run the team_app_add script** +```bash +./scripts/team_app_add.sh -a whereami -i "gcr.io/google-samples/whereami:v1.2.6" -p ${GKE_PROJECT_ID} -t team-2 -h "whereami.endpoints.${GKE_PROJECT_ID}.cloud.goog" +``` + +2. **Take a peek at the Argocd UI, filter by the team-2 project for easier location of applications, and you will see that the whereami app is starting to rollout to all application servers labeled as wave-one (there is only one at this point).** + +3. **Once the whereami pods have started navigate to it's endpoint and you will see that you are routed to a pod living in the us-west region. You can also curl the endpoint to the same effect.** +```bash +curl https://whereami.endpoints.${GKE_PROJECT_ID}.cloud.goog/ +# The output should look something like this... +{ + "cluster_name": "gke-std-west02", + "host_header": "whereami.endpoints.argo-spike.cloud.goog", + "pod_name": "whereami-rollout-6d6cb979b5-5xzpj", + "pod_name_emoji": "🇨🇵", + "project_id": "argo-spike", + "timestamp": "2022-08-01T16:16:56", + "zone": "us-west1-b" +} +``` + +## Add another application cluster to the Fleet +Let's get another application cluster added to the Fleet. This time we will deploy the cluster to us-east and label it as a wave two cluster. + +1. **Run the application cluster add script** +```bash +./scripts/fleet_cluster_add.sh -p ${GKE_PROJECT_ID} -n gke-ap-east01 -l us-east1-b -c "172.16.11.0/28" -t "autopilot" -w two +``` + + +2. **Once the whereami pods have started on the us-east cluster, refresh the endpoint webpage or curl it again and you will see that you are routed to a pod living in the region that is closest to you. If you are closer to the west coast and want to see the east coast pod in action you can deploy a GCE instance in the east coast and curl from there or feel free to spin up a curl container in the us-east cluster and curl the endpoint from there.** +```bash +curl https://whereami.endpoints.${GKE_PROJECT_ID}.cloud.goog/ +# The output should look something like this... +{ + "cluster_name": "gke-std-east01", + "host_header": "whereami.endpoints.argo-spike.cloud.goog", + "pod_name": "whereami-rollout-6d6cb979b5-x9h4v", + "pod_name_emoji": "🧍🏽", + "project_id": "argo-spike", + "timestamp": "2022-08-01T16:23:42", + "zone": "us-east1-b" +} +``` + +## Rolling out new version of an app +So far we have added an application cluster to the Fleet and new apps to those clusters. We've not shown off the usage of the wave label just yet, so we will do that now. First we need to create a new app that does a better job showing off Argo rollouts. Then we will progressively release the app to wave one followed by wave two clusters with a manual gate in between. + +1. **Run the team_app_add script** +```bash +./scripts/team_app_add.sh -a rollout-demo -i "argoproj/rollouts-demo:green" -p ${GKE_PROJECT_ID} -t team-1 -h "rollout-demo.endpoints.${GKE_PROJECT_ID}.cloud.goog" +``` + +2. **Release a new image of your app to wave one clusters** +```bash +./scripts/team_app_rollout.sh -a rollout-demo -t team-1 -i "argoproj/rollouts-demo" -l "yellow" -w "one" +``` + +3. **Check the state of your rollout in the argocd UI. You should see a new replicaset and pods being deployed with the new image tag and a progression through the steps of the rollout that generates an analysis templates result after each step. If the analysis does not pass, the rollout will stop and all traffic will be sent to the previous version.** + + +4. **Now that we have progressively release our new image to the first wave of clusters successfully we can move on to releasing the new image to wave two clusters.** +```bash +./scripts/team_app_rollout.sh -a rollout-demo -t team-1 -i "argoproj/rollouts-demo" -l "yellow" -w "two" +``` + +5. **All of the waves have been rolled out successfully and we need to merge the new image into main to conclude the rollout** +```bash +./scripts/team_app_rollout.sh -a rollout-demo -t team-1 -i "argoproj/rollouts-demo" -l "yellow" -w "done" +``` + +## Clean-up +The simplest way to clean up after this demo is to delete the project you used. However, before you can do this you'll need to remove the endpoints we created. +``` +gcloud endpoints services delete argocd.endpoints.${GKE_PROJECT_ID}.cloud.goog --project=${GKE_PROJECT_ID} +gcloud endpoints services delete rollout-demo.endpoints.${GKE_PROJECT_ID}.cloud.goog --project=${GKE_PROJECT_ID} +gcloud endpoints services delete whereami.endpoints.${GKE_PROJECT_ID}.cloud.goog --project=${GKE_PROJECT_ID} +``` + diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/base/argocd-namespace.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/base/argocd-namespace.yaml new file mode 100644 index 0000000..a040f2b --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/base/argocd-namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: argocd diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/base/kustomization.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/base/kustomization.yaml new file mode 100644 index 0000000..76db188 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/base/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: argocd + +resources: +- https://raw.githubusercontent.com/argoproj/argo-cd/v2.4.2/manifests/ha/install.yaml +- argocd-namespace.yaml diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/configmap.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/configmap.yaml new file mode 100644 index 0000000..d985279 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/configmap.yaml @@ -0,0 +1,17 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + namespace: argocd + name: my-cloudsdk-config +data: + config: | + { + "type": "external_account", + "audience": "identitynamespace:xuebinz-gke.svc.id.goog:https://gkehub.googleapis.com/projects/${PROJECT_ID}/locations/global/memberships/${FLEET_MEMBERSHIP_NAME}", + "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/argo-wi-sa@${PROJECT_ID}.iam.gserviceaccount.com:generateAccessToken", + "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", + "token_url": "https://sts.googleapis.com/v1/token", + "credential_source": { + "file": "/var/run/secrets/tokens/gcp-ksa/token" + } + } \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/fleetwi.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/fleetwi.yaml new file mode 100644 index 0000000..42b1e2d --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/fleetwi.yaml @@ -0,0 +1,81 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: argocd-application-controller + namespace: argocd +spec: + template: + spec: + containers: + - command: + - argocd-application-controller + - --status-processors + - "20" + - --operation-processors + - "10" + - --redis + - argocd-redis-ha-haproxy:6379 + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json + name: argocd-application-controller + volumeMounts: + - mountPath: /var/run/secrets/tokens/gcp-ksa + name: gcp-ksa + readOnly: true + volumes: + - name: gcp-ksa + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + audience: ${PROJECT_ID}.svc.id.goog + expirationSeconds: 172800 + path: token + - configMap: + items: + - key: config + path: google-application-credentials.json + name: my-cloudsdk-config + optional: false +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-server + namespace: argocd +spec: + template: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/name: argocd-server + spec: + containers: + - command: + - argocd-server + - --redis + - argocd-redis-ha-haproxy:6379 + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json + name: argocd-server + volumeMounts: + - mountPath: /var/run/secrets/tokens/gcp-ksa + name: gcp-ksa + readOnly: true + volumes: + - name: gcp-ksa + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + audience: ${PROJECT_ID}.svc.id.goog + expirationSeconds: 172800 + path: token + - configMap: + items: + - key: config + path: google-application-credentials.json + name: my-cloudsdk-config + optional: false \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/kustomization.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/kustomization.yaml new file mode 100644 index 0000000..a96df7a --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: argocd + +bases: +- ../../base + +resources: +- configmap.yaml + +patchesStrategicMerge: +- service.yaml +- fleetwi.yaml diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/service.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/service.yaml new file mode 100644 index 0000000..fcf8041 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/anthos/service.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Service +metadata: + name: argocd-server +spec: + type: LoadBalancer \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-managed-cert.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-managed-cert.yaml new file mode 100644 index 0000000..90cf63c --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-managed-cert.yaml @@ -0,0 +1,8 @@ +apiVersion: networking.gke.io/v1 +kind: ManagedCertificate +metadata: + name: argocd-managed-cert + namespace: argocd +spec: + domains: + - "argocd.endpoints.evmos-gcp.cloud.goog" diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-sa.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-sa.yaml new file mode 100644 index 0000000..fcb5e14 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-sa.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + iam.gke.io/gcp-service-account: argocd-fleet-admin@evmos-gcp.iam.gserviceaccount.com + name: argocd-application-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + iam.gke.io/gcp-service-account: argocd-fleet-admin@evmos-gcp.iam.gserviceaccount.com + name: argocd-server diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-backend-config.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-backend-config.yaml new file mode 100644 index 0000000..d2861cb --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-backend-config.yaml @@ -0,0 +1,14 @@ +apiVersion: cloud.google.com/v1 +kind: BackendConfig +metadata: + name: argocd-backend-config + namespace: argocd +spec: + healthCheck: + checkIntervalSec: 30 + timeoutSec: 5 + healthyThreshold: 1 + unhealthyThreshold: 2 + type: HTTP + requestPath: /healthz + port: 8080 \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-deployment_patch.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-deployment_patch.yaml new file mode 100644 index 0000000..2793d08 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-deployment_patch.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-server +spec: + template: + spec: + containers: + - name: argocd-server + command: + - argocd-server + - --redis + - argocd-redis-ha-haproxy:6379 + - --insecure + - --staticassets + - /shared/app \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-frontend-config.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-frontend-config.yaml new file mode 100644 index 0000000..5b0efda --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-frontend-config.yaml @@ -0,0 +1,8 @@ +apiVersion: networking.gke.io/v1beta1 +kind: FrontendConfig +metadata: + name: argocd-frontend-config + namespace: argocd +spec: + redirectToHttps: + enabled: true \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-ingress.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-ingress.yaml new file mode 100644 index 0000000..d3736c9 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-ingress.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: argocd + namespace: argocd + annotations: + kubernetes.io/ingress.global-static-ip-name: argocd-ip + networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config + networking.gke.io/managed-certificates: argocd-managed-cert +spec: + rules: + - host: "argocd.endpoints.evmos-gcp.cloud.goog" + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: argocd-server + port: + number: 80 diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-svc_patch.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-svc_patch.yaml new file mode 100644 index 0000000..a3cca79 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/argocd-server-svc_patch.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: argocd-server + annotations: + cloud.google.com/neg: '{"ingress": true}' + cloud.google.com/backend-config: '{"ports": {"http":"argocd-backend-config"}}' +spec: + type: ClusterIP + ports: + - $patch: delete + name: https + port: 443 + protocol: TCP + targetPort: 8080 \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/kustomization.yaml b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/kustomization.yaml new file mode 100644 index 0000000..f35e9bf --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-cd-gke/overlays/gke_ingress/kustomization.yaml @@ -0,0 +1,17 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: argocd +bases: +- ../../base + +resources: +- argocd-server-backend-config.yaml +- argocd-server-frontend-config.yaml +- argocd-server-ingress.yaml +- argocd-managed-cert.yaml + +patchesStrategicMerge: +- argocd-server-deployment_patch.yaml +- argocd-server-svc_patch.yaml +- argocd-sa.yaml diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/argo-rollouts/argo-rollouts.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/argo-rollouts/argo-rollouts.yaml new file mode 100644 index 0000000..6f81086 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/argo-rollouts/argo-rollouts.yaml @@ -0,0 +1,14709 @@ +# This is an auto-generated file. DO NOT EDIT +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + name: analysisruns.argoproj.io +spec: + group: argoproj.io + names: + kind: AnalysisRun + listKind: AnalysisRunList + plural: analysisruns + shortNames: + - ar + singular: analysisrun + preserveUnknownFields: false + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: AnalysisRun status + jsonPath: .status.phase + name: Status + type: string + - description: Time since resource was created + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + metrics: + items: + properties: + consecutiveErrorLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + failureCondition: + type: string + failureLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + inconclusiveLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + initialDelay: + type: string + interval: + type: string + name: + type: string + provider: + properties: + cloudWatch: + properties: + interval: + type: string + metricDataQueries: + items: + properties: + expression: + type: string + id: + type: string + label: + type: string + metricStat: + properties: + metric: + properties: + dimensions: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + metricName: + type: string + namespace: + type: string + type: object + period: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + stat: + type: string + unit: + type: string + type: object + period: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + returnData: + type: boolean + type: object + type: array + required: + - metricDataQueries + type: object + datadog: + properties: + interval: + type: string + query: + type: string + required: + - query + type: object + graphite: + properties: + address: + type: string + query: + type: string + type: object + job: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + backoffLimit: + format: int32 + type: integer + completionMode: + type: string + completions: + format: int32 + type: integer + manualSelector: + type: boolean + parallelism: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + suspend: + type: boolean + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + maxSkew: + format: int32 + type: integer + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + x-kubernetes-preserve-unknown-fields: true + required: + - containers + type: object + type: object + ttlSecondsAfterFinished: + format: int32 + type: integer + required: + - template + type: object + required: + - spec + type: object + kayenta: + properties: + address: + type: string + application: + type: string + canaryConfigName: + type: string + configurationAccountName: + type: string + metricsAccountName: + type: string + scopes: + items: + properties: + controlScope: + properties: + end: + type: string + region: + type: string + scope: + type: string + start: + type: string + step: + format: int64 + type: integer + required: + - end + - region + - scope + - start + - step + type: object + experimentScope: + properties: + end: + type: string + region: + type: string + scope: + type: string + start: + type: string + step: + format: int64 + type: integer + required: + - end + - region + - scope + - start + - step + type: object + name: + type: string + required: + - controlScope + - experimentScope + - name + type: object + type: array + storageAccountName: + type: string + threshold: + properties: + marginal: + format: int64 + type: integer + pass: + format: int64 + type: integer + required: + - marginal + - pass + type: object + required: + - address + - application + - canaryConfigName + - configurationAccountName + - metricsAccountName + - scopes + - storageAccountName + - threshold + type: object + newRelic: + properties: + profile: + type: string + query: + type: string + required: + - query + type: object + prometheus: + properties: + address: + type: string + query: + type: string + type: object + wavefront: + properties: + address: + type: string + query: + type: string + type: object + web: + properties: + body: + type: string + headers: + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + insecure: + type: boolean + jsonPath: + type: string + method: + type: string + timeoutSeconds: + format: int64 + type: integer + url: + type: string + required: + - url + type: object + type: object + successCondition: + type: string + required: + - name + - provider + type: object + type: array + terminate: + type: boolean + required: + - metrics + type: object + status: + properties: + dryRunSummary: + properties: + count: + format: int32 + type: integer + error: + format: int32 + type: integer + failed: + format: int32 + type: integer + inconclusive: + format: int32 + type: integer + successful: + format: int32 + type: integer + type: object + message: + type: string + metricResults: + items: + properties: + consecutiveError: + format: int32 + type: integer + count: + format: int32 + type: integer + dryRun: + type: boolean + error: + format: int32 + type: integer + failed: + format: int32 + type: integer + inconclusive: + format: int32 + type: integer + measurements: + items: + properties: + finishedAt: + format: date-time + type: string + message: + type: string + metadata: + additionalProperties: + type: string + type: object + phase: + type: string + resumeAt: + format: date-time + type: string + startedAt: + format: date-time + type: string + value: + type: string + required: + - phase + type: object + type: array + message: + type: string + metadata: + additionalProperties: + type: string + type: object + name: + type: string + phase: + type: string + successful: + format: int32 + type: integer + required: + - name + - phase + type: object + type: array + phase: + type: string + runSummary: + properties: + count: + format: int32 + type: integer + error: + format: int32 + type: integer + failed: + format: int32 + type: integer + inconclusive: + format: int32 + type: integer + successful: + format: int32 + type: integer + type: object + startedAt: + format: date-time + type: string + required: + - phase + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + name: analysistemplates.argoproj.io +spec: + group: argoproj.io + names: + kind: AnalysisTemplate + listKind: AnalysisTemplateList + plural: analysistemplates + shortNames: + - at + singular: analysistemplate + preserveUnknownFields: false + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Time since resource was created + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + metrics: + items: + properties: + consecutiveErrorLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + failureCondition: + type: string + failureLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + inconclusiveLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + initialDelay: + type: string + interval: + type: string + name: + type: string + provider: + properties: + cloudWatch: + properties: + interval: + type: string + metricDataQueries: + items: + properties: + expression: + type: string + id: + type: string + label: + type: string + metricStat: + properties: + metric: + properties: + dimensions: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + metricName: + type: string + namespace: + type: string + type: object + period: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + stat: + type: string + unit: + type: string + type: object + period: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + returnData: + type: boolean + type: object + type: array + required: + - metricDataQueries + type: object + datadog: + properties: + interval: + type: string + query: + type: string + required: + - query + type: object + graphite: + properties: + address: + type: string + query: + type: string + type: object + job: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + backoffLimit: + format: int32 + type: integer + completionMode: + type: string + completions: + format: int32 + type: integer + manualSelector: + type: boolean + parallelism: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + suspend: + type: boolean + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + maxSkew: + format: int32 + type: integer + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + x-kubernetes-preserve-unknown-fields: true + required: + - containers + type: object + type: object + ttlSecondsAfterFinished: + format: int32 + type: integer + required: + - template + type: object + required: + - spec + type: object + kayenta: + properties: + address: + type: string + application: + type: string + canaryConfigName: + type: string + configurationAccountName: + type: string + metricsAccountName: + type: string + scopes: + items: + properties: + controlScope: + properties: + end: + type: string + region: + type: string + scope: + type: string + start: + type: string + step: + format: int64 + type: integer + required: + - end + - region + - scope + - start + - step + type: object + experimentScope: + properties: + end: + type: string + region: + type: string + scope: + type: string + start: + type: string + step: + format: int64 + type: integer + required: + - end + - region + - scope + - start + - step + type: object + name: + type: string + required: + - controlScope + - experimentScope + - name + type: object + type: array + storageAccountName: + type: string + threshold: + properties: + marginal: + format: int64 + type: integer + pass: + format: int64 + type: integer + required: + - marginal + - pass + type: object + required: + - address + - application + - canaryConfigName + - configurationAccountName + - metricsAccountName + - scopes + - storageAccountName + - threshold + type: object + newRelic: + properties: + profile: + type: string + query: + type: string + required: + - query + type: object + prometheus: + properties: + address: + type: string + query: + type: string + type: object + wavefront: + properties: + address: + type: string + query: + type: string + type: object + web: + properties: + body: + type: string + headers: + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + insecure: + type: boolean + jsonPath: + type: string + method: + type: string + timeoutSeconds: + format: int64 + type: integer + url: + type: string + required: + - url + type: object + type: object + successCondition: + type: string + required: + - name + - provider + type: object + type: array + required: + - metrics + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + name: clusteranalysistemplates.argoproj.io +spec: + group: argoproj.io + names: + kind: ClusterAnalysisTemplate + listKind: ClusterAnalysisTemplateList + plural: clusteranalysistemplates + shortNames: + - cat + singular: clusteranalysistemplate + preserveUnknownFields: false + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Time since resource was created + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + metrics: + items: + properties: + consecutiveErrorLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + failureCondition: + type: string + failureLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + inconclusiveLimit: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + initialDelay: + type: string + interval: + type: string + name: + type: string + provider: + properties: + cloudWatch: + properties: + interval: + type: string + metricDataQueries: + items: + properties: + expression: + type: string + id: + type: string + label: + type: string + metricStat: + properties: + metric: + properties: + dimensions: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + metricName: + type: string + namespace: + type: string + type: object + period: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + stat: + type: string + unit: + type: string + type: object + period: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + returnData: + type: boolean + type: object + type: array + required: + - metricDataQueries + type: object + datadog: + properties: + interval: + type: string + query: + type: string + required: + - query + type: object + graphite: + properties: + address: + type: string + query: + type: string + type: object + job: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + backoffLimit: + format: int32 + type: integer + completionMode: + type: string + completions: + format: int32 + type: integer + manualSelector: + type: boolean + parallelism: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + suspend: + type: boolean + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + maxSkew: + format: int32 + type: integer + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + x-kubernetes-preserve-unknown-fields: true + required: + - containers + type: object + type: object + ttlSecondsAfterFinished: + format: int32 + type: integer + required: + - template + type: object + required: + - spec + type: object + kayenta: + properties: + address: + type: string + application: + type: string + canaryConfigName: + type: string + configurationAccountName: + type: string + metricsAccountName: + type: string + scopes: + items: + properties: + controlScope: + properties: + end: + type: string + region: + type: string + scope: + type: string + start: + type: string + step: + format: int64 + type: integer + required: + - end + - region + - scope + - start + - step + type: object + experimentScope: + properties: + end: + type: string + region: + type: string + scope: + type: string + start: + type: string + step: + format: int64 + type: integer + required: + - end + - region + - scope + - start + - step + type: object + name: + type: string + required: + - controlScope + - experimentScope + - name + type: object + type: array + storageAccountName: + type: string + threshold: + properties: + marginal: + format: int64 + type: integer + pass: + format: int64 + type: integer + required: + - marginal + - pass + type: object + required: + - address + - application + - canaryConfigName + - configurationAccountName + - metricsAccountName + - scopes + - storageAccountName + - threshold + type: object + newRelic: + properties: + profile: + type: string + query: + type: string + required: + - query + type: object + prometheus: + properties: + address: + type: string + query: + type: string + type: object + wavefront: + properties: + address: + type: string + query: + type: string + type: object + web: + properties: + body: + type: string + headers: + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + insecure: + type: boolean + jsonPath: + type: string + method: + type: string + timeoutSeconds: + format: int64 + type: integer + url: + type: string + required: + - url + type: object + type: object + successCondition: + type: string + required: + - name + - provider + type: object + type: array + required: + - metrics + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + name: experiments.argoproj.io +spec: + group: argoproj.io + names: + kind: Experiment + listKind: ExperimentList + plural: experiments + shortNames: + - exp + singular: experiment + preserveUnknownFields: false + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Experiment status + jsonPath: .status.phase + name: Status + type: string + - description: Time since resource was created + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + analyses: + items: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + required: + - name + type: object + type: array + clusterScope: + type: boolean + name: + type: string + requiredForCompletion: + type: boolean + templateName: + type: string + required: + - name + - templateName + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + duration: + type: string + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + progressDeadlineSeconds: + format: int32 + type: integer + scaleDownDelaySeconds: + format: int32 + type: integer + templates: + items: + properties: + minReadySeconds: + format: int32 + type: integer + name: + type: string + replicas: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + service: + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + maxSkew: + format: int32 + type: integer + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + x-kubernetes-preserve-unknown-fields: true + required: + - containers + type: object + type: object + required: + - name + - selector + - template + type: object + type: array + terminate: + type: boolean + required: + - templates + type: object + status: + properties: + analysisRuns: + items: + properties: + analysisRun: + type: string + message: + type: string + name: + type: string + phase: + type: string + required: + - analysisRun + - name + - phase + type: object + type: array + availableAt: + format: date-time + type: string + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + lastUpdateTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - lastTransitionTime + - lastUpdateTime + - message + - reason + - status + - type + type: object + type: array + message: + type: string + phase: + type: string + templateStatuses: + items: + properties: + availableReplicas: + format: int32 + type: integer + collisionCount: + format: int32 + type: integer + lastTransitionTime: + format: date-time + type: string + message: + type: string + name: + type: string + podTemplateHash: + type: string + readyReplicas: + format: int32 + type: integer + replicas: + format: int32 + type: integer + serviceName: + type: string + status: + type: string + updatedReplicas: + format: int32 + type: integer + required: + - availableReplicas + - name + - readyReplicas + - replicas + - updatedReplicas + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + name: rollouts.argoproj.io +spec: + group: argoproj.io + names: + kind: Rollout + listKind: RolloutList + plural: rollouts + shortNames: + - ro + singular: rollout + preserveUnknownFields: false + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Number of desired pods + jsonPath: .spec.replicas + name: Desired + type: integer + - description: Total number of non-terminated pods targeted by this rollout + jsonPath: .status.replicas + name: Current + type: integer + - description: Total number of non-terminated pods targeted by this rollout that + have the desired template spec + jsonPath: .status.updatedReplicas + name: Up-to-date + type: integer + - description: Total number of available pods (ready for at least minReadySeconds) + targeted by this rollout + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Time since resource was created + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + analysis: + properties: + successfulRunHistoryLimit: + format: int32 + type: integer + unsuccessfulRunHistoryLimit: + format: int32 + type: integer + type: object + minReadySeconds: + format: int32 + type: integer + paused: + type: boolean + progressDeadlineAbort: + type: boolean + progressDeadlineSeconds: + format: int32 + type: integer + replicas: + format: int32 + type: integer + restartAt: + format: date-time + type: string + revisionHistoryLimit: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + strategy: + properties: + blueGreen: + properties: + abortScaleDownDelaySeconds: + format: int32 + type: integer + activeMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + activeService: + type: string + antiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + properties: + weight: + format: int32 + type: integer + required: + - weight + type: object + requiredDuringSchedulingIgnoredDuringExecution: + type: object + type: object + autoPromotionEnabled: + type: boolean + autoPromotionSeconds: + format: int32 + type: integer + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + postPromotionAnalysis: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array + type: object + prePromotionAnalysis: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array + type: object + previewMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + previewReplicaCount: + format: int32 + type: integer + previewService: + type: string + scaleDownDelayRevisionLimit: + format: int32 + type: integer + scaleDownDelaySeconds: + format: int32 + type: integer + required: + - activeService + type: object + canary: + properties: + abortScaleDownDelaySeconds: + format: int32 + type: integer + analysis: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + startingStep: + format: int32 + type: integer + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array + type: object + antiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + properties: + weight: + format: int32 + type: integer + required: + - weight + type: object + requiredDuringSchedulingIgnoredDuringExecution: + type: object + type: object + canaryMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + canaryService: + type: string + dynamicStableScale: + type: boolean + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + pingPong: + properties: + pingService: + type: string + pongService: + type: string + required: + - pingService + - pongService + type: object + scaleDownDelayRevisionLimit: + format: int32 + type: integer + scaleDownDelaySeconds: + format: int32 + type: integer + stableMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + stableService: + type: string + steps: + items: + properties: + analysis: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + dryRun: + items: + properties: + metricName: + type: string + required: + - metricName + type: object + type: array + measurementRetention: + items: + properties: + limit: + format: int32 + type: integer + metricName: + type: string + required: + - limit + - metricName + type: object + type: array + templates: + items: + properties: + clusterScope: + type: boolean + templateName: + type: string + type: object + type: array + type: object + experiment: + properties: + analyses: + items: + properties: + args: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + fieldRef: + properties: + fieldPath: + type: string + required: + - fieldPath + type: object + podTemplateHashValue: + type: string + type: object + required: + - name + type: object + type: array + clusterScope: + type: boolean + name: + type: string + requiredForCompletion: + type: boolean + templateName: + type: string + required: + - name + - templateName + type: object + type: array + duration: + type: string + templates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + replicas: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + specRef: + type: string + weight: + format: int32 + type: integer + required: + - name + - specRef + type: object + type: array + required: + - templates + type: object + pause: + properties: + duration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + setCanaryScale: + properties: + matchTrafficWeight: + type: boolean + replicas: + format: int32 + type: integer + weight: + format: int32 + type: integer + type: object + setWeight: + format: int32 + type: integer + type: object + type: array + trafficRouting: + properties: + alb: + properties: + annotationPrefix: + type: string + ingress: + type: string + rootService: + type: string + servicePort: + format: int32 + type: integer + stickinessConfig: + properties: + durationSeconds: + format: int64 + type: integer + enabled: + type: boolean + required: + - durationSeconds + - enabled + type: object + required: + - ingress + - servicePort + type: object + ambassador: + properties: + mappings: + items: + type: string + type: array + required: + - mappings + type: object + appMesh: + properties: + virtualNodeGroup: + properties: + canaryVirtualNodeRef: + properties: + name: + type: string + required: + - name + type: object + stableVirtualNodeRef: + properties: + name: + type: string + required: + - name + type: object + required: + - canaryVirtualNodeRef + - stableVirtualNodeRef + type: object + virtualService: + properties: + name: + type: string + routes: + items: + type: string + type: array + required: + - name + type: object + type: object + istio: + properties: + destinationRule: + properties: + canarySubsetName: + type: string + name: + type: string + stableSubsetName: + type: string + required: + - canarySubsetName + - name + - stableSubsetName + type: object + virtualService: + properties: + name: + type: string + routes: + items: + type: string + type: array + tlsRoutes: + items: + properties: + port: + format: int64 + type: integer + sniHosts: + items: + type: string + type: array + type: object + type: array + required: + - name + type: object + virtualServices: + items: + properties: + name: + type: string + routes: + items: + type: string + type: array + tlsRoutes: + items: + properties: + port: + format: int64 + type: integer + sniHosts: + items: + type: string + type: array + type: object + type: array + required: + - name + type: object + type: array + type: object + nginx: + properties: + additionalIngressAnnotations: + additionalProperties: + type: string + type: object + annotationPrefix: + type: string + stableIngress: + type: string + required: + - stableIngress + type: object + smi: + properties: + rootService: + type: string + trafficSplitName: + type: string + type: object + type: object + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + x-kubernetes-preserve-unknown-fields: true + requests: + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + maxSkew: + format: int32 + type: integer + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + required: + - containers + type: object + type: object + workloadRef: + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + type: object + type: object + status: + properties: + HPAReplicas: + format: int32 + type: integer + abort: + type: boolean + abortedAt: + format: date-time + type: string + alb: + properties: + canaryTargetGroup: + properties: + arn: + type: string + name: + type: string + required: + - arn + - name + type: object + loadBalancer: + properties: + arn: + type: string + name: + type: string + required: + - arn + - name + type: object + stableTargetGroup: + properties: + arn: + type: string + name: + type: string + required: + - arn + - name + type: object + type: object + availableReplicas: + format: int32 + type: integer + blueGreen: + properties: + activeSelector: + type: string + postPromotionAnalysisRunStatus: + properties: + message: + type: string + name: + type: string + status: + type: string + required: + - name + - status + type: object + prePromotionAnalysisRunStatus: + properties: + message: + type: string + name: + type: string + status: + type: string + required: + - name + - status + type: object + previewSelector: + type: string + scaleUpPreviewCheckPoint: + type: boolean + type: object + canary: + properties: + currentBackgroundAnalysisRunStatus: + properties: + message: + type: string + name: + type: string + status: + type: string + required: + - name + - status + type: object + currentExperiment: + type: string + currentStepAnalysisRunStatus: + properties: + message: + type: string + name: + type: string + status: + type: string + required: + - name + - status + type: object + stablePingPong: + type: string + weights: + properties: + additional: + items: + properties: + podTemplateHash: + type: string + serviceName: + type: string + weight: + format: int32 + type: integer + required: + - weight + type: object + type: array + canary: + properties: + podTemplateHash: + type: string + serviceName: + type: string + weight: + format: int32 + type: integer + required: + - weight + type: object + stable: + properties: + podTemplateHash: + type: string + serviceName: + type: string + weight: + format: int32 + type: integer + required: + - weight + type: object + verified: + type: boolean + required: + - canary + - stable + type: object + type: object + collisionCount: + format: int32 + type: integer + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + lastUpdateTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - lastTransitionTime + - lastUpdateTime + - message + - reason + - status + - type + type: object + type: array + controllerPause: + type: boolean + currentPodHash: + type: string + currentStepHash: + type: string + currentStepIndex: + format: int32 + type: integer + message: + type: string + observedGeneration: + type: string + pauseConditions: + items: + properties: + reason: + type: string + startTime: + format: date-time + type: string + required: + - reason + - startTime + type: object + type: array + phase: + type: string + promoteFull: + type: boolean + readyReplicas: + format: int32 + type: integer + replicas: + format: int32 + type: integer + restartedAt: + format: date-time + type: string + selector: + type: string + stableRS: + type: string + updatedReplicas: + format: int32 + type: integer + workloadObservedGeneration: + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.HPAReplicas + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rollouts-controller + app.kubernetes.io/name: argo-rollouts + app.kubernetes.io/part-of: argo-rollouts + name: argo-rollouts +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: rollouts-controller + app.kubernetes.io/name: argo-rollouts + app.kubernetes.io/part-of: argo-rollouts + name: argo-rollouts +rules: +- apiGroups: + - argoproj.io + resources: + - rollouts + - rollouts/status + - rollouts/finalizers + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - argoproj.io + resources: + - analysisruns + - analysisruns/finalizers + - experiments + - experiments/finalizers + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - argoproj.io + resources: + - analysistemplates + - clusteranalysistemplates + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - replicasets + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + - apps + resources: + - deployments + - podtemplates + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - patch + - create + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - update +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - list + - update +- apiGroups: + - "" + resources: + - pods/eviction + verbs: + - create +- apiGroups: + - "" + resources: + - events + verbs: + - create + - update + - patch +- apiGroups: + - networking.k8s.io + - extensions + resources: + - ingresses + verbs: + - create + - get + - list + - watch + - patch +- apiGroups: + - batch + resources: + - jobs + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - networking.istio.io + resources: + - virtualservices + - destinationrules + verbs: + - watch + - get + - update + - patch + - list +- apiGroups: + - split.smi-spec.io + resources: + - trafficsplits + verbs: + - create + - watch + - get + - update + - patch +- apiGroups: + - getambassador.io + - x.getambassador.io + resources: + - mappings + - ambassadormappings + verbs: + - create + - watch + - get + - update + - list + - delete +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get +- apiGroups: + - elbv2.k8s.aws + resources: + - targetgroupbindings + verbs: + - list + - get +- apiGroups: + - appmesh.k8s.aws + resources: + - virtualservices + verbs: + - watch + - get + - list +- apiGroups: + - appmesh.k8s.aws + resources: + - virtualnodes + - virtualrouters + verbs: + - watch + - get + - list + - update + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: aggregate-cluster-role + app.kubernetes.io/name: argo-rollouts-aggregate-to-admin + app.kubernetes.io/part-of: argo-rollouts + rbac.authorization.k8s.io/aggregate-to-admin: "true" + name: argo-rollouts-aggregate-to-admin +rules: +- apiGroups: + - argoproj.io + resources: + - rollouts + - rollouts/scale + - rollouts/status + - experiments + - analysistemplates + - clusteranalysistemplates + - analysisruns + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: aggregate-cluster-role + app.kubernetes.io/name: argo-rollouts-aggregate-to-edit + app.kubernetes.io/part-of: argo-rollouts + rbac.authorization.k8s.io/aggregate-to-edit: "true" + name: argo-rollouts-aggregate-to-edit +rules: +- apiGroups: + - argoproj.io + resources: + - rollouts + - rollouts/scale + - rollouts/status + - experiments + - analysistemplates + - clusteranalysistemplates + - analysisruns + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: aggregate-cluster-role + app.kubernetes.io/name: argo-rollouts-aggregate-to-view + app.kubernetes.io/part-of: argo-rollouts + rbac.authorization.k8s.io/aggregate-to-view: "true" + name: argo-rollouts-aggregate-to-view +rules: +- apiGroups: + - argoproj.io + resources: + - rollouts + - rollouts/scale + - experiments + - analysistemplates + - clusteranalysistemplates + - analysisruns + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rollouts-controller + app.kubernetes.io/name: argo-rollouts + app.kubernetes.io/part-of: argo-rollouts + name: argo-rollouts +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argo-rollouts +subjects: +- kind: ServiceAccount + name: argo-rollouts + namespace: argo-rollouts +--- +apiVersion: v1 +kind: Secret +metadata: + name: argo-rollouts-notification-secret +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argo-rollouts-metrics + app.kubernetes.io/part-of: argo-rollouts + name: argo-rollouts-metrics +spec: + ports: + - name: metrics + port: 8090 + protocol: TCP + targetPort: 8090 + selector: + app.kubernetes.io/name: argo-rollouts +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: rollouts-controller + app.kubernetes.io/name: argo-rollouts + app.kubernetes.io/part-of: argo-rollouts + name: argo-rollouts +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: argo-rollouts + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: argo-rollouts + spec: + containers: + - image: quay.io/argoproj/argo-rollouts:v1.2.1 + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + periodSeconds: 20 + successThreshold: 1 + timeoutSeconds: 10 + name: argo-rollouts + ports: + - containerPort: 8090 + name: metrics + - containerPort: 8080 + name: healthz + readinessProbe: + failureThreshold: 3 + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 10 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 4 + securityContext: + runAsNonRoot: true + serviceAccountName: argo-rollouts diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-gateways-namespace.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-gateways-namespace.yaml new file mode 100644 index 0000000..7302db6 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-gateways-namespace.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: asm-gateways + labels: + istio.io/rev: asm-managed + annotations: + argocd.argoproj.io/sync-wave: "-1" \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-ingress-gateway.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-ingress-gateway.yaml new file mode 100644 index 0000000..8869301 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-ingress-gateway.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: asm-ingress-gateway-xlb +spec: + selector: + asm: ingressgateway-xlb # use ASM external ingress gateway + servers: + - port: + number: 443 + name: https + protocol: HTTPS + hosts: + - '*' # IMPORTANT: Must use wildcard here when using SSL, see note below + tls: + mode: SIMPLE + credentialName: edge2mesh-credential diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job-rbac.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job-rbac.yaml new file mode 100644 index 0000000..6f172cd --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job-rbac.yaml @@ -0,0 +1,24 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: asm-webhook-wait-job-role +rules: + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: asm-webhook-wait-job-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: asm-webhook-wait-job-role +subjects: + - kind: ServiceAccount + name: asm-webhook-wait-job-sa + namespace: istio-system \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job-sa.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job-sa.yaml new file mode 100644 index 0000000..c5c6779 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job-sa.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: asm-webhook-wait-job-sa + namespace: istio-system \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job.yaml new file mode 100644 index 0000000..d942f23 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/asm-webhook-wait-job.yaml @@ -0,0 +1,37 @@ +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + argocd.argoproj.io/sync-wave: "1" + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: HookSucceeded + name: asm-webhook-wait-job + namespace: istio-system +spec: + template: + spec: + containers: + - image: bitnami/kubectl:1.24.3 + command: + - /bin/bash + - -c + - | + export HOME=/tmp/webhook-test + echo "" + echo -n "Waiting for the ASM MCP webhook to install." + sleep $SLEEP + until kubectl get mutatingwebhookconfigurations istiod-asm-managed + do + echo -n "...still waiting for ASM MCP webhook creation" + sleep $SLEEP + done + echo "DONE" + imagePullPolicy: Always + name: asm-webhook-wait-job + env: + - name: SLEEP + value: "5" + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + serviceAccountName: asm-webhook-wait-job-sa + terminationGracePeriodSeconds: 30 \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/deployment.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/deployment.yaml new file mode 100644 index 0000000..87f1690 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/deployment.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: asm-ingressgateway-xlb + annotations: + argocd.argoproj.io/sync-wave: "1" + argocd.argoproj.io/hook: PostSync + # namespace: asm-gateways +spec: + replicas: 3 + selector: + matchLabels: + asm: ingressgateway-xlb + template: + metadata: + annotations: + # This is required to tell Anthos Service Mesh to inject the gateway with the + # required configuration. + inject.istio.io/templates: gateway + labels: + asm: ingressgateway-xlb + # asm.io/rev: ${ASM_LABEL} # This is required only if the namespace is not labeled. + spec: + containers: + - name: istio-proxy + image: auto # The image will automatically update each time the pod starts. + resources: + limits: + cpu: 2000m + memory: 1024Mi + requests: + cpu: 100m + memory: 128Mi \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/role.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/role.yaml new file mode 100644 index 0000000..94ae849 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/role.yaml @@ -0,0 +1,22 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: asm-ingressgateway-sds + # namespace: asm-gateways +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: asm-ingressgateway-sds + # namespace: asm-gateways +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: asm-ingressgateway-sds +subjects: + - kind: ServiceAccount + name: default diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/service.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/service.yaml new file mode 100644 index 0000000..97e204a --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/asm-gateways/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: asm-ingressgateway-xlb + # namespace: asm-gateways +spec: + type: ClusterIP + selector: + asm: ingressgateway-xlb + ports: + - port: 80 + name: http + - port: 443 + name: https + diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/istio-system/asm.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/istio-system/asm.yaml new file mode 100644 index 0000000..57a0f60 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/istio-system/asm.yaml @@ -0,0 +1,8 @@ +apiVersion: mesh.cloud.google.com/v1alpha1 +kind: ControlPlaneRevision +metadata: + name: asm-managed + namespace: istio-system +spec: + type: managed_service + channel: regular diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/istio-system/istio-system-namespace.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/istio-system/istio-system-namespace.yaml new file mode 100644 index 0000000..05c7cc6 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/istio-system/istio-system-namespace.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: istio-system + annotations: + argocd.argoproj.io/sync-wave: "-1" diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/prod-tools/prom-frontend.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/prod-tools/prom-frontend.yaml new file mode 100644 index 0000000..6626384 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/prod-tools/prom-frontend.yaml @@ -0,0 +1,65 @@ +# Copyright 2021 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 +# +# https:#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. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: prometheus-frontend +spec: + replicas: 2 + selector: + matchLabels: + app: prometheus-frontend + template: + metadata: + labels: + app: prometheus-frontend + spec: + automountServiceAccountToken: true + # nodeSelector: + # kubernetes.io/os: linux + # kubernetes.io/arch: amd64 + containers: + - name: frontend + image: "gke.gcr.io/prometheus-engine/frontend:v0.4.1-gke.0" + args: + - "--web.listen-address=:9090" + - "--query.project-id={{GKE_PROJECT_ID}}" + ports: + - name: web + containerPort: 9090 + readinessProbe: + httpGet: + path: /-/ready + port: web + livenessProbe: + httpGet: + path: /-/healthy + port: web + resources: + requests: + memory: 512Mi + cpu: 250m +--- +apiVersion: v1 +kind: Service +metadata: + name: prometheus-frontend +spec: + clusterIP: None + selector: + app: prometheus-frontend + ports: + - name: web + port: 9090 diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/prod-tools/success-rate-analysis-template.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/prod-tools/success-rate-analysis-template.yaml new file mode 100644 index 0000000..4b7da6e --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-clusters-config/prod-tools/success-rate-analysis-template.yaml @@ -0,0 +1,20 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ClusterAnalysisTemplate +metadata: + name: success-rate +spec: + args: + - name: service-name + metrics: + - name: success-rate + successCondition: len(result) == 0 || result[0] >= 0.95 + provider: + prometheus: + address: "http://prometheus-frontend.prod-tools.svc.cluster.local:9090" + query: | + sum(increase( + istio_io:service_client_request_count{monitored_resource="istio_canonical_service",destination_service_name=~"rollouts-demo-canary",response_code="200"}[3m] + )) / + sum(increase( + istio_io:service_client_request_count{monitored_resource="istio_canonical_service",destination_service_name=~"rollouts-demo-canary"}[3m] + )) \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/kustomization.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/kustomization.yaml new file mode 100644 index 0000000..bbf16db --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- quota.yaml +- rbac.yaml +- service-canary.yaml +- service-stable.yaml diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/quota.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/quota.yaml new file mode 100644 index 0000000..8452081 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/quota.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: quota +spec: + hard: + cpu: "1000" + memory: 100Gi + pods: "100" \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/rbac.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/rbac.yaml new file mode 100644 index 0000000..aa3f12f --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/rbac.yaml @@ -0,0 +1,11 @@ +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: rolebinding +subjects: +- kind: Group + name: "team-name@nickeberts.altostrat.com" +roleRef: + kind: Role + name: edit + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/service-canary.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/service-canary.yaml new file mode 100644 index 0000000..4e3e516 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/service-canary.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: canary +spec: + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: app-name \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/service-stable.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/service-stable.yaml new file mode 100644 index 0000000..6f4eb8b --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/base/service-stable.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: stable +spec: + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: app-name \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/applicationset-wave-1.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/applicationset-wave-1.yaml new file mode 100644 index 0000000..d67c94f --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/applicationset-wave-1.yaml @@ -0,0 +1,45 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: TEAM_NAME-APP_NAME-wave-1-generator +spec: + generators: + - clusters: + selector: + matchLabels: + argocd.argoproj.io/secret-type: cluster + matchExpressions: + - key: wave + operator: In + values: ["one"] + template: + metadata: + name: '{{name}}-TEAM_NAME-APP_NAME' + spec: + project: "TEAM_NAME" + source: + repoURL: {{SYNC_REPO}} + targetRevision: "wave-one" + path: teams/TEAM_NAME/APP_NAME + destination: + server: '{{server}}' # 'server' field of the secret + namespace: APP_NAME + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: true + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + retry: + limit: 20 + backoff: + duration: 5s + factor: 2 + maxDuration: 5m + ignoreDifferences: + - group: networking.istio.io + kind: VirtualService + jsonPointers: + - /spec/http/0 diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/applicationset-wave-2.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/applicationset-wave-2.yaml new file mode 100644 index 0000000..2f7a943 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/applicationset-wave-2.yaml @@ -0,0 +1,45 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: TEAM_NAME-APP_NAME-wave-2-generator +spec: + generators: + - clusters: + selector: + matchLabels: + argocd.argoproj.io/secret-type: cluster + matchExpressions: + - key: wave + operator: In + values: ["two"] + template: + metadata: + name: '{{name}}-TEAM_NAME-APP_NAME' + spec: + project: "TEAM_NAME" + source: + repoURL: {{SYNC_REPO}} + targetRevision: "wave-two" + path: teams/TEAM_NAME/APP_NAME + destination: + server: '{{server}}' # 'server' field of the secret + namespace: APP_NAME + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: true + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + retry: + limit: 20 + backoff: + duration: 5s + factor: 2 + maxDuration: 5m + ignoreDifferences: + - group: networking.istio.io + kind: VirtualService + jsonPointers: + - /spec/http/0 diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/argocd-project.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/argocd-project.yaml new file mode 100644 index 0000000..c5a1ce9 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/argocd-project.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: TEAM_NAME + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + sourceRepos: + - '*' + destinations: + - namespace: '*' + server: '*' + clusterResourceWhitelist: + - group: '*' + kind: '*' \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-central.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-central.yaml new file mode 100644 index 0000000..7145a26 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-central.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: APP_NAME-destrule + namespace: APP_NAME +spec: + host: APP_NAME-stable.APP_NAME.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-central1 + to: us-west1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-east.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-east.yaml new file mode 100644 index 0000000..4d236f7 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-east.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: APP_NAME-destrule + namespace: APP_NAME +spec: + host: APP_NAME-stable.APP_NAME.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-east1 + to: us-central1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-west.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-west.yaml new file mode 100644 index 0000000..d6c55bd --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/destination-rule-west.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: APP_NAME-destrule + namespace: APP_NAME +spec: + host: APP_NAME-stable.APP_NAME.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-west1 + to: us-central1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/kustomization.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/kustomization.yaml new file mode 100644 index 0000000..cfddaed --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/kustomization.yaml @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: APP_NAME +namePrefix: APP_NAME- +resources: +- ../../../app-template/base/ +- rollout.yaml +commonLabels: + app: APP_NAME \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/namespace.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/namespace.yaml new file mode 100644 index 0000000..361c916 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/namespace.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: APP_NAME + labels: + istio.io/rev: asm-managed + annotations: + argocd.argoproj.io/sync-wave: "-1" \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/rollout.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/rollout.yaml new file mode 100644 index 0000000..51be499 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/rollout.yaml @@ -0,0 +1,58 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: rollout +spec: + replicas: 1 + strategy: + canary: + canaryService: APP_NAME-canary + stableService: APP_NAME-stable + trafficRouting: + istio: + virtualServices: + - name: APP_NAME-virtualservice # At least one virtualService is required + routes: + - primary # At least one route is required + steps: + - setWeight: 20 + - pause: + duration: 4m + - analysis: + templates: + - templateName: success-rate + clusterScope: true + args: + - name: service-name + value: APP_NAME-canary.APP_NAME.svc.cluster.local + - setWeight: 80 + - pause: + duration: 4m + - analysis: + templates: + - templateName: success-rate + clusterScope: true + args: + - name: service-name + value: APP_NAME-canary.APP_NAME.svc.cluster.local + revisionHistoryLimit: 2 + selector: + matchLabels: + app: APP_NAME + template: + metadata: + labels: + app: APP_NAME + istio-injection: enabled + spec: + containers: + - name: APP_NAME + image: APP_IMAGE + ports: + - name: http + containerPort: 8080 + protocol: TCP + resources: + requests: + memory: 32Mi + cpu: 5m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/virtual-service.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/virtual-service.yaml new file mode 100644 index 0000000..2274b19 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/app-template/new-app/virtual-service.yaml @@ -0,0 +1,23 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: APP_NAME-virtualservice + namespace: APP_NAME +spec: + gateways: + - asm-gateways/asm-ingress-gateway-xlb + hosts: + - APP_HOST_NAME + http: + - name: primary + route: + - destination: + host: APP_NAME-stable + port: + number: 80 + weight: 100 + - destination: + host: APP_NAME-canary + port: + number: 80 + weight: 0 diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/generators/app-clusters-tooling-applicationset.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/app-clusters-tooling-applicationset.yaml new file mode 100644 index 0000000..cebd6b3 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/app-clusters-tooling-applicationset.yaml @@ -0,0 +1,43 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: app-clusters-config-generator +spec: + generators: + - matrix: + generators: + - git: + repoURL: {{SYNC_REPO}} + revision: HEAD + directories: + - path: app-clusters-config/* + - clusters: + selector: + matchLabels: + env: "prod" + template: + metadata: + name: '{{name}}-{{path.basename}}' + spec: + project: "admin" + source: + repoURL: {{SYNC_REPO}} + targetRevision: HEAD + path: '{{path}}' + destination: + server: '{{server}}' # 'server' field of the secret + namespace: '{{path.basename}}' + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: true + syncOptions: + - CreateNamespace=true + - Validate=false + retry: + limit: 20 + backoff: + duration: 5s + factor: 2 + maxDuration: 5m diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/generators/central-clusters-applicationset.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/central-clusters-applicationset.yaml new file mode 100644 index 0000000..9e3d2d3 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/central-clusters-applicationset.yaml @@ -0,0 +1,34 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: central-clusters-config-generator +spec: + generators: + - clusters: + selector: + matchLabels: + region: "us-central1" + template: + metadata: + name: '{{name}}-configs' + spec: + project: "admin" + source: + repoURL: {{SYNC_REPO}} + targetRevision: HEAD + path: region-clusters-config/us-central-clusters-config + destination: + server: '{{server}}' # 'server' field of the secret + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: true + syncOptions: + - Validate=false + retry: + limit: 20 + backoff: + duration: 5s + factor: 2 + maxDuration: 5m diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/generators/east-clusters-applicationset.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/east-clusters-applicationset.yaml new file mode 100644 index 0000000..23ebea2 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/east-clusters-applicationset.yaml @@ -0,0 +1,34 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: east-clusters-config-generator +spec: + generators: + - clusters: + selector: + matchLabels: + region: "us-east1" + template: + metadata: + name: '{{name}}-configs' + spec: + project: "admin" + source: + repoURL: {{SYNC_REPO}} + targetRevision: HEAD + path: region-clusters-config/us-east-clusters-config + destination: + server: '{{server}}' # 'server' field of the secret + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: true + syncOptions: + - Validate=false + retry: + limit: 20 + backoff: + duration: 5s + factor: 2 + maxDuration: 5m diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/generators/multi-cluster-controller-applicationset.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/multi-cluster-controller-applicationset.yaml new file mode 100644 index 0000000..4c64815 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/multi-cluster-controller-applicationset.yaml @@ -0,0 +1,40 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: mcc-clusters-config-generator + namespace: argocd +spec: + generators: + - matrix: + generators: + - git: + repoURL: {{SYNC_REPO}} + revision: HEAD + directories: + - path: multi-cluster-controllers/* + - clusters: + selector: + matchLabels: + env: "multi-cluster-controller" + template: + metadata: + name: '{{name}}-{{path.basename}}' + spec: + project: "admin" + source: + repoURL: {{SYNC_REPO}} + targetRevision: HEAD + path: '{{path}}' + destination: + server: '{{server}}' # 'server' field of the secret + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: true + retry: + limit: 20 + backoff: + duration: 5s + factor: 2 + maxDuration: 5m diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/generators/west-clusters-applicationset.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/west-clusters-applicationset.yaml new file mode 100644 index 0000000..7700c78 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/generators/west-clusters-applicationset.yaml @@ -0,0 +1,34 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: west-clusters-config-generator +spec: + generators: + - clusters: + selector: + matchLabels: + region: "us-west1" + template: + metadata: + name: '{{name}}-configs' + spec: + project: "admin" + source: + repoURL: {{SYNC_REPO}} + targetRevision: HEAD + path: region-clusters-config/us-west-clusters-config + destination: + server: '{{server}}' # 'server' field of the secret + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: true + syncOptions: + - Validate=false + retry: + limit: 20 + backoff: + duration: 5s + factor: 2 + maxDuration: 5m diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_gatewayclasses.gateway.networking.k8s.io.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_gatewayclasses.gateway.networking.k8s.io.yaml new file mode 100644 index 0000000..cc8d605 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_gatewayclasses.gateway.networking.k8s.io.yaml @@ -0,0 +1,224 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 + creationTimestamp: null + name: gatewayclasses.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + shortNames: + - gc + singular: gatewayclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1alpha2 + schema: + openAPIV3Schema: + description: "GatewayClass describes a class of Gateways available to the + user for creating Gateway resources. \n It is recommended that this resource + be used as a template for Gateways. This means that a Gateway is based on + the state of the GatewayClass at the time it was created and changes to + the GatewayClass or associated parameters are not propagated down to existing + Gateways. This recommendation is intended to limit the blast radius of changes + to GatewayClass or associated parameters. If implementations choose to propagate + GatewayClass changes to existing Gateways, that MUST be clearly documented + by the implementation. \n Whenever one or more Gateways are using a GatewayClass, + implementations MUST add the `gateway-exists-finalizer.gateway.networking.k8s.io` + finalizer on the associated GatewayClass. This ensures that a GatewayClass + associated with a Gateway is not deleted while in use. \n GatewayClass is + a Cluster level resource." + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of GatewayClass. + properties: + controllerName: + description: "ControllerName is the name of the controller that is + managing Gateways of this class. The value of this field MUST be + a domain prefixed path. \n Example: \"example.net/gateway-controller\". + \n This field is not mutable and cannot be empty. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: "ParametersRef is a reference to a resource that contains + the configuration parameters corresponding to the GatewayClass. + This is optional if the controller does not require any additional + configuration. \n ParametersRef can reference a standard Kubernetes + resource, i.e. ConfigMap, or an implementation-specific custom resource. + The resource can be cluster-scoped or namespace-scoped. \n If the + referent cannot be found, the GatewayClass's \"InvalidParameters\" + status condition will be true. \n Support: Custom" + properties: + group: + description: Group is the group of the referent. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace is the namespace of the referent. This + field is required when referring to a Namespace-scoped resource + and MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: Status defines the current state of GatewayClass. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: "Conditions is the current status from the controller + for this GatewayClass. \n Controllers should prefer to publish conditions + using values of GatewayClassConditionType for the type of each Condition." + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_gateways.gateway.networking.k8s.io.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_gateways.gateway.networking.k8s.io.yaml new file mode 100644 index 0000000..353aeea --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_gateways.gateway.networking.k8s.io.yaml @@ -0,0 +1,717 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 + creationTimestamp: null + name: gateways.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gtw + singular: gateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: Gateway represents an instance of a service-traffic handling + infrastructure by binding Listeners to a set of IP addresses. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of Gateway. + properties: + addresses: + description: "Addresses requested for this Gateway. This is optional + and behavior can depend on the implementation. If a value is set + in the spec and the requested address is invalid or unavailable, + the implementation MUST indicate this in the associated entry in + GatewayStatus.Addresses. \n The Addresses field represents a request + for the address(es) on the \"outside of the Gateway\", that traffic + bound for this Gateway will use. This could be the IP address or + hostname of an external load balancer or other networking infrastructure, + or some other address that traffic will be sent to. \n The .listener.hostname + field is used to route traffic that has already arrived at the Gateway + to the correct in-cluster destination. \n If no Addresses are specified, + the implementation MAY schedule the Gateway in an implementation-specific + manner, assigning an appropriate set of Addresses. \n The implementation + MUST bind all Listeners to every GatewayAddress that it assigns + to the Gateway and add a corresponding entry in GatewayStatus.Addresses. + \n Support: Core" + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + properties: + type: + default: IPAddress + description: Type of the address. + enum: + - IPAddress + - Hostname + - NamedAddress + type: string + value: + description: "Value of the address. The validity of the values + will depend on the type and support by the controller. \n + Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + maxItems: 16 + type: array + gatewayClassName: + description: GatewayClassName used for this Gateway. This is the name + of a GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + listeners: + description: "Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. At + least one Listener MUST be specified. \n Each listener in a Gateway + must have a unique combination of Hostname, Port, and Protocol. + \n An implementation MAY group Listeners by Port and then collapse + each group of Listeners into a single Listener if the implementation + determines that the Listeners in the group are \"compatible\". An + implementation MAY also group together and collapse compatible Listeners + belonging to different Gateways. \n For example, an implementation + might consider Listeners to be compatible with each other if all + of the following conditions are met: \n 1. Either each Listener + within the group specifies the \"HTTP\" Protocol or each Listener + within the group specifies either the \"HTTPS\" or \"TLS\" Protocol. + \n 2. Each Listener within the group specifies a Hostname that is + unique within the group. \n 3. As a special case, one Listener + within a group may omit Hostname, in which case this Listener + matches when no other Listener matches. \n If the implementation + does collapse compatible Listeners, the hostname provided in the + incoming client request MUST be matched to a Listener to find the + correct set of Routes. The incoming hostname MUST be matched using + the Hostname field for each Listener in order of most to least specific. + That is, exact matches must be processed before wildcard matches. + \n If this field specifies multiple Listeners that have the same + Port value but are not compatible, the implementation must raise + a \"Conflicted\" condition in the Listener status. \n Support: Core" + items: + description: Listener embodies the concept of a logical endpoint + where a Gateway accepts network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: "AllowedRoutes defines the types of routes that + MAY be attached to a Listener and the trusted namespaces where + those Route resources MAY be present. \n Although a client + request may match multiple route rules, only one rule may + ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: \n * The most + specific match as defined by the Route type. * The oldest + Route based on creation timestamp. For example, a Route with + \ a creation timestamp of \"2020-09-08 01:02:03\" is given + precedence over a Route with a creation timestamp of \"2020-09-08 + 01:02:04\". * If everything else is equivalent, the Route + appearing first in alphabetical order (namespace/name) should + be given precedence. For example, foo/bar is given precedence + over foo/baz. \n All valid rules within a Route attached to + this Listener should be implemented. Invalid Route rules can + be ignored (sometimes that will mean the full Route). If a + Route rule transitions from valid to invalid, support for + that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, + the rest of the rules within that Route should still be supported. + \n Support: Core" + properties: + kinds: + description: "Kinds specifies the groups and kinds of Routes + that are allowed to bind to this Gateway Listener. When + unspecified or empty, the kinds of Routes selected are + determined using the Listener protocol. \n A RouteGroupKind + MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's + Protocol field. If an implementation does not support + or recognize this resource type, it MUST set the \"ResolvedRefs\" + condition to False for this Listener with the \"InvalidRoutesRef\" + reason. \n Support: Core" + items: + description: RouteGroupKind indicates the group and kind + of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: "Namespaces indicates namespaces from which + Routes may be attached to this Listener. This is restricted + to the namespace of this Gateway by default. \n Support: + Core" + properties: + from: + default: Same + description: "From indicates where Routes will be selected + for this Gateway. Possible values are: * All: Routes + in all namespaces may be used by this Gateway. * Selector: + Routes in namespaces selected by the selector may + be used by this Gateway. * Same: Only Routes in + the same namespace may be used by this Gateway. \n + Support: Core" + enum: + - All + - Selector + - Same + type: string + selector: + description: "Selector must be specified when From is + set to \"Selector\". In that case, only Routes in + Namespaces matching this Selector will be selected + by this Gateway. This field is ignored for other values + of \"From\". \n Support: Core" + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + type: object + type: object + hostname: + description: "Hostname specifies the virtual hostname to match + for protocol types that define this concept. When unspecified, + all hostnames are matched. This field is ignored for protocols + that don't require hostname based matching. \n Implementations + MUST apply Hostname matching appropriately for each of the + following protocols: \n * TLS: The Listener Hostname MUST + match the SNI. * HTTP: The Listener Hostname MUST match the + Host header of the request. * HTTPS: The Listener Hostname + SHOULD match at both the TLS and HTTP protocol layers as + described above. If an implementation does not ensure that + both the SNI and Host header match the Listener hostname, + \ it MUST clearly document that. \n For HTTPRoute and TLSRoute + resources, there is an interaction with the `spec.hostnames` + array. When both listener and route specify hostnames, there + MUST be an intersection between the values for a Route to + be accepted. For more information, refer to the Route specific + Hostnames documentation. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + name: + description: "Name is the name of the Listener. \n Support: + Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + port: + description: "Port is the network port. Multiple listeners may + use the same port, subject to the Listener compatibility rules. + \n Support: Core" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: "Protocol specifies the network protocol this listener + expects to receive. \n Support: Core" + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ + type: string + tls: + description: "TLS is the TLS configuration for the Listener. + This field is required if the Protocol field is \"HTTPS\" + or \"TLS\". It is invalid to set this field if the Protocol + field is \"HTTP\", \"TCP\", or \"UDP\". \n The association + of SNIs to Certificate defined in GatewayTLSConfig is defined + based on the Hostname field for this listener. \n The GatewayClass + MUST use the longest matching SNI out of all available certificates + for any TLS handshake. \n Support: Core" + properties: + certificateRefs: + description: "CertificateRefs contains a series of references + to Kubernetes objects that contains TLS certificates and + private keys. These certificates are used to establish + a TLS handshake for requests that match the hostname of + the associated listener. \n A single CertificateRef to + a Kubernetes Secret has \"Core\" support. Implementations + MAY choose to support attaching multiple certificates + to a Listener, but this behavior is implementation-specific. + \n References to a resource in different namespace are + invalid UNLESS there is a ReferencePolicy in the target + namespace that allows the certificate to be attached. + If a ReferencePolicy does not allow this reference, the + \"ResolvedRefs\" condition MUST be set to False for this + listener with the \"InvalidCertificateRef\" reason. \n + This field is required to have at least one element when + the mode is set to \"Terminate\" (default) and is optional + otherwise. \n CertificateRefs can reference to standard + Kubernetes resources, i.e. Secret, or implementation-specific + custom resources. \n Support: Core - A single reference + to a Kubernetes Secret \n Support: Implementation-specific + (More than one reference or other resource types)" + items: + description: "SecretObjectReference identifies an API + object including its namespace, defaulting to Secret. + \n The API object must be valid in the cluster; the + Group and Kind must be registered in the cluster for + this reference to be valid. \n References to objects + with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate + Conditions set on the containing object." + properties: + group: + default: "" + description: Group is the group of the referent. For + example, "networking.k8s.io". When unspecified (empty + string), core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Secret + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. + \n Note that when a namespace is specified, a ReferencePolicy + object is required in the referent namespace to + allow that namespace's owner to accept the reference. + See the ReferencePolicy documentation for details. + \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + maxItems: 64 + type: array + mode: + default: Terminate + description: "Mode defines the TLS behavior for the TLS + session initiated by the client. There are two possible + modes: \n - Terminate: The TLS session between the downstream + client and the Gateway is terminated at the Gateway. + This mode requires certificateRefs to be set and contain + at least one element. - Passthrough: The TLS session is + NOT terminated by the Gateway. This implies that the + Gateway can't decipher the TLS stream except for the + ClientHello message of the TLS protocol. CertificateRefs + field is ignored in this mode. \n Support: Core" + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: AnnotationValue is the value of an annotation + in Gateway API. This is used for validation of maps + such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation + in that case is based on the entire size of the annotations + struct. + maxLength: 4096 + minLength: 0 + type: string + description: "Options are a list of key/value pairs to enable + extended TLS configuration for each implementation. For + example, configuring the minimum TLS version or supported + cipher suites. \n A set of common keys MAY be defined + by the API in the future. To avoid any ambiguity, implementation-specific + definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by + Gateway API. \n Support: Implementation-specific" + maxProperties: 16 + type: object + type: object + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: NotReconciled + status: Unknown + type: Scheduled + description: Status defines the current state of Gateway. + properties: + addresses: + description: Addresses lists the IP addresses that have actually been + bound to the Gateway. These addresses may differ from the addresses + in the Spec, e.g. if the Gateway automatically assigns an address + from a reserved pool. + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + properties: + type: + default: IPAddress + description: Type of the address. + enum: + - IPAddress + - Hostname + - NamedAddress + type: string + value: + description: "Value of the address. The validity of the values + will depend on the type and support by the controller. \n + Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: NotReconciled + status: Unknown + type: Scheduled + description: "Conditions describe the current conditions of the Gateway. + \n Implementations should prefer to express Gateway conditions using + the `GatewayConditionType` and `GatewayConditionReason` constants + so that operators and tools can converge on a common vocabulary + to describe Gateway state. \n Known condition types are: \n * \"Scheduled\" + * \"Ready\"" + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port + defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: AttachedRoutes represents the total number of Routes + that have been successfully attached to this Listener. + format: int32 + type: integer + conditions: + description: Conditions describe the current condition of this + listener. + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should + be when the underlying condition changed. If that is + not known, then using the time when the API field changed + is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, + if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the + current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier + indicating the reason for the condition's last transition. + Producers of specific condition types may define expected + values and meanings for this field, and whether the + values are considered a guaranteed API. The value should + be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across + resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability + to deconflict is important. The regex it matches is + (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status + corresponds to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + supportedKinds: + description: "SupportedKinds is the list indicating the Kinds + supported by this listener. This MUST represent the kinds + an implementation supports for that Listener configuration. + \n If kinds are specified in Spec that are not supported, + they MUST NOT appear in this list and an implementation MUST + set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" + reason. If both valid and invalid Route kinds are specified, + the implementation MUST reference the valid Route kinds that + have been specified." + items: + description: RouteGroupKind indicates the group and kind of + a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_httproutes.gateway.networking.k8s.io.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_httproutes.gateway.networking.k8s.io.yaml new file mode 100644 index 0000000..7cf93a9 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_httproutes.gateway.networking.k8s.io.yaml @@ -0,0 +1,1282 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 + creationTimestamp: null + name: httproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: HTTPRoute + listKind: HTTPRouteList + plural: httproutes + singular: httproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: HTTPRoute provides a way to route HTTP requests. This includes + the capability to match requests by hostname, path, header, or query param. + Filters can be used to specify additional processing steps. Backends specify + where matching requests should be routed. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of HTTPRoute. + properties: + hostnames: + description: "Hostnames defines a set of hostname that should match + against the HTTP Host header to select a HTTPRoute to process the + request. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may + be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n If a hostname is specified + by both the Listener and HTTPRoute, there must be at least one intersecting + hostname for the HTTPRoute to be attached to the Listener. For example: + \n * A Listener with `test.example.com` as the hostname matches + HTTPRoutes that have either not specified any hostnames, or have + specified at least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + \ that have either not specified any hostnames or have specified + at least one hostname that matches the Listener hostname. For + example, `test.example.com` and `*.example.com` would both match. + On the other hand, `example.com` and `test.example.net` would + not match. \n If both the Listener and HTTPRoute have specified + hostnames, any HTTPRoute hostnames that do not match the Listener + hostname MUST be ignored. For example, if a Listener specified `*.example.com`, + and the HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. \n If both + the Listener and HTTPRoute have specified hostnames, and none match + with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status + of `False` in the corresponding RouteParentStatus. \n Support: Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged." + items: + description: "ParentRef identifies an API object (usually a Gateway) + that can be considered a parent of this resource (usually a route). + The only kind of parent resource with \"Core\" support is Gateway. + This API may be extended in the future to support additional kinds + of parent resources, such as HTTPRoute. \n The API object must + be valid in the cluster; the Group and Kind must be registered + in the cluster for this reference to be valid. \n References to + objects with invalid Group and Kind are not valid, and must be + rejected by the implementation, with appropriate Conditions set + on the containing object." + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified (or empty string), this refers to the local namespace + of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name + \n Implementations MAY choose to support attaching Routes + to other resources. If that is the case, they MUST clearly + document how SectionName is interpreted. \n When unspecified + (empty string), this will reference the entire resource. For + the purpose of status, an attachment is considered successful + if at least one section in the parent resource accepts it. + For example, Gateway listeners can restrict which Routes can + attach to them by Route kind, namespace, or hostname. If 1 + of 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. \n + Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: HTTPRouteRule defines semantics for matching an HTTP + request based on conditions (matches), processing it (filters), + and forwarding the request to an API object (backendRefs). + properties: + backendRefs: + description: "If unspecified or invalid (refers to a non-existent + resource or a Service with no endpoints), the rule performs + no forwarding. If there are also no filters specified that + would result in a response being sent, a HTTP 503 status code + is returned. 503 responses must be sent so that the overall + weight is respected; if an invalid backend is requested to + have 80% of requests, then 80% of requests must get a 503 + instead. \n Support: Core for Kubernetes Service Support: + Custom for any other resource \n Support for weight: Core" + items: + description: HTTPBackendRef defines how a HTTPRoute should + forward an HTTP request. + properties: + filters: + description: "Filters defined at this level should be + executed if and only if the request is being forwarded + to the backend defined here. \n Support: Custom (For + broader support of filters, use the Filters field in + HTTPRouteRule.)" + items: + description: HTTPRouteFilter defines processing steps + that must be completed during the request or response + lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway + implementations. Some examples include request or + response modification, implementing authentication + strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type + of the filter. + properties: + extensionRef: + description: "ExtensionRef is an optional, implementation-specific + extension to the \"filter\" behavior. For example, + resource \"myroutefilter\" in group \"networking.example.net\"). + ExtensionRef MUST NOT be used for core and extended + filters. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. + For example, "networking.k8s.io". When unspecified + (empty string), core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema + for a filter that modifies request headers. \n + Support: Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo + HTTP/1.1 my-header: foo \n Config: add: + \ - name: \"my-header\" value: \"bar\" + \n Output: GET /foo HTTP/1.1 my-header: + foo my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: + foo my-header2: bar my-header3: baz \n + Config: remove: [\"my-header1\", \"my-header3\"] + \n Output: GET /foo HTTP/1.1 my-header2: + bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + \ value: \"bar\" \n Output: GET /foo + HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: "RequestMirror defines a schema for + a filter that mirrors requests. Requests are sent + to the specified destination, but responses from + that destination are ignored. \n Support: Extended" + properties: + backendRef: + description: "BackendRef references a resource + where mirrored requests are sent. \n If the + referent cannot be found, this BackendRef + is invalid and must be dropped from the Gateway. + The controller must ensure the \"ResolvedRefs\" + condition on the Route status is set to `status: + False` and not configure this backend in the + underlying implementation. \n If there is + a cross-namespace reference to an *existing* + object that is not allowed by a ReferencePolicy, + the controller must ensure the \"ResolvedRefs\" + \ condition on the Route is set to `status: + False`, with the \"RefNotPermitted\" reason + and not configure this backend in the underlying + implementation. \n In either error case, the + Message of the `ResolvedRefs` Condition should + be used to provide more detail about the problem. + \n Support: Extended for Kubernetes Service + Support: Custom for any other resource" + properties: + group: + default: "" + description: Group is the group of the referent. + For example, "networking.k8s.io". When + unspecified (empty string), core API group + is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: Kind is kind of the referent. + For example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace + of the backend. When unspecified, the + local namespace is inferred. \n Note that + when a namespace is specified, a ReferencePolicy + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferencePolicy + documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination + port number to use for this resource. + Port is required when the referent is + a Kubernetes Service. For other resources, + destination port might be derived from + the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + required: + - backendRef + type: object + requestRedirect: + description: "RequestRedirect defines a schema for + a filter that responds to the request with an + HTTP redirection. \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be + used in the value of the `Location` header + in the response. When empty, the hostname + of the request is used. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + port: + description: "Port is the port to be used in + the value of the `Location` header in the + response. When empty, port (if specified) + of the request is used. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used + in the value of the `Location` header in the + response. When empty, the scheme of the request + is used. \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status + code to be used in response. \n Support: Core" + enum: + - 301 + - 302 + type: integer + type: object + type: + description: "Type identifies the type of filter + to apply. As with other API fields, types are + classified into three conformance levels: \n - + Core: Filter types and their corresponding configuration + defined by \"Support: Core\" in this package, + e.g. \"RequestHeaderModifier\". All implementations + must support core filters. \n - Extended: Filter + types and their corresponding configuration defined + by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged + to support extended filters. \n - Custom: Filters + that are defined and supported by specific vendors. + \ In the future, filters showing convergence + in behavior across multiple implementations + will be considered for inclusion in extended or + core conformance levels. Filter-specific configuration + for such filters is specified using the ExtensionRef + field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged + to define custom implementation types to extend + the core API with implementation-specific behavior. + \n If a reference to a custom filter type cannot + be resolved, the filter MUST NOT be skipped. Instead, + requests that would have been processed by that + filter MUST receive a HTTP error response." + enum: + - RequestHeaderModifier + - RequestMirror + - RequestRedirect + - ExtensionRef + type: string + required: + - type + type: object + maxItems: 16 + type: array + group: + default: "" + description: Group is the group of the referent. For example, + "networking.k8s.io". When unspecified (empty string), + core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace is specified, a ReferencePolicy + object is required in the referent namespace to allow + that namespace's owner to accept the reference. See + the ReferencePolicy documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. For other resources, + destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + maxItems: 16 + type: array + filters: + description: "Filters define the filters that are applied to + requests that match this rule. \n The effects of ordering + of multiple behaviors are currently unspecified. This can + change in the future based on feedback during the alpha stage. + \n Conformance-levels at this level are defined based on the + type of filter: \n - ALL core filters MUST be supported by + all implementations. - Implementers are encouraged to support + extended filters. - Implementation-specific custom filters + have no API guarantees across implementations. \n Specifying + a core filter multiple times has unspecified or custom conformance. + \n Support: Core" + items: + description: HTTPRouteFilter defines processing steps that + must be completed during the request or response lifecycle. + HTTPRouteFilters are meant as an extension point to express + processing that may be done in Gateway implementations. + Some examples include request or response modification, + implementing authentication strategies, rate-limiting, and + traffic shaping. API guarantee/conformance is defined based + on the type of the filter. + properties: + extensionRef: + description: "ExtensionRef is an optional, implementation-specific + extension to the \"filter\" behavior. For example, + resource \"myroutefilter\" in group \"networking.example.net\"). + ExtensionRef MUST NOT be used for core and extended + filters. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. For + example, "networking.k8s.io". When unspecified (empty + string), core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema for + a filter that modifies request headers. \n Support: + Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: add: - name: \"my-header\" value: + \"bar\" \n Output: GET /foo HTTP/1.1 my-header: + foo my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + \ my-header2: bar my-header3: baz \n Config: + \ remove: [\"my-header1\", \"my-header3\"] \n Output: + \ GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + \ set: - name: \"my-header\" value: \"bar\" + \n Output: GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: "RequestMirror defines a schema for a filter + that mirrors requests. Requests are sent to the specified + destination, but responses from that destination are + ignored. \n Support: Extended" + properties: + backendRef: + description: "BackendRef references a resource where + mirrored requests are sent. \n If the referent cannot + be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure + the \"ResolvedRefs\" condition on the Route status + is set to `status: False` and not configure this + backend in the underlying implementation. \n If + there is a cross-namespace reference to an *existing* + object that is not allowed by a ReferencePolicy, + the controller must ensure the \"ResolvedRefs\" + \ condition on the Route is set to `status: False`, + with the \"RefNotPermitted\" reason and not configure + this backend in the underlying implementation. \n + In either error case, the Message of the `ResolvedRefs` + Condition should be used to provide more detail + about the problem. \n Support: Extended for Kubernetes + Service Support: Custom for any other resource" + properties: + group: + default: "" + description: Group is the group of the referent. + For example, "networking.k8s.io". When unspecified + (empty string), core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the + backend. When unspecified, the local namespace + is inferred. \n Note that when a namespace is + specified, a ReferencePolicy object is required + in the referent namespace to allow that namespace's + owner to accept the reference. See the ReferencePolicy + documentation for details. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port + number to use for this resource. Port is required + when the referent is a Kubernetes Service. For + other resources, destination port might be derived + from the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + required: + - backendRef + type: object + requestRedirect: + description: "RequestRedirect defines a schema for a filter + that responds to the request with an HTTP redirection. + \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be used + in the value of the `Location` header in the response. + When empty, the hostname of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + port: + description: "Port is the port to be used in the value + of the `Location` header in the response. When empty, + port (if specified) of the request is used. \n Support: + Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used in the + value of the `Location` header in the response. + When empty, the scheme of the request is used. \n + Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status code to + be used in response. \n Support: Core" + enum: + - 301 + - 302 + type: integer + type: object + type: + description: "Type identifies the type of filter to apply. + As with other API fields, types are classified into + three conformance levels: \n - Core: Filter types and + their corresponding configuration defined by \"Support: + Core\" in this package, e.g. \"RequestHeaderModifier\". + All implementations must support core filters. \n + - Extended: Filter types and their corresponding configuration + defined by \"Support: Extended\" in this package, + e.g. \"RequestMirror\". Implementers are encouraged + to support extended filters. \n - Custom: Filters that + are defined and supported by specific vendors. In + the future, filters showing convergence in behavior + across multiple implementations will be considered + for inclusion in extended or core conformance levels. + Filter-specific configuration for such filters is + specified using the ExtensionRef field. `Type` should + be set to \"ExtensionRef\" for custom filters. \n + Implementers are encouraged to define custom implementation + types to extend the core API with implementation-specific + behavior. \n If a reference to a custom filter type + cannot be resolved, the filter MUST NOT be skipped. + Instead, requests that would have been processed by + that filter MUST receive a HTTP error response." + enum: + - RequestHeaderModifier + - RequestMirror + - RequestRedirect + - ExtensionRef + type: string + required: + - type + type: object + maxItems: 16 + type: array + matches: + default: + - path: + type: PathPrefix + value: / + description: "Matches define conditions used for matching the + rule against incoming HTTP requests. Each match is independent, + i.e. this rule will be matched if **any** one of the matches + is satisfied. \n For example, take the following matches configuration: + \n ``` matches: - path: value: \"/foo\" headers: - + name: \"version\" value: \"v2\" - path: value: \"/v2/foo\" + ``` \n For a request to match against this rule, a request + must satisfy EITHER of the two conditions: \n - path prefixed + with `/foo` AND contains the header `version: v2` - path prefix + of `/v2/foo` \n See the documentation for HTTPRouteMatch on + how to specify multiple match conditions that should be ANDed + together. \n If no matches are specified, the default is a + prefix path match on \"/\", which has the effect of matching + every HTTP request. \n Proxy or Load Balancer routing configuration + generated from HTTPRoutes MUST prioritize rules based on the + following criteria, continuing on ties. Precedence must be + given to the the Rule with the largest number of: \n * Characters + in a matching non-wildcard hostname. * Characters in a matching + hostname. * Characters in a matching path. * Header matches. + * Query param matches. \n If ties still exist across multiple + Routes, matching precedence MUST be determined in order of + the following criteria, continuing on ties: \n * The oldest + Route based on creation timestamp. * The Route appearing first + in alphabetical order by \"/\". \n If ties + still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching + rule meeting the above criteria." + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given action. Multiple match types are + ANDed together, i.e. the match will evaluate to true only + if all conditions are satisfied. \n For example, the match + below will match a HTTP request only if its path starts + with `/foo` AND it contains the `version: v1` header: \n + ``` match: path: value: \"/foo\" headers: - name: + \"version\" value \"v1\" ```" + properties: + headers: + description: Headers specifies HTTP request header matchers. + Multiple match values are ANDed together, meaning, a + request must match all the specified headers to select + the route. + items: + description: HTTPHeaderMatch describes how to select + a HTTP route by matching HTTP request headers. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case insensitive. + (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent header + names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be + ignored. Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered equivalent. + \n When a header is repeated in an HTTP request, + it is implementation-specific behavior as to how + this is represented. Generally, proxies should + follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 + regarding processing a repeated header, with special + handling for \"Set-Cookie\"." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the header. \n Support: Core (Exact) + \n Support: Custom (RegularExpression) \n Since + RegularExpression HeaderMatchType has custom conformance, + implementations can support POSIX, PCRE or any + other dialects of regular expressions. Please + read the implementation's documentation to determine + the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: "Method specifies HTTP method matcher. When + specified, this route will be matched only if the request + has the specified method. \n Support: Extended" + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: Path specifies a HTTP request path matcher. + If this field is not specified, a default prefix match + on the "/" path is provided. + properties: + type: + default: PathPrefix + description: "Type specifies how to match against + the path Value. \n Support: Core (Exact, PathPrefix) + \n Support: Custom (RegularExpression)" + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + queryParams: + description: QueryParams specifies HTTP query parameter + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified query + parameters to select the route. + items: + description: HTTPQueryParamMatch describes how to select + a HTTP route by matching HTTP query parameters. + properties: + name: + description: Name is the name of the HTTP query + param to be matched. This must be an exact string + match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). + maxLength: 256 + minLength: 1 + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the query parameter. \n Support: + Extended (Exact) \n Support: Custom (RegularExpression) + \n Since RegularExpression QueryParamMatchType + has custom conformance, implementations can support + POSIX, PCRE or any other dialects of regular expressions. + Please read the implementation's documentation + to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should + be when the underlying condition changed. If that is + not known, then using the time when the API field changed + is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, + if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the + current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier + indicating the reason for the condition's last transition. + Producers of specific condition types may define expected + values and meanings for this field, and whether the + values are considered a guaranteed API. The value should + be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across + resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability + to deconflict is important. The regex it matches is + (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified (or empty string), this refers to the + local namespace of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name \n Implementations MAY choose to support attaching + Routes to other resources. If that is the case, they MUST + clearly document how SectionName is interpreted. \n When + unspecified (empty string), this will reference the entire + resource. For the purpose of status, an attachment is + considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can + restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept + attachment from the referencing Route, the Route MUST + be considered successfully attached. If no Gateway listeners + accept attachment from this Route, the Route MUST be considered + detached from the Gateway. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_referencepolicies.gateway.networking.k8s.io.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_referencepolicies.gateway.networking.k8s.io.yaml new file mode 100644 index 0000000..bed5b6b --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_referencepolicies.gateway.networking.k8s.io.yaml @@ -0,0 +1,143 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 + creationTimestamp: null + name: referencepolicies.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: ReferencePolicy + listKind: ReferencePolicyList + plural: referencepolicies + shortNames: + - refpol + singular: referencepolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: "ReferencePolicy identifies kinds of resources in other namespaces + that are trusted to reference the specified kinds of resources in the same + namespace as the policy. \n Each ReferencePolicy can be used to represent + a unique trust relationship. Additional Reference Policies can be used to + add to the set of trusted sources of inbound references for the namespace + they are defined within. \n All cross-namespace references in Gateway API + (with the exception of cross-namespace Gateway-route attachment) require + a ReferencePolicy. \n Support: Core" + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of ReferencePolicy. + properties: + from: + description: "From describes the trusted namespaces and kinds that + can reference the resources described in \"To\". Each entry in this + list must be considered to be an additional place that references + can be valid from, or to put this another way, entries must be combined + using OR. \n Support: Core" + items: + description: ReferencePolicyFrom describes trusted namespaces and + kinds. + properties: + group: + description: "Group is the group of the referent. When empty, + the Kubernetes core API group is inferred. \n Support: Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: "Kind is the kind of the referent. Although implementations + may support additional resources, the following Route types + are part of the \"Core\" support level for this field: \n + * HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + namespace: + description: "Namespace is the namespace of the referent. \n + Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + minItems: 1 + type: array + to: + description: "To describes the resources that may be referenced by + the resources described in \"From\". Each entry in this list must + be considered to be an additional place that references can be valid + to, or to put this another way, entries must be combined using OR. + \n Support: Core" + items: + description: ReferencePolicyTo describes what Kinds are allowed + as targets of the references. + properties: + group: + description: "Group is the group of the referent. When empty, + the Kubernetes core API group is inferred. \n Support: Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: "Kind is the kind of the referent. Although implementations + may support additional resources, the following types are + part of the \"Core\" support level for this field: \n * Service" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. When unspecified + or empty, this policy refers to all resources of the specified + Group and Kind in the local namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_tcproutes.gateway.networking.k8s.io.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_tcproutes.gateway.networking.k8s.io.yaml new file mode 100644 index 0000000..2107589 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_tcproutes.gateway.networking.k8s.io.yaml @@ -0,0 +1,429 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 + creationTimestamp: null + name: tcproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: TCPRoute + listKind: TCPRouteList + plural: tcproutes + singular: tcproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: TCPRoute provides a way to route TCP requests. When combined + with a Gateway listener, it can be used to forward connections on the port + specified by the listener to a set of backends specified by the TCPRoute. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of TCPRoute. + properties: + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged." + items: + description: "ParentRef identifies an API object (usually a Gateway) + that can be considered a parent of this resource (usually a route). + The only kind of parent resource with \"Core\" support is Gateway. + This API may be extended in the future to support additional kinds + of parent resources, such as HTTPRoute. \n The API object must + be valid in the cluster; the Group and Kind must be registered + in the cluster for this reference to be valid. \n References to + objects with invalid Group and Kind are not valid, and must be + rejected by the implementation, with appropriate Conditions set + on the containing object." + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified (or empty string), this refers to the local namespace + of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name + \n Implementations MAY choose to support attaching Routes + to other resources. If that is the case, they MUST clearly + document how SectionName is interpreted. \n When unspecified + (empty string), this will reference the entire resource. For + the purpose of status, an attachment is considered successful + if at least one section in the parent resource accepts it. + For example, Gateway listeners can restrict which Routes can + attach to them by Route kind, namespace, or hostname. If 1 + of 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. \n + Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + description: Rules are a list of TCP matchers and actions. + items: + description: TCPRouteRule is the configuration for a given rule. + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching + requests should be sent. If unspecified or invalid (refers + to a non-existent resource or a Service with no endpoints), + the underlying implementation MUST actively reject connection + attempts to this backend. Connection rejections must respect + weight; if an invalid backend is requested to have 80% of + connections, then 80% of connections must be rejected instead. + \n Support: Core for Kubernetes Service Support: Custom for + any other resource \n Support for weight: Extended" + items: + description: "BackendRef defines how a Route should forward + a request to a Kubernetes resource. \n Note that when a + namespace is specified, a ReferencePolicy object is required + in the referent namespace to allow that namespace's owner + to accept the reference. See the ReferencePolicy documentation + for details." + properties: + group: + default: "" + description: Group is the group of the referent. For example, + "networking.k8s.io". When unspecified (empty string), + core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace is specified, a ReferencePolicy + object is required in the referent namespace to allow + that namespace's owner to accept the reference. See + the ReferencePolicy documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. For other resources, + destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of TCPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should + be when the underlying condition changed. If that is + not known, then using the time when the API field changed + is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, + if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the + current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier + indicating the reason for the condition's last transition. + Producers of specific condition types may define expected + values and meanings for this field, and whether the + values are considered a guaranteed API. The value should + be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across + resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability + to deconflict is important. The regex it matches is + (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified (or empty string), this refers to the + local namespace of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name \n Implementations MAY choose to support attaching + Routes to other resources. If that is the case, they MUST + clearly document how SectionName is interpreted. \n When + unspecified (empty string), this will reference the entire + resource. For the purpose of status, an attachment is + considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can + restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept + attachment from the referencing Route, the Route MUST + be considered successfully attached. If no Gateway listeners + accept attachment from this Route, the Route MUST be considered + detached from the Gateway. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_tlsroutes.gateway.networking.k8s.io.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_tlsroutes.gateway.networking.k8s.io.yaml new file mode 100644 index 0000000..d7053dd --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_tlsroutes.gateway.networking.k8s.io.yaml @@ -0,0 +1,478 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 + creationTimestamp: null + name: tlsroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: TLSRoute + listKind: TLSRouteList + plural: tlsroutes + singular: tlsroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: "The TLSRoute resource is similar to TCPRoute, but can be configured + to match against TLS-specific metadata. This allows more flexibility in + matching streams for a given TLS listener. \n If you need to forward traffic + to a single target for a TLS listener, you could choose to use a TCPRoute + with a TLS listener." + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of TLSRoute. + properties: + hostnames: + description: "Hostnames defines a set of SNI names that should match + against the SNI attribute of TLS ClientHello message in TLS handshake. + This matches the RFC 1123 definition of a hostname with 2 notable + exceptions: \n 1. IPs are not allowed in SNI names per RFC 6066. + 2. A hostname may be prefixed with a wildcard label (`*.`). The + wildcard label must appear by itself as the first label. \n If + a hostname is specified by both the Listener and TLSRoute, there + must be at least one intersecting hostname for the TLSRoute to be + attached to the Listener. For example: \n * A Listener with `test.example.com` + as the hostname matches TLSRoutes that have either not specified + any hostnames, or have specified at least one of `test.example.com` + or `*.example.com`. * A Listener with `*.example.com` as the hostname + matches TLSRoutes that have either not specified any hostnames + or have specified at least one hostname that matches the Listener + hostname. For example, `test.example.com` and `*.example.com` + would both match. On the other hand, `example.com` and `test.example.net` + would not match. \n If both the Listener and TLSRoute have specified + hostnames, any TLSRoute hostnames that do not match the Listener + hostname MUST be ignored. For example, if a Listener specified `*.example.com`, + and the TLSRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. \n If both + the Listener and TLSRoute have specified hostnames, and none match + with the criteria above, then the TLSRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status + of `False` in the corresponding RouteParentStatus. \n Support: Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged." + items: + description: "ParentRef identifies an API object (usually a Gateway) + that can be considered a parent of this resource (usually a route). + The only kind of parent resource with \"Core\" support is Gateway. + This API may be extended in the future to support additional kinds + of parent resources, such as HTTPRoute. \n The API object must + be valid in the cluster; the Group and Kind must be registered + in the cluster for this reference to be valid. \n References to + objects with invalid Group and Kind are not valid, and must be + rejected by the implementation, with appropriate Conditions set + on the containing object." + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified (or empty string), this refers to the local namespace + of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name + \n Implementations MAY choose to support attaching Routes + to other resources. If that is the case, they MUST clearly + document how SectionName is interpreted. \n When unspecified + (empty string), this will reference the entire resource. For + the purpose of status, an attachment is considered successful + if at least one section in the parent resource accepts it. + For example, Gateway listeners can restrict which Routes can + attach to them by Route kind, namespace, or hostname. If 1 + of 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. \n + Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + description: Rules are a list of TLS matchers and actions. + items: + description: TLSRouteRule is the configuration for a given rule. + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching + requests should be sent. If unspecified or invalid (refers + to a non-existent resource or a Service with no endpoints), + the rule performs no forwarding; if no filters are specified + that would result in a response being sent, the underlying + implementation must actively reject request attempts to this + backend, by rejecting the connection or returning a 503 status + code. Request rejections must respect weight; if an invalid + backend is requested to have 80% of requests, then 80% of + requests must be rejected instead. \n Support: Core for Kubernetes + Service Support: Custom for any other resource \n Support + for weight: Extended" + items: + description: "BackendRef defines how a Route should forward + a request to a Kubernetes resource. \n Note that when a + namespace is specified, a ReferencePolicy object is required + in the referent namespace to allow that namespace's owner + to accept the reference. See the ReferencePolicy documentation + for details." + properties: + group: + default: "" + description: Group is the group of the referent. For example, + "networking.k8s.io". When unspecified (empty string), + core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace is specified, a ReferencePolicy + object is required in the referent namespace to allow + that namespace's owner to accept the reference. See + the ReferencePolicy documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. For other resources, + destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of TLSRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should + be when the underlying condition changed. If that is + not known, then using the time when the API field changed + is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, + if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the + current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier + indicating the reason for the condition's last transition. + Producers of specific condition types may define expected + values and meanings for this field, and whether the + values are considered a guaranteed API. The value should + be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across + resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability + to deconflict is important. The regex it matches is + (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified (or empty string), this refers to the + local namespace of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name \n Implementations MAY choose to support attaching + Routes to other resources. If that is the case, they MUST + clearly document how SectionName is interpreted. \n When + unspecified (empty string), this will reference the entire + resource. For the purpose of status, an attachment is + considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can + restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept + attachment from the referencing Route, the Route MUST + be considered successfully attached. If no Gateway listeners + accept attachment from this Route, the Route MUST be considered + detached from the Gateway. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_udproutes.gateway.networking.k8s.io.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_udproutes.gateway.networking.k8s.io.yaml new file mode 100644 index 0000000..9da0bd1 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/apiextensions.k8s.io_v1_customresourcedefinition_udproutes.gateway.networking.k8s.io.yaml @@ -0,0 +1,429 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/891 + creationTimestamp: null + name: udproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: UDPRoute + listKind: UDPRouteList + plural: udproutes + singular: udproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: UDPRoute provides a way to route UDP traffic. When combined with + a Gateway listener, it can be used to forward traffic on the port specified + by the listener to a set of backends specified by the UDPRoute. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of UDPRoute. + properties: + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged." + items: + description: "ParentRef identifies an API object (usually a Gateway) + that can be considered a parent of this resource (usually a route). + The only kind of parent resource with \"Core\" support is Gateway. + This API may be extended in the future to support additional kinds + of parent resources, such as HTTPRoute. \n The API object must + be valid in the cluster; the Group and Kind must be registered + in the cluster for this reference to be valid. \n References to + objects with invalid Group and Kind are not valid, and must be + rejected by the implementation, with appropriate Conditions set + on the containing object." + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified (or empty string), this refers to the local namespace + of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name + \n Implementations MAY choose to support attaching Routes + to other resources. If that is the case, they MUST clearly + document how SectionName is interpreted. \n When unspecified + (empty string), this will reference the entire resource. For + the purpose of status, an attachment is considered successful + if at least one section in the parent resource accepts it. + For example, Gateway listeners can restrict which Routes can + attach to them by Route kind, namespace, or hostname. If 1 + of 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. \n + Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + description: Rules are a list of UDP matchers and actions. + items: + description: UDPRouteRule is the configuration for a given rule. + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching + requests should be sent. If unspecified or invalid (refers + to a non-existent resource or a Service with no endpoints), + the underlying implementation MUST actively reject connection + attempts to this backend. Packet drops must respect weight; + if an invalid backend is requested to have 80% of the packets, + then 80% of packets must be dropped instead. \n Support: Core + for Kubernetes Service Support: Custom for any other resource + \n Support for weight: Extended" + items: + description: "BackendRef defines how a Route should forward + a request to a Kubernetes resource. \n Note that when a + namespace is specified, a ReferencePolicy object is required + in the referent namespace to allow that namespace's owner + to accept the reference. See the ReferencePolicy documentation + for details." + properties: + group: + default: "" + description: Group is the group of the referent. For example, + "networking.k8s.io". When unspecified (empty string), + core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace is specified, a ReferencePolicy + object is required in the referent namespace to allow + that namespace's owner to accept the reference. See + the ReferencePolicy documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. For other resources, + destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of UDPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should + be when the underlying condition changed. If that is + not known, then using the time when the API field changed + is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, + if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the + current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier + indicating the reason for the condition's last transition. + Producers of specific condition types may define expected + values and meanings for this field, and whether the + values are considered a guaranteed API. The value should + be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across + resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability + to deconflict is important. The regex it matches is + (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified (or empty string), this refers to the + local namespace of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name \n Implementations MAY choose to support attaching + Routes to other resources. If that is the case, they MUST + clearly document how SectionName is interpreted. \n When + unspecified (empty string), this will reference the entire + resource. For the purpose of status, an attachment is + considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can + restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept + attachment from the referencing Route, the Route MUST + be considered successfully attached. If no Gateway listeners + accept attachment from this Route, the Route MUST be considered + detached from the Gateway. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/asm-namespace .yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/asm-namespace .yaml new file mode 100644 index 0000000..41730a0 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/asm-namespace .yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: asm-gateways + annotations: + argocd.argoproj.io/sync-wave: "-1" \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/backendcongfig.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/backendcongfig.yaml new file mode 100644 index 0000000..8e88ed7 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/backendcongfig.yaml @@ -0,0 +1,10 @@ +apiVersion: cloud.google.com/v1 +kind: BackendConfig +metadata: + name: asm-ingress-xlb-config + namespace: asm-gateways +spec: + healthCheck: + requestPath: /healthz/ready + port: 15021 + type: HTTP \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/istio-namespace.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/istio-namespace.yaml new file mode 100644 index 0000000..0bd15d5 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/istio-namespace.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: istio-system + annotations: + argocd.argoproj.io/sync-wave: "-1" \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/loadgen-deploy.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/loadgen-deploy.yaml new file mode 100644 index 0000000..ec2a1d2 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/loadgen-deploy.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: load-test-deployment + namespace: asm-gateways + labels: + app: load-test +spec: + selector: + matchLabels: + app: load-test + template: + metadata: + labels: + app: load-test + spec: + containers: + - name: load-tester + image: argoproj/load-tester:latest + command: [sh, -c, -x, -e] + args: + - | + wrk -t10 -c40 -d6h -s report.lua https://rollout-demo.endpoints.{{GKE_PROJECT_ID}}.cloud.goog/ + jq -e '.errors_ratio <= 0.05 and .latency_avg_ms < 100' report.json \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/multi-cluster-ingress.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/multi-cluster-ingress.yaml new file mode 100644 index 0000000..470b293 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/multi-cluster-ingress.yaml @@ -0,0 +1,14 @@ +apiVersion: networking.gke.io/v1beta1 +kind: MultiClusterIngress +metadata: + name: asm-ingressgateway-xlb-multicluster-ingress + namespace: asm-gateways + annotations: + networking.gke.io/static-ip: "{{ASM_GW_IP}}" + networking.gke.io/pre-shared-certs: "whereami-cert,rollout-demo-cert" +spec: + template: + spec: + backend: + serviceName: asm-ingressgateway-xlb-multicluster-svc + servicePort: 443 diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/multi-cluster-services.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/multi-cluster-services.yaml new file mode 100644 index 0000000..8b9f050 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/multi-cluster-controllers/asm-gateways/multi-cluster-services.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.gke.io/v1beta1 +kind: MultiClusterService +metadata: + name: asm-ingressgateway-xlb-multicluster-svc + namespace: asm-gateways + annotations: + beta.cloud.google.com/backend-config: '{"ports": {"443":"asm-ingress-xlb-config"}}' + networking.gke.io/app-protocols: '{"http2":"HTTP2"}' +spec: + template: + spec: + selector: + asm: ingressgateway-xlb + ports: + - name: http2 + protocol: TCP + port: 443 # Port the Service listens on diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-central-clusters-config/team-1-rollout-demo-destination-rule.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-central-clusters-config/team-1-rollout-demo-destination-rule.yaml new file mode 100644 index 0000000..ff40fac --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-central-clusters-config/team-1-rollout-demo-destination-rule.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: rollout-demo-destrule + namespace: rollout-demo +spec: + host: rollout-demo-stable.rollout-demo.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-central1 + to: us-west1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-central-clusters-config/team-2-whereami-destination-rule.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-central-clusters-config/team-2-whereami-destination-rule.yaml new file mode 100644 index 0000000..5cdab97 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-central-clusters-config/team-2-whereami-destination-rule.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: whereami-destrule + namespace: whereami +spec: + host: whereami-stable.whereami.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-central1 + to: us-west1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-east-clusters-config/team-1-rollout-demo-destination-rule.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-east-clusters-config/team-1-rollout-demo-destination-rule.yaml new file mode 100644 index 0000000..683fa3c --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-east-clusters-config/team-1-rollout-demo-destination-rule.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: rollout-demo-destrule + namespace: rollout-demo +spec: + host: rollout-demo-stable.rollout-demo.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-east1 + to: us-central1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-east-clusters-config/team-2-whereami-destination-rule.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-east-clusters-config/team-2-whereami-destination-rule.yaml new file mode 100644 index 0000000..5acec00 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-east-clusters-config/team-2-whereami-destination-rule.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: whereami-destrule + namespace: whereami +spec: + host: whereami-stable.whereami.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-east1 + to: us-central1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-west-clusters-config/team-1-rollout-demo-destination-rule.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-west-clusters-config/team-1-rollout-demo-destination-rule.yaml new file mode 100644 index 0000000..16e6b1d --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-west-clusters-config/team-1-rollout-demo-destination-rule.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: rollout-demo-destrule + namespace: rollout-demo +spec: + host: rollout-demo-stable.rollout-demo.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-west1 + to: us-central1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-west-clusters-config/team-2-whereami-destination-rule.yaml b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-west-clusters-config/team-2-whereami-destination-rule.yaml new file mode 100644 index 0000000..3440720 --- /dev/null +++ b/examples/gke-fleets-with-argocd/argo-repo-sync/region-clusters-config/us-west-clusters-config/team-2-whereami-destination-rule.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: whereami-destrule + namespace: whereami +spec: + host: whereami-stable.whereami.svc.cluster.local + trafficPolicy: + connectionPool: + http: + maxRequestsPerConnection: 1 + loadBalancer: + simple: ROUND_ROBIN + localityLbSetting: + enabled: true + failover: + - from: us-west1 + to: us-central1 + outlierDetection: + consecutive5xxErrors: 1 + interval: 1s + baseEjectionTime: 1m \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/assets/diagram.png b/examples/gke-fleets-with-argocd/assets/diagram.png new file mode 100644 index 0000000..893dfff Binary files /dev/null and b/examples/gke-fleets-with-argocd/assets/diagram.png differ diff --git a/examples/gke-fleets-with-argocd/config.yaml b/examples/gke-fleets-with-argocd/config.yaml new file mode 100644 index 0000000..d5cd005 --- /dev/null +++ b/examples/gke-fleets-with-argocd/config.yaml @@ -0,0 +1,42 @@ +terraformState: cloud # local, cloud +clustersProjectId: "my-project" +governanceProjectId: "my-project" +region: "us-east1" # Region for resources aside from GKE clusters +enableWindowsNodepool: false +enablePreemptibleNodepool: false # Enforced on Linux Node pools only +privateEndpoint: false +releaseChannel: REGULAR +defaultNodepoolOS: cos +initialNodeCount: 1 +maxNodeCount: 10 +minNodeCount: 3 +configSync: false +policyController: false +multiClusterGateway: true +anthosServiceMesh: true +tfModuleRepo: "github.com/GoogleCloudPlatform/gke-poc-toolkit//terraform/modules/" +tfModuleBranch: "main" +sendAnalytics: true +vpcConfig: + vpcName: "argo-demo" + vpcType: "standalone" # standalone, shared + vpcProjectId: "my-host-project" # Required if you are using a sharedVPC + podCIDRName: "mypodcidr" + svcCIDRName: "mysvccidr" + authCIDR: "0.0.0.0/0" # only needed if enabling private endpoints for clusters +clustersConfig: # a list of one or more clusters, each with their own config +- clusterName: "mccp-central-01" + machineType: "e2-standard-4" + region: "us-central1" + zone: "us-central1-b" + subnetName: "us-central1" +- clusterName: "gke-std-east01" + machineType: "e2-standard-4" + region: "us-east1" + zone: "us-east1-b" + subnetName: "us-east1" +- clusterName: "gke-std-west01" + machineType: "e2-standard-4" + region: "us-west1" + zone: "us-west1-b" + subnetName: "us-west1" \ No newline at end of file diff --git a/examples/gke-fleets-with-argocd/scripts/argocd-openapi.yaml b/examples/gke-fleets-with-argocd/scripts/argocd-openapi.yaml new file mode 100644 index 0000000..165a819 --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/argocd-openapi.yaml @@ -0,0 +1,10 @@ +swagger: "2.0" +info: + description: "Cloud Endpoints DNS" + title: "Cloud Endpoints DNS" + version: "1.0.0" +paths: {} +host: "argocd.endpoints.evmos-gcp.cloud.goog" +x-google-endpoints: +- name: "argocd.endpoints.evmos-gcp.cloud.goog" + target: "34.120.55.131" diff --git a/examples/gke-fleets-with-argocd/scripts/fleet_cluster_add.sh b/examples/gke-fleets-with-argocd/scripts/fleet_cluster_add.sh new file mode 100755 index 0000000..85296cd --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/fleet_cluster_add.sh @@ -0,0 +1,229 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) + +while getopts p:n:l:c:t:w: flag +do + case "${flag}" in + p) PROJECT_ID=${OPTARG};; + n) CLUSTER_NAME=${OPTARG};; + l) CLUSTER_LOCATION=${OPTARG};; + c) CONTROL_PLANE_CIDR=${OPTARG};; + t) CLUSTER_TYPE=${OPTARG};; + w) APP_DEPLOYMENT_WAVE=${OPTARG};; + esac +done + +echo "::Variable set::" +echo "PROJECT_ID: ${PROJECT_ID}" +echo "CLUSTER_NAME: ${CLUSTER_NAME}" +echo "CLUSTER_LOCATION: ${CLUSTER_LOCATION}" +echo "CONTROL_PLANE_CIDR:${CONTROL_PLANE_CIDR}" +echo "CONTROL_TYPE:${CLUSTER_TYPE}" +echo "APP_DEPLOYMENT_WAVE:${APP_DEPLOYMENT_WAVE}" + +REGION=${CLUSTER_LOCATION:0:-2} +PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") +echo "REGION:${REGION}" +echo "PROJECT_NUMBER:${PROJECT_NUMBER}" + +if [[ ${CLUSTER_TYPE} == "autopilot" ]]; then + gcloud beta container --project ${PROJECT_ID} clusters create-auto ${CLUSTER_NAME} \ + --region ${CLUSTER_LOCATION} \ + --release-channel "rapid" \ + --network "argo-demo" --subnetwork ${CLUSTER_LOCATION} \ + --enable-master-authorized-networks \ + --master-authorized-networks 0.0.0.0/0 \ + # --security-group "gke-security-groups@nickeberts.altostrat.com" + # gcloud container clusters update ${CLUSTER_NAME} --project ${PROJECT_ID} \ + # --region ${CLUSTER_LOCATION} \ + # --enable-master-global-access + gcloud container clusters update ${CLUSTER_NAME} --project ${PROJECT_ID} \ + --region ${CLUSTER_LOCATION} \ + --update-labels mesh_id=proj-${PROJECT_NUMBER} +else + gcloud beta container --project ${PROJECT_ID} clusters create ${CLUSTER_NAME} \ + --zone ${CLUSTER_LOCATION} \ + --release-channel "rapid" \ + --machine-type "e2-medium" \ + --num-nodes "3" \ + --network "argo-demo" \ + --subnetwork ${REGION} \ + --enable-ip-alias \ + --enable-autoscaling --min-nodes "3" --max-nodes "10" \ + --enable-autoupgrade --enable-autorepair --max-surge-upgrade 1 --max-unavailable-upgrade 0 \ + --labels mesh_id=proj-${PROJECT_NUMBER} \ + --autoscaling-profile optimize-utilization \ + --workload-pool "${PROJECT_ID}.svc.id.goog" \ + # --security-group "gke-security-groups@nickeberts.altostrat.com" \ + --enable-image-streaming --node-locations ${CLUSTER_LOCATION} + # --master-ipv4-cidr ${CONTROL_PLANE_CIDR} \ + # --enable-private-nodes \ + # --enable-master-authorized-networks \ + # --master-authorized-networks 0.0.0.0/0 \ + # --enable-master-global-access \ +fi + +function join_by { local IFS="$1"; shift; echo "$*"; } +ALL_CLUSTER_CIDRS=$(gcloud container clusters list --project ${PROJECT_ID} --format='value(clusterIpv4Cidr)' | sort | uniq) +ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}")) +TAGS=`gcloud compute firewall-rules list --filter="Name:gke-gke*" --format="value(targetTags)" --project ${PROJECT_ID} | uniq` +TAGS=`join_by , $(echo "${TAGS}")` +echo "Network tags for pod ranges are $TAGS" + +if [[ $(gcloud compute firewall-rules describe asm-multicluster-pods --project ${PROJECT_ID}) ]]; then + gcloud compute firewall-rules update asm-multicluster-pods --project ${PROJECT_ID}\ + --allow=tcp,udp,icmp,esp,ah,sctp \ + --source-ranges="${ALL_CLUSTER_CIDRS}" \ + --target-tags=$TAGS +else + gcloud compute firewall-rules create asm-multicluster-pods --project ${PROJECT_ID}\ + --allow=tcp,udp,icmp,esp,ah,sctp \ + --direction=INGRESS \ + --priority=900 --network=argo-demo \ + --source-ranges="${ALL_CLUSTER_CIDRS}" \ + --target-tags=$TAGS +fi + +gcloud container clusters get-credentials ${CLUSTER_NAME} --zone ${CLUSTER_LOCATION} --project ${PROJECT_ID} +gcloud container fleet memberships register ${CLUSTER_NAME} --project ${PROJECT_ID}\ + --gke-cluster=${CLUSTER_LOCATION}/${CLUSTER_NAME} \ + --enable-workload-identity + +# gcloud container fleet mesh update \ +# --control-plane automatic \ +# --memberships ${CLUSTER_NAME} \ +# --project ${PROJECT_ID} + +kubectx ${CLUSTER_NAME}=gke_${PROJECT_ID}_${CLUSTER_LOCATION}_${CLUSTER_NAME} +kubectl create ns tools --context ${CLUSTER_NAME} +kubectl create ns asm-gateways --context ${CLUSTER_NAME} +kubectl create ns istio-system --context ${CLUSTER_NAME} +kubectl create ns prod-tools --context ${CLUSTER_NAME} +gcloud projects add-iam-policy-binding ${PROJECT_ID} --role roles/monitoring.viewer --member "serviceAccount:${PROJECT_ID}.svc.id.goog[prod-tools/default]" + +openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ +-subj "/CN=frontend.endpoints.${PROJECT_ID}.cloud.goog/O=Edge2Mesh Inc" \ +-keyout frontend.endpoints.${PROJECT_ID}.cloud.goog.key \ +-out frontend.endpoints.${PROJECT_ID}.cloud.goog.crt + +kubectl -n asm-gateways create secret tls edge2mesh-credential \ +--key=frontend.endpoints.${PROJECT_ID}.cloud.goog.key \ +--cert=frontend.endpoints.${PROJECT_ID}.cloud.goog.crt --context ${CLUSTER_NAME} + +rm frontend.endpoints* + +mkdir -p tmp +for i in `gcloud container clusters list --project ${PROJECT_ID} --format="value(name)"`; do + if [[ "$i" != "${CLUSTER_NAME}" ]] && [[ "$i" != "mccp-central-01" ]]; then + echo -e "Creating kubeconfig secret from cluster ${CLUSTER_NAME} and installing it on cluster ${i}" + istioctl create-remote-secret --context=${i} --name=${i} > ./tmp/secret-kubeconfig-${i}.yaml + kubectl apply -f ./tmp/secret-kubeconfig-${i}.yaml --context=${CLUSTER_NAME} + else + echo -e "Skipping as the current cluster ${CLUSTER_NAME} is the same as the target cluster ${i} or the mccp-central-01 cluster." + fi +done +rm -rf tmp + +# if [[ ${CLUSTER_TYPE} == "autopilot" ]]; then +# argocd cluster add ${CLUSTER_NAME} \ +# --label region=${CLUSTER_LOCATION} \ +# --label env=prod \ +# --label wave="${APP_DEPLOYMENT_WAVE}" \ +# --name ${CLUSTER_NAME} \ +# --grpc-web \ +# --system-namespace tools -y +# else +# argocd cluster add ${CLUSTER_NAME} \ +# --label region=${REGION} \ +# --label env=prod \ +# --label wave="${APP_DEPLOYMENT_WAVE}" \ +# --name ${CLUSTER_NAME} \ +# --grpc-web \ +# --system-namespace tools -y +# fi + +if [[ ${CLUSTER_TYPE} == "autopilot" ]]; then +cat < ${CLUSTER_NAME}-argo-secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: ${CLUSTER_NAME} + labels: + argocd.argoproj.io/secret-type: cluster + env: prod + region: ${CLUSTER_LOCATION} + wave: "${APP_DEPLOYMENT_WAVE}" +type: Opaque +stringData: + name: ${CLUSTER_NAME} + server: https://connectgateway.googleapis.com/v1beta1/projects/${PROJECT_NUMBER}/locations/global/gkeMemberships/${CLUSTER_NAME} + config: | + { + "execProviderConfig": { + "command": "argocd-k8s-auth", + "args": ["gcp"], + "apiVersion": "client.authentication.k8s.io/v1beta1" + }, + "tlsClientConfig": { + "insecure": false, + "caData": "" + } + } +EOF +kubectl apply -f ${CLUSTER_NAME}-argo-secret.yaml -n argocd --context mccp-central-01 +else +cat < ${CLUSTER_NAME}-argo-secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: ${CLUSTER_NAME} + labels: + argocd.argoproj.io/secret-type: cluster + env: prod + region: ${REGION} + wave: "${APP_DEPLOYMENT_WAVE}" +type: Opaque +stringData: + name: ${CLUSTER_NAME} + server: https://connectgateway.googleapis.com/v1beta1/projects/${PROJECT_NUMBER}/locations/global/gkeMemberships/${CLUSTER_NAME} + config: | + { + "execProviderConfig": { + "command": "argocd-k8s-auth", + "args": ["gcp"], + "apiVersion": "client.authentication.k8s.io/v1beta1" + }, + "tlsClientConfig": { + "insecure": false, + "caData": "" + } + } +EOF +kubectl apply -f ${CLUSTER_NAME}-argo-secret.yaml -n argocd --context mccp-central-01 +fi + +rm ${CLUSTER_NAME}-argo-secret.yaml + +## Check for apps managed certs and create them if they do not exist +if [[ $(gcloud compute ssl-certificates describe whereami-cert --project ${PROJECT_ID}) ]]; then + echo "Whereami demo app cert already exists" +else + echo "Creating certificates for whereami demo app." + gcloud compute ssl-certificates create whereami-cert \ + --domains=whereami.endpoints.${PROJECT_ID}.cloud.goog \ + --global +fi + +if [[ $(gcloud compute ssl-certificates describe rollout-demo-cert --project ${PROJECT_ID}) ]]; then + echo "Rollout demo app cert already exists" +else + echo "Creating certificate for rollout demo app." + gcloud compute ssl-certificates create rollout-demo-cert \ + --domains=rollout-demo.endpoints.${PROJECT_ID}.cloud.goog \ + --global +fi + +echo "${CLUSTER_NAME} has been deployed and added to the Fleet." diff --git a/examples/gke-fleets-with-argocd/scripts/fleet_cluster_remove.sh b/examples/gke-fleets-with-argocd/scripts/fleet_cluster_remove.sh new file mode 100755 index 0000000..c58262d --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/fleet_cluster_remove.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -Euo pipefail + +script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) + +while getopts p:n:l: flag +do + case "${flag}" in + p) PROJECT_ID=${OPTARG};; + n) CLUSTER_NAME=${OPTARG};; + l) CLUSTER_LOCATION=${OPTARG};; + esac +done + +echo "::Variable set::" +echo "PROJECT: ${PROJECT_ID}" +echo "CLUSTER_NAME: ${CLUSTER_NAME}" +echo "CLUSTER_LOCATION: ${CLUSTER_LOCATION}" + +gcloud container fleet memberships unregister ${CLUSTER_NAME} --gke-cluster=${CLUSTER_LOCATION}/${CLUSTER_NAME} --project ${PROJECT_ID} -q +gcloud container clusters delete ${CLUSTER_NAME} --zone ${CLUSTER_LOCATION} --project ${PROJECT_ID} -q +# ARGO_CLUSTER_TO_REMOVE=$(argocd cluster list --grpc-web | grep ${CLUSTER_NAME} | awk '{print $1}') +# argocd cluster rm ${CLUSTER_NAME} --grpc-web +kubectl delete secret ${CLUSTER_NAME} -n argocd --context mccp-central-01 +kctx -d ${CLUSTER_NAME} + diff --git a/examples/gke-fleets-with-argocd/scripts/fleet_prep.sh b/examples/gke-fleets-with-argocd/scripts/fleet_prep.sh new file mode 100755 index 0000000..64eb65c --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/fleet_prep.sh @@ -0,0 +1,216 @@ +#!/usr/bin/env bash + +set -Euo pipefail + +script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) + +while getopts p:r:t: flag +do + case "${flag}" in + p) PROJECT_ID=${OPTARG};; + r) SYNC_REPO=${OPTARG};; + t) PAT_TOKEN=${OPTARG};; + esac +done + +echo "::Variable set::" +echo "PROJECT_ID: ${PROJECT_ID}" +echo "SYNC_REPO: ${SYNC_REPO}" + +### ArgoCD Install### +echo "Setting up ArgoCD on the mccp cluster including configure it for GKE Ingress." +echo "Creating a global public IP for the ArgoCD." +if [[ $(gcloud compute addresses describe argocd-ip --global --project ${PROJECT_ID}) ]]; then + echo "ArgoCD IP already exists." +else + echo "Creating ArgoCD IP." + gcloud compute addresses create argocd-ip --global --project ${PROJECT_ID} +fi +export GCLB_IP=$(gcloud compute addresses describe argocd-ip --project ${PROJECT_ID} --global --format="value(address)") +echo -e "GCLB_IP is ${GCLB_IP}" + +cat < argocd-openapi.yaml +swagger: "2.0" +info: + description: "Cloud Endpoints DNS" + title: "Cloud Endpoints DNS" + version: "1.0.0" +paths: {} +host: "argocd.endpoints.${PROJECT_ID}.cloud.goog" +x-google-endpoints: +- name: "argocd.endpoints.${PROJECT_ID}.cloud.goog" + target: "${GCLB_IP}" +EOF +gcloud endpoints services deploy argocd-openapi.yaml --project ${PROJECT_ID} + +cat < ${script_dir}/../argo-cd-gke/overlays/gke_ingress/argocd-managed-cert.yaml +apiVersion: networking.gke.io/v1 +kind: ManagedCertificate +metadata: + name: argocd-managed-cert + namespace: argocd +spec: + domains: + - "argocd.endpoints.${PROJECT_ID}.cloud.goog" +EOF + +cat < ${script_dir}/../argo-cd-gke/overlays/gke_ingress/argocd-server-ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: argocd + namespace: argocd + annotations: + kubernetes.io/ingress.global-static-ip-name: argocd-ip + networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config + networking.gke.io/managed-certificates: argocd-managed-cert +spec: + rules: + - host: "argocd.endpoints.${PROJECT_ID}.cloud.goog" + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: argocd-server + port: + number: 80 +EOF + +cat < ${script_dir}/../argo-cd-gke/overlays/gke_ingress/argocd-sa.yaml +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + iam.gke.io/gcp-service-account: argocd-fleet-admin@${PROJECT_ID}.iam.gserviceaccount.com + name: argocd-application-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + iam.gke.io/gcp-service-account: argocd-fleet-admin@${PROJECT_ID}.iam.gserviceaccount.com + name: argocd-server +EOF + +kubectl apply -k argo-cd-gke/overlays/gke_ingress +SECONDS=0 + +echo "Creating a global public IP for the ASM GW." +if [[ $(gcloud compute addresses describe asm-gw-ip --global --project ${PROJECT_ID}) ]]; then + echo "ASM GW IP already exists." +else + echo "Creating ASM GW IP." + gcloud compute addresses create asm-gw-ip --global --project ${PROJECT_ID} +fi +export ASM_GW_IP=`gcloud compute addresses describe asm-gw-ip --global --format="value(address)"` +echo -e "GCLB_IP is ${ASM_GW_IP}" + +echo "Creating gcp endpoints for each demo app." +cat < rollout-demo-openapi.yaml +swagger: "2.0" +info: + description: "Cloud Endpoints DNS" + title: "Cloud Endpoints DNS" + version: "1.0.0" +paths: {} +host: "rollout-demo.endpoints.${PROJECT_ID}.cloud.goog" +x-google-endpoints: +- name: "rollout-demo.endpoints.${PROJECT_ID}.cloud.goog" + target: "${ASM_GW_IP}" +EOF + +gcloud endpoints services deploy rollout-demo-openapi.yaml --project ${PROJECT_ID} + +cat < whereami-openapi.yaml +swagger: "2.0" +info: + description: "Cloud Endpoints DNS" + title: "Cloud Endpoints DNS" + version: "1.0.0" +paths: {} +host: "whereami.endpoints.${PROJECT_ID}.cloud.goog" +x-google-endpoints: +- name: "whereami.endpoints.${PROJECT_ID}.cloud.goog" + target: "${ASM_GW_IP}" +EOF + +gcloud endpoints services deploy whereami-openapi.yaml --project ${PROJECT_ID} + +### Setup Sync Repo w/ Argocd ### +echo "Waiting for managed cert to become Active, this can take about 5 mins." + +while [[ $(kubectl get managedcertificates -n argocd argocd-managed-cert -o=jsonpath='{.status.certificateStatus}') != "Active" ]]; do + sleep 10 + echo "Argocd managed certificate is not yet active and it has been $SECONDS seconds since it was created." +done + +cat < argo-cd-gke/overlays/gke_ingress/argocd-admin-project.yaml +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: admin + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + sourceRepos: + - '*' + destinations: + - namespace: '*' + server: '*' + clusterResourceWhitelist: + - group: '*' + kind: '*' +EOF + +kubectl apply -f argo-cd-gke/overlays/gke_ingress/argocd-admin-project.yaml -n argocd --context mccp-central-01 + +ARGOCD_SECRET=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo) +echo "Logging into to argocd." +argocd login "argocd.endpoints.${PROJECT_ID}.cloud.goog" --username admin --password ${ARGOCD_SECRET} --grpc-web + +if [[ $(argocd cluster get mccp-central-01 --grpc-web) ]]; then + echo "The mccp-central-01 cluster is already registered to ArgoCD." +else + echo "Adding the mccp-central-01 cluster to ArgoCD." + argocd cluster add mccp-central-01 --in-cluster --label=env="multi-cluster-controller" --grpc-web -y +fi + +cd argo-repo-sync +git init + +REPO="https://github.com/"$(gh repo list | grep ${SYNC_REPO} | awk '{print $1}') + +if [[ ${REPO} != "https://github.com/" ]]; then + echo "${SYNC_REPO} repo already exists in github." +else + echo "Creating repo ${SYNC_REPO} in github." + gh repo create ${SYNC_REPO} --private --source=. --remote=upstream + REPO="https://github.com/"$(gh repo list | grep ${SYNC_REPO} | awk '{print $1}') +fi + +if [[ "$OSTYPE" == "darwin"* ]]; then + LC_ALL=C find ./ -type f -exec sed -i '' -e "s/{{GKE_PROJECT_ID}}/${PROJECT_ID}/g" {} + + LC_ALL=C find ./ -type f -exec sed -i '' -e "s/{{ASM_GW_IP}}/${ASM_GW_IP}/g" {} + + LC_ALL=C find ./ -type f -exec sed -i '' -e "s|{{SYNC_REPO}}|${REPO}|g" {} + +else + find ./ -type f -exec sed -i -e "s/{{GKE_PROJECT_ID}}/${PROJECT_ID}/g" {} + + find ./ -type f -exec sed -i -e "s/{{ASM_GW_IP}}/${ASM_GW_IP}/g" {} + + find ./ -type f -exec sed -i -e "s|{{SYNC_REPO}}|${REPO}|g" {} + +fi + +### Setup applicationsets ### +kubectl apply -f generators/ -n argocd --context mccp-central-01 + +### Binding GCP RBAC to the ARGOCD service accounts +gcloud iam service-accounts create argocd-fleet-admin --project ${PROJECT_ID} +gcloud projects add-iam-policy-binding ${PROJECT_ID} --member "serviceAccount:argocd-fleet-admin@${PROJECT_ID}.iam.gserviceaccount.com" --role 'roles/container.admin' --project ${PROJECT_ID} +gcloud projects add-iam-policy-binding ${PROJECT_ID} --member "serviceAccount:argocd-fleet-admin@${PROJECT_ID}.iam.gserviceaccount.com" --role 'roles/gkehub.gatewayAdmin' --project ${PROJECT_ID} +gcloud iam service-accounts add-iam-policy-binding --role roles/iam.workloadIdentityUser --member "serviceAccount:${PROJECT_ID}.svc.id.goog[argocd/argocd-server]" argocd-fleet-admin@${PROJECT_ID}.iam.gserviceaccount.com --project ${PROJECT_ID} +gcloud iam service-accounts add-iam-policy-binding --role roles/iam.workloadIdentityUser --member "serviceAccount:${PROJECT_ID}.svc.id.goog[argocd/argocd-application-controller]" argocd-fleet-admin@${PROJECT_ID}.iam.gserviceaccount.com --project ${PROJECT_ID} + +echo "The Fleet has been configured, checkout the sync status here:" +echo "https://argocd.endpoints.${PROJECT_ID}.cloud.goog" diff --git a/examples/gke-fleets-with-argocd/scripts/rollout-demo-openapi.yaml b/examples/gke-fleets-with-argocd/scripts/rollout-demo-openapi.yaml new file mode 100644 index 0000000..6d1c7c1 --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/rollout-demo-openapi.yaml @@ -0,0 +1,10 @@ +swagger: "2.0" +info: + description: "Cloud Endpoints DNS" + title: "Cloud Endpoints DNS" + version: "1.0.0" +paths: {} +host: "rollout-demo.endpoints.evmos-gcp.cloud.goog" +x-google-endpoints: +- name: "rollout-demo.endpoints.evmos-gcp.cloud.goog" + target: "34.95.112.78" diff --git a/examples/gke-fleets-with-argocd/scripts/team_app_add.sh b/examples/gke-fleets-with-argocd/scripts/team_app_add.sh new file mode 100755 index 0000000..b77e59c --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/team_app_add.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +set -Euo pipefail + +script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) + +while getopts a:h:i:p:t: flag +do + case "${flag}" in + a) APP_NAME=${OPTARG};; + h) APP_HOST_NAME=${OPTARG};; + i) APP_IMAGE=${OPTARG};; + p) PROJECT_ID=${OPTARG};; + t) TEAM_NAME=${OPTARG};; + esac +done + +echo "::Variable set::" +echo "APP_NAME: ${APP_NAME}" +echo "APP_HOST_NAME: ${APP_HOST_NAME}" +echo "APP_IMAGE: ${APP_IMAGE}" +echo "PROJECT_ID: ${PROJECT_ID}" +echo "TEAM_NAME: ${TEAM_NAME}" + +cd $script_dir +APP_DIR=../argo-repo-sync/teams/${TEAM_NAME}/${APP_NAME}/ +mkdir -p ${APP_DIR} +cp ../argo-repo-sync/app-template/new-app/* ${APP_DIR} + +APP_IMAGE="${APP_IMAGE}" +if [[ "$OSTYPE" == "darwin"* ]]; then + for file in ${APP_DIR}*; do + [ -e "${file}" ] + echo ${file} + sed -i '' -e "s/APP_NAME/${APP_NAME}/g" ${file} + sed -i '' -e "s|APP_IMAGE|${APP_IMAGE}|g" ${file} + sed -i '' -e "s/TEAM_NAME/${TEAM_NAME}/g" ${file} + # sed -i '' -e "s/WAVE/${WAVE}/g" ${file} + sed -i '' -e "s/APP_HOST_NAME/${APP_HOST_NAME}/g" ${file} + done +else + for file in ${APP_DIR}*; do + [ -e "${file}" ] + echo ${file} + sed -i -e "s/APP_NAME/${APP_NAME}/g" ${file} + sed -i -e "s|APP_IMAGE|${APP_IMAGE}|g" ${file} + sed -i -e "s/TEAM_NAME/${TEAM_NAME}/g" ${file} + # sed -i '' -e "s/WAVE/${WAVE}/g" ${file} + sed -i -e "s/APP_HOST_NAME/${APP_HOST_NAME}/g" ${file} + done +fi + +mv ${APP_DIR}applicationset-wave-1.yaml ../argo-repo-sync/generators/${TEAM_NAME}-${APP_NAME}-applicationset-wave-1.yaml +mv ${APP_DIR}applicationset-wave-2.yaml ../argo-repo-sync/generators/${TEAM_NAME}-${APP_NAME}-applicationset-wave-2.yaml +mv ${APP_DIR}argocd-project.yaml ../argo-repo-sync/teams/${TEAM_NAME}/ +mv ${APP_DIR}virtual-service.yaml ../argo-repo-sync/app-clusters-config/asm-gateways/${TEAM_NAME}-${APP_NAME}-virtual-service.yaml +mv ${APP_DIR}destination-rule-central.yaml ../argo-repo-sync/region-clusters-config/us-central-clusters-config/${TEAM_NAME}-${APP_NAME}-destination-rule.yaml +mv ${APP_DIR}destination-rule-east.yaml ../argo-repo-sync/region-clusters-config/us-east-clusters-config/${TEAM_NAME}-${APP_NAME}-destination-rule.yaml +mv ${APP_DIR}destination-rule-west.yaml ../argo-repo-sync/region-clusters-config/us-west-clusters-config/${TEAM_NAME}-${APP_NAME}-destination-rule.yaml +mv ${APP_DIR}namespace.yaml ../argo-repo-sync/app-clusters-config/asm-gateways/${TEAM_NAME}-${APP_NAME}-namespace.yaml +cd ../argo-repo-sync + +git checkout wave-one +git merge main +git add . && git commit -m "Added application ${APP_NAME} to wave-one branch." +git push -u origin wave-one + +git checkout wave-two +git merge wave-one +git add . && git commit -m "Added application ${APP_NAME} to wave-two branch." +git push -u origin wave-two + +git checkout main +git merge wave-two +git add . && git commit -m "Added application ${APP_NAME} to team ${TEAM_NAME}." +git push -u origin main + +kubectl apply -f ../argo-repo-sync/teams/${TEAM_NAME}/argocd-project.yaml -n argocd --context mccp-central-01 +kubectl apply -f ../argo-repo-sync/generators/${TEAM_NAME}-${APP_NAME}-applicationset-wave-1.yaml -n argocd --context mccp-central-01 +kubectl apply -f ../argo-repo-sync/generators/${TEAM_NAME}-${APP_NAME}-applicationset-wave-2.yaml -n argocd --context mccp-central-01 + +echo "Added application ${APP_NAME} to team ${TEAM_NAME} and staged for wave one and wave two clusters." + + + diff --git a/examples/gke-fleets-with-argocd/scripts/team_app_remove.sh b/examples/gke-fleets-with-argocd/scripts/team_app_remove.sh new file mode 100755 index 0000000..0099c97 --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/team_app_remove.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +set -Euo pipefail + +script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) + +while getopts a:t: flag +do + case "${flag}" in + a) APP_NAME=${OPTARG};; + t) TEAM_NAME=${OPTARG};; + esac +done + +echo "::Variable set::" +echo "APP_NAME: ${APP_NAME}" +echo "TEAM_NAME: ${TEAM_NAME}" + +cd $script_dir/../argo-repo-sync +git checkout main + +APP_DIR=teams/${TEAM_NAME}/${APP_NAME} +kubectl delete -f generators/${TEAM_NAME}-${APP_NAME}-applicationset-wave-1.yaml -n argocd --context mccp-central-01 +kubectl delete -f generators/${TEAM_NAME}-${APP_NAME}-applicationset-wave-2.yaml -n argocd --context mccp-central-01 + +rm -rf ${APP_DIR} +rm generators/${TEAM_NAME}-${APP_NAME}-* +rm region-clusters-config/us-central-clusters-config/${TEAM_NAME}-${APP_NAME}-destination-rule.yaml +rm region-clusters-config/us-east-clusters-config/${TEAM_NAME}-${APP_NAME}-destination-rule.yaml +rm region-clusters-config/us-west-clusters-config/${TEAM_NAME}-${APP_NAME}-destination-rule.yaml +rm app-clusters-config/asm-gateways/${TEAM_NAME}-${APP_NAME}-* + +git add . && git commit -m "Removed application ${APP_NAME} from main branch." +git push + +git checkout wave-one +git merge main +git add . && git commit -m "Removed application ${APP_NAME} from wave-one branch." +git push + +git checkout wave-two +git merge main +git add . && git commit -m "Removed application ${APP_NAME} from wave-two branch." +git push + +echo "Removed application ${APP_NAME} from all branches." + + + + + + + diff --git a/examples/gke-fleets-with-argocd/scripts/team_app_rollout.sh b/examples/gke-fleets-with-argocd/scripts/team_app_rollout.sh new file mode 100755 index 0000000..3f8eff0 --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/team_app_rollout.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +set -Euo pipefail + +script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) + +while getopts a:i:l:t:w: flag +do + case "${flag}" in + a) APP_NAME=${OPTARG};; + i) APP_IMAGE=${OPTARG};; + l) APP_IMAGE_TAG=${OPTARG};; + t) TEAM_NAME=${OPTARG};; + w) WAVE=${OPTARG};; + esac +done + +echo "::Variable set::" +echo "APP_NAME: ${APP_NAME}" +echo "APP_IMAGE: ${APP_IMAGE}" +echo "APP_IMAGE_TAG: ${APP_IMAGE_TAG}" +echo "TEAM_NAME: ${TEAM_NAME}" +echo "WAVE:${WAVE}" + +cd $script_dir/../argo-repo-sync +APP_DIR=../argo-repo-sync/teams/${TEAM_NAME}/${APP_NAME}/ +if [[ "$OSTYPE" == "darwin"* ]]; then + if [[ ${WAVE} == "one" ]]; then + git checkout wave-one + git merge main + sed -i '' -e "s|image: ${APP_IMAGE}:.*|image: ${APP_IMAGE}:${APP_IMAGE_TAG}|g" ${APP_DIR}rollout.yaml + git add . && git commit -m "Updated application ${APP_NAME} image tag to ${APP_IMAGE}:${APP_IMAGE_TAG} on wave ${WAVE} clusters." + git push -u origin wave-one + elif [[ ${WAVE} == "two" ]]; then + git checkout wave-two + git merge wave-one + git add . && git commit -m "Updated application ${APP_NAME} image tag to ${APP_IMAGE}:${APP_IMAGE_TAG} on wave ${WAVE} clusters." + git push -u origin wave-two + else + git checkout main + git merge wave-two + git add . && git commit -m "Merged application ${APP_NAME} update ${APP_IMAGE}:${APP_IMAGE_TAG} into main." + git push -u origin main + fi +else + if [[ ${WAVE} == "one" ]]; then + git checkout wave-one + git merge main + sed -i -e "s|image: ${APP_IMAGE}:.*|image: ${APP_IMAGE}:${APP_IMAGE_TAG}|g" ${APP_DIR}rollout.yaml + git add . && git commit -m "Updated application ${APP_NAME} image tag to ${APP_IMAGE}:${APP_IMAGE_TAG} on wave ${WAVE} clusters." + git push -u origin wave-one + elif [[ ${WAVE} == "two" ]]; then + git checkout wave-two + git merge wave-one + git add . && git commit -m "Updated application ${APP_NAME} image tag to ${APP_IMAGE}:${APP_IMAGE_TAG} on wave ${WAVE} clusters." + git push -u origin wave-two + else + git checkout main + git merge wave-two + git add . && git commit -m "Merged application ${APP_NAME} update ${APP_IMAGE}:${APP_IMAGE_TAG} into main." + git push -u origin main + fi +fi + + diff --git a/examples/gke-fleets-with-argocd/scripts/whereami-openapi.yaml b/examples/gke-fleets-with-argocd/scripts/whereami-openapi.yaml new file mode 100644 index 0000000..a1a482a --- /dev/null +++ b/examples/gke-fleets-with-argocd/scripts/whereami-openapi.yaml @@ -0,0 +1,10 @@ +swagger: "2.0" +info: + description: "Cloud Endpoints DNS" + title: "Cloud Endpoints DNS" + version: "1.0.0" +paths: {} +host: "whereami.endpoints.evmos-gcp.cloud.goog" +x-google-endpoints: +- name: "whereami.endpoints.evmos-gcp.cloud.goog" + target: "34.95.112.78" diff --git a/k8s/README.md b/k8s/README.md new file mode 100644 index 0000000..050eb03 --- /dev/null +++ b/k8s/README.md @@ -0,0 +1,15 @@ +# Terraform K8s setup in GKE +Terraform K8s setup of a public and a private GKE cluster +Requires access to gcloud via oauth + + + + + Use an oauth token, such as this example from a GKE cluster. The google_client_config data source fetches a token from the Google Authorization server, which expires in 1 hour by default. +```json +provider "kubernetes" { + host = "https://${data.google_container_cluster.my_cluster.endpoint}" + token = data.google_client_config.default.access_token + cluster_ca_certificate = base64decode(data.google_container_cluster.my_cluster.master_auth[0].cluster_ca_certificate) +} +``` diff --git a/k8s/kubernetes-dashboard-admin.rbac.yaml b/k8s/kubernetes-dashboard-admin.rbac.yaml new file mode 100644 index 0000000..33d62b1 --- /dev/null +++ b/k8s/kubernetes-dashboard-admin.rbac.yaml @@ -0,0 +1,32 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: admin-user + namespace: kube-system +--- +#Create Secret for ServiceAccount +apiVersion: v1 +kind: Secret +metadata: + name: admin-user + namespace: kube-system + annotations: + kubernetes.io/service-account.name: "admin-user" +type: kubernetes.io/service-account-token +--- +# Create ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: admin-user +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: admin-user + namespace: kube-system diff --git a/k8s/private-cluster/.terraform.lock.hcl b/k8s/private-cluster/.terraform.lock.hcl new file mode 100644 index 0000000..0ef915b --- /dev/null +++ b/k8s/private-cluster/.terraform.lock.hcl @@ -0,0 +1,122 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/external" { + version = "2.3.1" + constraints = ">= 2.2.2" + hashes = [ + "h1:bROCw6g5D/3fFnWeJ01L4IrdnJl1ILU8DGDgXCtYzaY=", + "zh:001e2886dc81fc98cf17cf34c0d53cb2dae1e869464792576e11b0f34ee92f54", + "zh:2eeac58dd75b1abdf91945ac4284c9ccb2bfb17fa9bdb5f5d408148ff553b3ee", + "zh:2fc39079ba61411a737df2908942e6970cb67ed2f4fb19090cd44ce2082903dd", + "zh:472a71c624952cff7aa98a7b967f6c7bb53153dbd2b8f356ceb286e6743bb4e2", + "zh:4cff06d31272aac8bc35e9b7faec42cf4554cbcbae1092eaab6ab7f643c215d9", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7ed16ccd2049fa089616b98c0bd57219f407958f318f3c697843e2397ddf70df", + "zh:842696362c92bf2645eb85c739410fd51376be6c488733efae44f4ce688da50e", + "zh:8985129f2eccfd7f1841ce06f3bf2bbede6352ec9e9f926fbaa6b1a05313b326", + "zh:a5f0602d8ec991a5411ef42f872aa90f6347e93886ce67905c53cfea37278e05", + "zh:bf4ab82cbe5256dcef16949973bf6aa1a98c2c73a98d6a44ee7bc40809d002b8", + "zh:e70770be62aa70198fa899526d671643ff99eecf265bf1a50e798fc3480bd417", + ] +} + +provider "registry.terraform.io/hashicorp/google" { + version = "5.5.0" + constraints = ">= 5.0.0, < 6.0.0" + hashes = [ + "h1:TQ4LGg1zAYB81X3ANvzLEjMdq/e05NLBFkG/ZuPHG6s=", + "zh:0052a5f222a3e19debb1e5621998809a91e7cc312aa825da21bf2e73876def1f", + "zh:116f9797723523efcfa7de3d3884003134a8eda891f6824440c6f56b598ae55b", + "zh:3b8bc1e26f856d4193ca50d866862903238196d59368141afdfff1cc992e63ef", + "zh:7397a2502a98a7b778df7c95caf0d2b10c873782bb503b5810cb8314912a7595", + "zh:8bffba8191eb299c22386c7d94524ea0cbbcff950f76bb2b361c266b17d4c403", + "zh:b2566261c0dbf0bfcda85bc9fb109e11c95be206c58ea467ea5772bdaba4166e", + "zh:c62527252932484d4e999e0766ae8225216cb89ed53ad00a10babbd24ba75f03", + "zh:cfd9cb93ba9fb33bf41aa99bedc225c211ef330e3a9a7a1347b88a8abaa490e4", + "zh:f242d0edf3234823f7b7c9ec658c149b36427813c84d554a7c39ed125ac5bec3", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f80c9936e9efa5234fc55c3436841f3720b384e87db6abc1aacf65a1a225d07f", + "zh:fb3b178154e1ff8685add05012c3ebacb7c247be2933af86a9deea72fba30782", + ] +} + +provider "registry.terraform.io/hashicorp/google-beta" { + version = "5.5.0" + constraints = ">= 4.47.0, != 4.49.0, != 4.50.0, < 6.0.0" + hashes = [ + "h1:6MuTgOzwLbcUgQX+KeaWRstq3fjV+nevKTDQQ1Z6Md0=", + "zh:32d2a3d7c38cc5fa52c27241c48b4eaf601499f2e731b8db2be65b50536ebef0", + "zh:384929a478fcd397c5faf4e25e924df8bec5f772734db8d72a60c78dcdf88460", + "zh:394597d7260b821b4fdfe9d96d5d4d7220b7218fa1fdb1b15a30c86d9bdca8b5", + "zh:46139fa03b3b299d241cd3a1ab5baac6ffc5beef118bbad509190bcb11b095f6", + "zh:90210370899aa2fc92cdd8d850842541b44d3ab97c90db65bfa9a8fa6e07bc4b", + "zh:a63e5f536b23092c7ac3d09c3513ae55b7edc9bf72f55979ef16f595a2fd747a", + "zh:b1559b027f630c570ba3123f4aec7e9c2b2ff5d5389d0f00fb56af99cda51740", + "zh:b70cb5c5a645bd7bf15a328d4b528512805bfe2cc5a84eeb5a52784c9f0f1b50", + "zh:e4fe9727df775382d1b35f4907ba423ea9c221658f4460c103aad1b2c4c7e5a8", + "zh:f05226eaf6e7c7723ecde07314b8e0105520f4a29ab5b60397b660ade7a20374", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f6a8fca11369140fcdfda6ead955622e72f8665881f4e269a0251d8b7038113a", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.23.0" + constraints = "~> 2.10" + hashes = [ + "h1:xyFc77aYkPoU4Xt1i5t0B1IaS8TbTtp9aCSuQKDayII=", + "zh:10488a12525ed674359585f83e3ee5e74818b5c98e033798351678b21b2f7d89", + "zh:1102ba5ca1a595f880e67102bbf999cc8b60203272a078a5b1e896d173f3f34b", + "zh:1347cf958ed3f3f80b3c7b3e23ddda3d6c6573a81847a8ee92b7df231c238bf6", + "zh:2cb18e9f5156bc1b1ee6bc580a709f7c2737d142722948f4a6c3c8efe757fa8d", + "zh:5506aa6f28dcca2a265ccf8e34478b5ec2cb43b867fe6d93b0158f01590fdadd", + "zh:6217a20686b631b1dcb448ee4bc795747ebc61b56fbe97a1ad51f375ebb0d996", + "zh:8accf916c00579c22806cb771e8909b349ffb7eb29d9c5468d0a3f3166c7a84a", + "zh:9379b0b54a0fa030b19c7b9356708ec8489e194c3b5e978df2d31368563308e5", + "zh:aa99c580890691036c2931841e88e7ee80d59ae52289c8c2c28ea0ac23e31520", + "zh:c57376d169875990ac68664d227fb69cd0037b92d0eba6921d757c3fd1879080", + "zh:e6068e3f94f6943b5586557b73f109debe19d1a75ca9273a681d22d1ce066579", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.1" + constraints = ">= 2.1.0" + hashes = [ + "h1:FbGfc+muBsC17Ohy5g806iuI1hQc4SIexpYCrQHQd8w=", + "zh:58ed64389620cc7b82f01332e27723856422820cfd302e304b5f6c3436fb9840", + "zh:62a5cc82c3b2ddef7ef3a6f2fedb7b9b3deff4ab7b414938b08e51d6e8be87cb", + "zh:63cff4de03af983175a7e37e52d4bd89d990be256b16b5c7f919aff5ad485aa5", + "zh:74cb22c6700e48486b7cabefa10b33b801dfcab56f1a6ac9b6624531f3d36ea3", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:79e553aff77f1cfa9012a2218b8238dd672ea5e1b2924775ac9ac24d2a75c238", + "zh:a1e06ddda0b5ac48f7e7c7d59e1ab5a4073bbcf876c73c0299e4610ed53859dc", + "zh:c37a97090f1a82222925d45d84483b2aa702ef7ab66532af6cbcfb567818b970", + "zh:e4453fbebf90c53ca3323a92e7ca0f9961427d2f0ce0d2b65523cc04d5d999c2", + "zh:e80a746921946d8b6761e77305b752ad188da60688cfd2059322875d363be5f5", + "zh:fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f", + "zh:fca01a623d90d0cad0843102f9b8b9fe0d3ff8244593bd817f126582b52dd694", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.5.1" + constraints = ">= 2.1.0" + hashes = [ + "h1:VSnd9ZIPyfKHOObuQCaKfnjIHRtR7qTw19Rz8tJxm+k=", + "zh:04e3fbd610cb52c1017d282531364b9c53ef72b6bc533acb2a90671957324a64", + "zh:119197103301ebaf7efb91df8f0b6e0dd31e6ff943d231af35ee1831c599188d", + "zh:4d2b219d09abf3b1bb4df93d399ed156cadd61f44ad3baf5cf2954df2fba0831", + "zh:6130bdde527587bbe2dcaa7150363e96dbc5250ea20154176d82bc69df5d4ce3", + "zh:6cc326cd4000f724d3086ee05587e7710f032f94fc9af35e96a386a1c6f2214f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:b6d88e1d28cf2dfa24e9fdcc3efc77adcdc1c3c3b5c7ce503a423efbdd6de57b", + "zh:ba74c592622ecbcef9dc2a4d81ed321c4e44cddf7da799faa324da9bf52a22b2", + "zh:c7c5cde98fe4ef1143bd1b3ec5dc04baf0d4cc3ca2c5c7d40d17c0e9b2076865", + "zh:dac4bad52c940cd0dfc27893507c1e92393846b024c5a9db159a93c534a3da03", + "zh:de8febe2a2acd9ac454b844a4106ed295ae9520ef54dc8ed2faf29f12716b602", + "zh:eab0d0495e7e711cca367f7d4df6e322e6c562fc52151ec931176115b83ed014", + ] +} diff --git a/k8s/private-cluster/README.md b/k8s/private-cluster/README.md new file mode 100644 index 0000000..b2e4ffa --- /dev/null +++ b/k8s/private-cluster/README.md @@ -0,0 +1,26 @@ +# Private Zonal Cluster Terraform Setup + +Create a simple private cluster in a single zone. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| cluster\_name\_suffix | A suffix to append to the default cluster name | `string` | `""` | no | +| ip\_range\_pods | The secondary ip range to use for pods | `any` | n/a | yes | +| ip\_range\_services | The secondary ip range to use for services | `any` | n/a | yes | +| network | The VPC network to host the cluster in | `any` | n/a | yes | +| project\_id | The project ID to host the cluster in | `any` | n/a | yes | +| region | The region to host the cluster in | `any` | n/a | yes | +| subnetwork | The subnetwork to host the cluster in | `any` | n/a | yes | +| zones | The zone to host the cluster in (required if is a zonal cluster) | `list(string)` | n/a | yes | + +## Update Inputs In terraform.tfvars +The code is pretty generic, most variable can directly be set in the .tfvars file +A generic VPC confuration is set in private-vpc.tf. Edit as needed. + +To provision this example, run the following from within this directory: +- `terraform init` to get the plugins +- `terraform plan` to see the infrastructure plan +- `terraform apply` to apply the infrastructure build +- `terraform destroy` to destroy the built infrastructure \ No newline at end of file diff --git a/k8s/private-cluster/gke-private.tf b/k8s/private-cluster/gke-private.tf new file mode 100644 index 0000000..9c4bcef --- /dev/null +++ b/k8s/private-cluster/gke-private.tf @@ -0,0 +1,114 @@ +# google_client_config and kubernetes provider must be explicitly specified like the following. +data "google_client_config" "default" {} + +provider "kubernetes" { + host = "https://${module.gke.endpoint}" + token = data.google_client_config.default.access_token + cluster_ca_certificate = base64decode(module.gke.ca_certificate) +} + +# data "google_compute_subnetwork" "subnetwork" { +# name = var.subnetwork +# project = var.project_id +# region = var.region +# } + +locals { + cluster_type = "private-zonal" +} + + +module "gke" { + source = "terraform-google-modules/kubernetes-engine/google//modules/private-cluster" + project_id = var.project_id + name = "${local.cluster_type}-cluster${var.cluster_name_suffix}" + region = var.region + zones = var.zones + network = var.network + subnetwork = var.subnetwork + ip_range_pods = var.ip_range_pods + ip_range_services = var.ip_range_services + http_load_balancing = false + network_policy = true + horizontal_pod_autoscaling = true + filestore_csi_driver = false + enable_private_endpoint = false # turn to true in production environment + enable_private_nodes = true + master_ipv4_cidr_block = "10.50.0.0/28" + master_global_access_enabled = true + add_cluster_firewall_rules = true + gateway_api_channel = "CHANNEL_STANDARD" + + # enable in production. + # master_authorized_networks = [ + # { + # cidr_block = data.google_compute_subnetwork.subnetwork.ip_cidr_range + # display_name = "VPC" + # }, + # ] + + node_pools = [ + { + name = "default-node-pool" + machine_type = "e2-medium" + node_locations = "us-central1-a,us-central1-b" + min_count = 1 + max_count = 5 + local_ssd_count = 0 + spot = false + disk_size_gb = 10 + disk_type = "pd-standard" + image_type = "COS_CONTAINERD" + enable_gcfs = false + enable_gvnic = false + logging_variant = "DEFAULT" + auto_repair = true + auto_upgrade = true + preemptible = false + initial_node_count = 1 + }, + ] + + node_pools_oauth_scopes = { + all = [ + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + ] + } + + node_pools_labels = { + all = {} + + default-node-pool = { + default-node-pool = true + } + } + + node_pools_metadata = { + all = {} + + default-node-pool = { + node-pool-metadata-custom-value = "my-node-pool" + } + } + + node_pools_taints = { + all = [] + + default-node-pool = [ + { + key = "default-node-pool" + value = true + effect = "PREFER_NO_SCHEDULE" + }, + ] + } + + node_pools_tags = { + all = [] + + default-node-pool = [ + "default-node-pool", + ] + } +} \ No newline at end of file diff --git a/k8s/private-cluster/main.tf b/k8s/private-cluster/main.tf new file mode 100644 index 0000000..e913846 --- /dev/null +++ b/k8s/private-cluster/main.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } + + required_version = ">= 1.1.0" +} diff --git a/k8s/private-cluster/private-vpc.tf b/k8s/private-cluster/private-vpc.tf new file mode 100644 index 0000000..e2106bb --- /dev/null +++ b/k8s/private-cluster/private-vpc.tf @@ -0,0 +1,29 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +provider "google" { + project = var.project_id + region = var.region +} + +# VPC +resource "google_compute_network" "vpc" { + name = "${var.project_id}-vpc-us1" + auto_create_subnetworks = "false" +} + +# Subnet +resource "google_compute_subnetwork" "private-subnet" { + name = "${var.project_id}-private-subnet-${var.region}" + region = var.region + network = google_compute_network.vpc.name + ip_cidr_range = "10.0.0.0/16" + secondary_ip_range { + range_name = "${var.region}-gke-pods" + ip_cidr_range = "10.1.0.0/16" + } + secondary_ip_range { + range_name = "${var.region}-gke-services" + ip_cidr_range = "10.2.0.0/16" + } +} diff --git a/k8s/private-cluster/terraform.tfvars b/k8s/private-cluster/terraform.tfvars new file mode 100644 index 0000000..64e2cdf --- /dev/null +++ b/k8s/private-cluster/terraform.tfvars @@ -0,0 +1,11 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +cluster_name_suffix = "us" +ip_range_pods = "us-central1-gke-pods" +ip_range_services = "us-central1-gke-services" +network = "evmos-gcp-vpc-us1" +project_id = "evmos-gcp" +region = "us-central1" +subnetwork = "evmos-gcp-private-subnet-us-central1" +zones = ["us-central1-a", "us-central1-b"] diff --git a/k8s/private-cluster/variables.tf b/k8s/private-cluster/variables.tf new file mode 100644 index 0000000..cc3a05a --- /dev/null +++ b/k8s/private-cluster/variables.tf @@ -0,0 +1,33 @@ +variable "project_id" { + description = "The project ID to host the cluster in" +} + +variable "cluster_name_suffix" { + description = "A suffix to append to the default cluster name" + default = "" +} + +variable "region" { + description = "The region to host the cluster in" +} + +variable "zones" { + type = list(string) + description = "The zone to host the cluster in (required if is a zonal cluster)" +} + +variable "network" { + description = "The VPC network to host the cluster in" +} + +variable "subnetwork" { + description = "The subnetwork to host the cluster in" +} + +variable "ip_range_pods" { + description = "The secondary ip range to use for pods" +} + +variable "ip_range_services" { + description = "The secondary ip range to use for services" +} diff --git a/k8s/public-cluster/.terraform.lock.hcl b/k8s/public-cluster/.terraform.lock.hcl new file mode 100644 index 0000000..65a5692 --- /dev/null +++ b/k8s/public-cluster/.terraform.lock.hcl @@ -0,0 +1,23 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "4.74.0" + constraints = "4.74.0" + hashes = [ + "h1:ghkjuvUrHsIlzjNL5KRsYZcP3R9BoFRfb0q069BXBi4=", + "h1:sod0KZScwUDWiOEEBY7JSXj8kNxiP8wPjqpAauiaTeI=", + "zh:60904193c367b1ba9a3cb1bd86ca469ffcec2f7237e59adf4b0a34c84b2fa9ff", + "zh:6e5ac12f3fefc23907a94e5f6040118c978af76ab5deb60a5b80110c1c8ade09", + "zh:9fc0ae0f97ab598c27fae0a6b19e82c13fd59d020d7cdfeeebdbe41c4a8216ef", + "zh:aa2346dbd9f22e56d011b1b741e1829bc78633cc3da704d7c4e9636c314541fa", + "zh:ca692e666253cca77c6ff68423bf940c7f249a8b4f4af9b80c1a7079808b8ada", + "zh:cbaf541db823cff4379e294ad696bef2940c3eff863fa7fd340ea978872dfdaf", + "zh:d1f6fba2f64d51a804bf4f4e90b7809e26fa0539a1119e55907cc501add6a5d2", + "zh:d556680c85b8c90557b469d30a8082f056a2b724f812b97da6505a9d78139854", + "zh:ea7cd2d4fa940e3518221a67f24b2ff8d795c325fe8b95fd149ac0cc3e1e944a", + "zh:eca542a0e4caed8ab6a30eb0199755dfc2938083942a233d6a5ef60e204ac67c", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f729b6f01050dd443b98cc5e7911102cdc8209e250cc1c2568aa37ba74b7c894", + ] +} diff --git a/k8s/public-cluster/gke-public.tf.bkup b/k8s/public-cluster/gke-public.tf.bkup new file mode 100644 index 0000000..4afef1b --- /dev/null +++ b/k8s/public-cluster/gke-public.tf.bkup @@ -0,0 +1,89 @@ +# google_client_config and kubernetes provider must be explicitly specified like the following. +data "google_client_config" "default" {} + +provider "kubernetes" { + host = "https://${module.gke.endpoint}" + token = data.google_client_config.default.access_token + cluster_ca_certificate = base64decode(module.gke.ca_certificate) +} + +module "gke" { + source = "terraform-google-modules/kubernetes-engine/google" + project_id = "evmos-gcp" + name = "gke-private-us" + region = "${var.region}" + zones = ["us-central1-a", "us-central1-b", "us-central1-f"] + network = "${var.project_id}-vpc-us1" + subnetwork = "${var.project_id}-private-subnet-${var.region}" + ip_range_pods = "${var.region}-gke-pods" + ip_range_services = "${var.region}-gke-services" + http_load_balancing = false + network_policy = false + horizontal_pod_autoscaling = true + filestore_csi_driver = false + + node_pools = [ + { + name = "default-node-pool" + machine_type = "e2-medium" + node_locations = "us-central1-b,us-central1-c" + min_count = 1 + max_count = 3 + local_ssd_count = 0 + spot = false + disk_size_gb = 10 + disk_type = "pd-standard" + image_type = "COS_CONTAINERD" + enable_gcfs = false + enable_gvnic = false + logging_variant = "DEFAULT" + auto_repair = true + auto_upgrade = true + preemptible = false + initial_node_count = 2 + }, + ] + + node_pools_oauth_scopes = { + all = [ + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + ] + } + + node_pools_labels = { + all = {} + + default-node-pool = { + default-node-pool = true + } + } + + node_pools_metadata = { + all = {} + + default-node-pool = { + node-pool-metadata-custom-value = "my-node-pool" + } + } + + node_pools_taints = { + all = [] + + default-node-pool = [ + { + key = "default-node-pool" + value = true + effect = "PREFER_NO_SCHEDULE" + }, + ] + } + + node_pools_tags = { + all = [] + + default-node-pool = [ + "default-node-pool", + ] + } +} \ No newline at end of file diff --git a/k8s/public-cluster/gke.tf b/k8s/public-cluster/gke.tf new file mode 100644 index 0000000..d84b108 --- /dev/null +++ b/k8s/public-cluster/gke.tf @@ -0,0 +1,57 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +variable "gke_num_nodes" { + default = 1 + description = "number of gke nodes" +} + +# GKE cluster +data "google_container_engine_versions" "gke_version" { + location = var.region + version_prefix = "1.27." +} + +resource "google_container_cluster" "primary" { + name = "${var.project_id}-gke" + location = var.region + + # We can't create a cluster with no node pool defined, but we want to only use + # separately managed node pools. So we create the smallest possible default + # node pool and immediately delete it. + remove_default_node_pool = true + initial_node_count = 1 + + network = google_compute_network.vpc.name + subnetwork = google_compute_subnetwork.subnet.name +} + +# Separately Managed Node Pool +resource "google_container_node_pool" "primary_nodes" { + name = google_container_cluster.primary.name + location = var.region + cluster = google_container_cluster.primary.name + + version = data.google_container_engine_versions.gke_version.release_channel_latest_version["STABLE"] + node_count = var.gke_num_nodes + + node_config { + oauth_scopes = [ + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + ] + + labels = { + env = var.project_id + } + + # preemptible = true + machine_type = "n1-standard-8" + disk_size_gb = 50 + local_ssd_count = 1 + tags = ["gke-node", "${var.project_id}"] + metadata = { + disable-legacy-endpoints = "true" + } + } +} diff --git a/k8s/public-cluster/outputs.tf b/k8s/public-cluster/outputs.tf new file mode 100644 index 0000000..3ca5add --- /dev/null +++ b/k8s/public-cluster/outputs.tf @@ -0,0 +1,22 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +output "region" { + value = var.region + description = "GCloud Region" +} + +output "project_id" { + value = var.project_id + description = "GCloud Project ID" +} + +output "kubernetes_cluster_name" { + value = google_container_cluster.primary.name + description = "GKE Cluster Name" +} + +output "kubernetes_cluster_host" { + value = google_container_cluster.primary.endpoint + description = "GKE Cluster Host" +} diff --git a/k8s/public-cluster/terraform.tfvars b/k8s/public-cluster/terraform.tfvars new file mode 100644 index 0000000..1be60b9 --- /dev/null +++ b/k8s/public-cluster/terraform.tfvars @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +project_id = "evmos-gcp" +region = "europe-west1" diff --git a/k8s/public-cluster/versions.tf b/k8s/public-cluster/versions.tf new file mode 100644 index 0000000..c71ae32 --- /dev/null +++ b/k8s/public-cluster/versions.tf @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +terraform { + required_providers { + google = { + source = "hashicorp/google" + # version = "4.74.0" + } + } + + required_version = ">= 1.0" +} diff --git a/k8s/public-cluster/vpc.tf b/k8s/public-cluster/vpc.tf new file mode 100644 index 0000000..1641fa3 --- /dev/null +++ b/k8s/public-cluster/vpc.tf @@ -0,0 +1,29 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +variable "project_id" { + description = "project id" +} + +variable "region" { + description = "region" +} + +provider "google" { + project = var.project_id + region = var.region +} + +# VPC +resource "google_compute_network" "vpc" { + name = "${var.project_id}-vpc" + auto_create_subnetworks = "false" +} + +# Subnet +resource "google_compute_subnetwork" "subnet" { + name = "${var.project_id}-subnet" + region = var.region + network = google_compute_network.vpc.name + ip_cidr_range = "10.10.0.0/24" +}