Compare commits

...

61 Commits

Author SHA1 Message Date
Jeff McCune
30ddde7b49 (maint) Add make image to make help
Previously it wasn't clear how to build the image, wasn't showing up in
make help.
2024-06-24 20:48:47 -07:00
Jeff McCune
5cced6fb51 Version 0.84.0 2024-06-24 20:40:00 -07:00
Jeff McCune
a82ebf43b6 Merge pull request #187 from holos-run/jeff/180-backstage-component
(#180) Configure GitHub Apps Discovery
2024-06-24 20:38:17 -07:00
Jeff McCune
ebb6d6205a (#180) Configure GitHub Apps Discovery
Previously Backstage was not configured to integrate with GitHub.  The
integration is necessary for Backstage to automatically discover
resources in a GitHub organization and import them into the Catalog.

This patch adds a new platform model form field and section for the
primary GitHub organization name of the platform.  Additional GitHub
organizations can be added in the future, Backstage supports them.

The result is Backstage automatically scans public and private
repositories and adds the information in `catalog-info.yaml` to the UI.
2024-06-24 20:35:20 -07:00
Jeff McCune
58950c469a (#180) Manage default-istio ServiceAccount
Previosly the gateway ArogCD Application resource is out of sync because
the `default-istio` `ServiceAccount` is not in the git repository
source.  Argo would prune the service account on sync which is a problem.

This patch manages the service account so the Application can be synced
properly.
2024-06-13 06:04:10 -07:00
Jeff McCune
0eebdaf0c7 (#180) Fix authpolicy component after generate
Previously the holos render platform command fails with the following
error when giving a demo after the generate platform step.

This patch updates the internal generated holos platform to the latest
version.

Running through the demo is successful now.

```
holos logout
holos login
holos register user
holos generate platform holos
holos pull platform config .
holos render platform ./platform
```
2024-06-13 05:51:47 -07:00
Jeff McCune
54e2f28f4c (#179) Double check if the error group is done.
I'm not sure if we should check in the loop, in the go routine, or in
both places.  Double check in both cases just to be sure we're not doing
extra unnecessary work.
2024-06-06 15:51:16 -07:00
Jeff McCune
d4d50ef12b (#179) Use errorgroup SetLimit to limit concurrency
Previously a channel was used to limit concurrency.  This is more
difficult to read and comprehend than the inbuilt errorgroup.SetLimit
functionality.

This patch uses `errgroup.`[Group.SetLimit()][1] to limit concurrency,
avoid leaking go routines, and avoid unnecessary work.

[1]: https://pkg.go.dev/golang.org/x/sync/errgroup#Group.SetLimit
2024-06-06 15:23:49 -07:00
Jeff McCune
075f2b16a4 Merge pull request #179 from holos-run:nate/concurrency
Add concurrency to 'holos render platform'
2024-06-06 15:10:50 -07:00
Nate McCurdy
6f8008a53c Add concurrency to 'holos render platform'
This adds concurrency to the 'holos render platform' command so platform
components are rendered in less time than before.

Default concurrency is set to `min(runtime.NumCPU(), 8)`, which is the
lesser of 8 or the number of CPU cores. In testing, I found that past 8,
there are diminishing or negative returns due to memory usage or
rendering each component.

In practice, this reduced rendering of the saas platform components from
~90s to ~28s on my 12-core macbook pro.

This also changes the key name of the Helm Chart's version in log lines
from `version` to `chart_version` since `version` already exists and
shows the Holos CLI version.
2024-06-06 15:04:55 -07:00
Jeff McCune
0618b52bae (#181) Add AuthorizationPolicy resources for admin interfaces
Previously, when a user registered and logged into the holos app server,
they were able to reach admin interfaces like
https://argocd.admin.example.com

This patch adds AuthorizationPolicy resources governing the whole
cluster.  Users with the prod-cluster-{admin,edit,view} roles may access
admin services like argocd.

Users without these roles are blocked with RBAC: access denied.

In ZITADEL, the Holos Platform project is granted to the CIAM
organization without granting the prod-cluster-* roles, so there's no
possible way a CIAM user account can have these roles.
2024-06-06 14:57:48 -07:00
Jeff McCune
f1951c5db3 (#178) Add holos push platform model command
Previously there wasn't a good way to populate the platform model in the
database after building a new instance of holos server.

With this patch, the process to reset clean is:

```
export HOLOS_SERVER=https://dev.app.holos.run:443
grpcurl -H "x-oidc-id-token: $(holos token)" ${HOLOS_SERVER##*/} holos.user.v1alpha1.SystemService.DropTables
grpcurl -H "x-oidc-id-token: $(holos token)" ${HOLOS_SERVER##*/} holos.system.v1alpha1.SystemService.SeedDatabase
```

Then populate the form and model:

```
holos push platform form .
holos push platform model .
```

The `platform.config.json` file stored in version control is pushed to
the holos server and stored in the database.  This makes it nice and
easy to reset entirely, or move to another service url.
2024-06-05 15:38:55 -07:00
Jeff McCune
dad12acd8d (#178) Seed the Holos Platform itself
Previously this would have needed to be created in pgAdmin.
2024-06-05 14:17:31 -07:00
Jeff McCune
a4503e076f (#178) Add make image task to push the container image
Previously there wasn't an easy way to make the container image and
publish it.  This adds a simple `make image` task to build and push the
image.
2024-06-05 14:03:31 -07:00
Jeff McCune
09ddd339b8 (#178) Update user ids for SeedDatabase rpc
Need them to match the new login issuer.
2024-06-05 13:57:52 -07:00
Jeff McCune
bc94f4b6b8 (#178) Login to https://login.holos.run
Previously the default oidc issuer was to one of the kubernetes clusters
running in my basement.  This patch changes the issuer to the production
ready issuer running in EKS.
2024-06-05 13:42:37 -07:00
Jeff McCune
564406f60f (#178) Add app.example.com HTTPRoute for holos server
Previously the holos server Service was not exposed.

This patch exposes the holos service with an HTTPRoute behind the auth
proxy.  Holos successfully authenticates the user with the
x-oidc-id-token header set by the default Gateway.

---

Add dev-holos-infra and dev-holos-app

Previously the PostgresCluster and the holos server Deployment are not
managed on the aws2 cluster.

This patch is a start, but the Deployment does not yet start.  We need
to pass an option for the oidc issuer.

---

Add namespaces and cert for prod-holos, dev-holos, jeff-holos

Previously we didn't have a place to deploy holos server.  This patch
adds a namespace, creates a Gateway listener, and binds the tls certs
for app.example.com and *.app.example.com to the listeners.

In addition, cluster specific endpoints of *.app.aws2.example.com,
*.app.aws1.example.com, etc. are created to provide dev environment
urls. For example jeff.app.aws2.example.com is my personal dev hostname.
2024-06-05 13:15:11 -07:00
Jeff McCune
7845ce62e0 (#178) Update buf with make tools
Previously go releaser was failing because buf has been updated again.
2024-06-03 11:10:42 -07:00
Jeff McCune
a1542752b7 (#178) Add ArgoCD Application resources for each build plan
Previously holos render platform ./platform did not render any GitOps
resources for Flux or ArgoCD.

This patch uses the new DeployFiles field in holos v0.83.0 to write an
Application resource for every component BuildPlan listed in the
platform.
2024-06-03 10:33:05 -07:00
Jeff McCune
7956475363 (#178) Add BuildPlan deployFiles field
Previously, each BuildPlan has no clear way to produce an ArgoCD
Application resource.  This patch provides a general solution where each
BuildPlan can provide arbitrary files as a map[string]string where the
key is the file path relative to the gitops repository `deploy/` folder.
2024-06-03 10:00:35 -07:00
Jeff McCune
004ed56591 (#178) Add ArgoCD repository credentials
Previously ArgoCD has no ssh credentials to connect to GitHub.  This
patch adds an ssh ed25519 key as a secret in the management cluster.
The secret is synced to the workload clusters using an ExternalSecret
with the proper label for ArgoCD to find and load it for use with any
application that references the Git URL.
2024-06-02 15:58:35 -07:00
Jeff McCune
d497df3c27 (#178) Add ArgoCD RBAC Policy
Previously a logged in user could not modify anything in ArgoCD.  With
this patch users who have been granted the prod-cluster-admin role in
ZITADEL are granted the admin role in ArgoCD.
2024-06-02 15:07:27 -07:00
Jeff McCune
3a8d46234f (#178) Add ArgoCD
Previously ArgoCD was present in the platform configuration, but not
functional.  This patch brings ArgoCD fully up, integrated with the
service mesh, auth proxy, and SSO at
https://argocd.admin.clustername.example.com/

The upstream [helm chart][1] is used instead of the kustomize install
method.  We had existing prior art integrating the v6 helm chart with
the holos platform identity provider, so we continue with the helm
chart.

CRDs are still managed with the kustomize version.  The CRDs need to be
kept in sync.  It's possible to generate the kustomization.yaml file
from the same version value as is used by the helm chart, but we don't
for the time being.

[1]: https://github.com/argoproj/argo-helm/tree/argo-cd-7.1.1/charts/argo-cd
2024-06-02 14:35:36 -07:00
Jeff McCune
4d24dc5149 (#178) Add authpolicy component for RequestAuthentication
Previously, no RequestAuthentication or AuthorizationPolicy resources
govern the default Gateway.  This patch adds the resources and
configures the service mesh with the authproxy as an ExtAuthZ provider
for CUSTOM AuthorizationPolicy rules.

This patch also fixes a bug in the zitadel-server component where
resources from the upstream helm chart did not specify a namespace.
Kustomize is used as a post processor to force all resources into the
zitadel namespace.

Add multiple HTTPRoutes to validate http2 connection reuse

This patch adds multiple HTTPRoute resources which match
*.admin.example.com  The purpose is to validate http2 connections are
reused properly with Chrome.

With this patch no 404 no route errors are encountered when navigating
between the various httpbin{1,2,3,4} urls.

Add note backupRestore will trigger a restore

The process of configuring ZITADEL to provision from a datasource will
cause an in-place restore from S3.  This isn't a major issue, but users
should be aware data added since the most recent backup will be lost.
2024-06-02 09:41:57 -07:00
Jeff McCune
8eb7fbf7dc (#178) Move httpbin HTTPRoute resources to namespace istio-gateways
Previously, HTTPRoute resources were in the same namespace as the
backend service, httpbin in this case.  This doesn't follow the default
behavior of a Gateway listener only allowing attachment from HTTPRoute
resources in the same namespace as the Gateway.

This also complicates intercepting the authproxy path prefix and sending
it to the authproxy.  We'd need to add a ReferenceGrant in the authproxy
namespace, which seems backwards and dangerous because it would grant
the application developer the ability to route requests to all Services
in the istio-gateways namespace.

This patch enables Cluster Operators to manage the HTTPRoute resources
and direct the auth proxy path prefix of `/holos/authproxy` to the auth
proxy Service in the same namespace.

ReferenceGrant resources are used to enable the HTTPRoute backend
references.

When an application developer needs to manage their own HTTPRoute, as is
the case for ZITADEL, a label selector may be used and will override
less specific HTTPRoute hostsnames in the istio-gateways namespace.
2024-06-01 21:18:47 -07:00
Jeff McCune
ffeeb7c553 (#178) Add authproxy Deployment
With redis.  The auth proxy authenticates correctly against zitadel
running in the same cluster.  Validated by visiting
https://httpbin.admin.clustername.example.com/holos/authproxy

Visiting
https://httpbin.admin.clustername.example.com/holos/authproxy/auth
returns the id token in the response header, visible in the Chrome
network inspector.  The ID token works as expected from multiple orgs
with project grants in ZITADEL from the Holos org to the OIS org.

This patch doesn't fully implement the auth proxy feature.
AuthorizationPolicy and RequestAuthentication resources need to be
added.

Before we do so, we need to move the HTTPRoute resources into the
gateway namespace so all of the security policies are in one place and
to simplify the process of routing requests to two backends, the
authproxy and the backend server.
2024-06-01 20:12:35 -07:00
Jeff McCune
c3c174155c (#178) Add httpbin{1,2,3,4} HTTPRoutes to validate http2 connection reuse
This patch adds multiple HTTPRoute resources which match
*.admin.example.com  The purpose is to validate http2 connections are
reused properly with Chrome.

With this patch no 404 no route errors are encountered when navigating
between the various httpbin{1,2,3,4} urls.
2024-06-01 12:44:33 -07:00
Jeff McCune
2c2d2a9fd9 (#178) Add Namespaces documentation
Describe how to manage a new namespace to build a component in.
2024-06-01 09:43:32 -07:00
Jeff McCune
d692e2a6d5 (#178) Split subdomain certs into two certs
Problem:
Istio 1.22 with Gateway API and HTTPRoute is mis-routing HTTP2 requests
when the tls certificate has two dns names, for example
login.example.com and *.login.example.com.

When the user visits login.example.com and then tries to visit
other.login.example.com with Chrome, the connection is re-used and istio
returns a 404 route not found error even though there is a valid and
accepted HTTPRoute for *.login.example.com

This patch attempts to fix the problem by ensuring certificate dns names
map exactly to Gateway listeners.  When a wildcard cert is used, the
corresponding Gateway listener host field exactly matches the wildcard
cert dns name so Istio and envoy should not get confused.
2024-06-01 09:30:47 -07:00
Jeff McCune
e4cebddd0c (#178) Make aws2 the primary cluster 2024-05-31 14:01:11 -07:00
Jeff McCune
0e48537d65 (#178) Add zitadel-server component
This patch adds the ZITADEL server component, which deploys zitadel from
a helm chart.  Kustomize is used heavily to patch the output of helm to
make the configuration fit nicely with the holos platform.

With this patch the two Jobs that initialize the database and setup
ZITADEL run successfully.  The ZITADEL deployment starts successfully.

ZITADEL is accessible at https://login.example.com/ with the default
admin username of `zitadel-admin@zitadel.login.example.com` and password
`Password1!`.

Use grant.holos.run/subdomain.admin: "true" for HTTPRoute

This patch clarifies the label that grants httproute attachment for a
subdomain Gateway listener to a namespace.

Fix istio-base holos component name

Was named `base` which is the chart name, not the holos component name.
2024-05-31 13:47:03 -07:00
Jeff McCune
a461a96b9c (#178) Add ZITADEL crunchy pgo PostgresCluster
This patch adds the postgres clusters and a few console form controls to
configure how backups are taken and if the postgres cluster is
initialized from an existing backup or not.

The pgo-s3-creds file is manually created at this time.  It looks like:

    ❯ holos get secret -n zitadel pgo-s3-creds --print-key s3.conf
    [global]
    repo2-cipher-pass=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    repo2-s3-key=KKKKKKKKKKKKKKKKKKKK
    repo2-s3-key-secret=/SSSSSSS/SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
    repo3-cipher-pass=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    repo3-s3-key=KKKKKKKKKKKKKKKKKKKK
    repo3-s3-key-secret=/SSSSSSS/SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

The s3 key and secret are credentials to read / write to the bucket.
The cipher pass is a random string for client side encryption.  Generate
it with `tr -dc A-Za-z0-9 </dev/urandom | head -c 64`
2024-05-30 11:33:00 -07:00
Jeff McCune
9524c4f7c3 (#178) Add crunchy postgres operator
Needed for ZITADEL and Holos Server.  Intended for ephemeral dev
environments, but may also try it in staging while we wait for RDS.
2024-05-29 12:03:05 -07:00
Jeff McCune
64b04d9cfd (#178) Add Gateway listener for login.example.com
This patch is foundational work for the ZITADEL login service.

This patch adds a tls certificate with names *.login.example.com and
login.example.com, a pair of listeners attached to the certificate in
the `default` Gateway, and the ExternalSecret to sync the secret from
the management cluster.

The zitadel namespace is managed and has the label
holos.run/login.grant: "true" to grant HTTPRoute attachment from the
zitadel namespace to the default Gateway in the istio-gateways
namespace.
2024-05-29 09:27:08 -07:00
Jeff McCune
b419ad8caf (#178) Add HTTPRoute for httpbin.admin.aws1.example.com
With this change, https://httpbin.admin.aws1.example.com works as
expected.

PROXY protocol is configured on the AWS load balancer and the istio
gateway.  The istio gateway logs have the correct client source ip
address and x-forwarded-for headers.

Namespaces must have the holos.run/admin.grant: "true" label in order to
attach an HTTPRoute to the admin section of the default Gateway.

The TLS certificate is working as expected and hopefully does not suffer
from the NR route not found issued encountered with the Istio Gateway
API.
2024-05-28 21:10:18 -07:00
Jeff McCune
8036c17916 (#178) Add istiod and gateway components
This patch gets the istio-ingressgateway up and running in AWS with
minimal configuration.  No authentication or authorization policies have
been migrated from previous iterations of the platform.  These will be
handled in subsequent iterations.

Connectivity to a backend service like httpbin has not yet been tested.
This will happen in a follow up as well using /httpbin path prefixes on
existing services like argocd to conserve certificate resources.
2024-05-28 14:37:25 -07:00
Jeff McCune
220d498be0 (#178) Define a #IngressCertificate
This is the standard way to issue public facing certificates.  Be aware
of the 50 cert limit per week from LetsEncrypt.  We map names to certs
1:1 to avoid http2 connection reuse issues with istio.
2024-05-28 13:15:14 -07:00
Jeff McCune
0f5b6a2d6e (#178) Add istio 1.22.0 base component 2024-05-28 13:08:34 -07:00
Jeff McCune
36369d75c7 (#178) Add argocd.admin.aws1.holos.run cert
Manage certificates on a project basis similar to how namespaces
associated with each project are managed.

Manage the Certificate resources on the management cluster in the
istio-ingress namespace so the tls certs can be synced to the workload
clusters.
2024-05-28 11:50:31 -07:00
Jeff McCune
059b8283fd (#178) Add cert-letsencrypt component for holos management cluster
The secret needs to be manually provisioned for this to work since the
management cluster does not sync secrets from any other external
cluster.
2024-05-26 09:56:46 -07:00
Jeff McCune
386eb2452a (#178) Add cert-manager to the holos platform
This patch adds cert-manager on all clusters.  On the management cluster
cert manager is scheduled on spot instances to reduce cost.
2024-05-26 09:29:15 -07:00
Jeff McCune
38e9a97fd2 (#178) Add secretstores holos platform component
The secretstores component is critical and provides the mechanism to
securely fetch Secret resources from the Management Cluster.
The holos server and configuration code stored in version control
contains only ExternalSecret references, no actual secrets.

This component adds a `default` `SecretStore` to each management
namespace which uses the `eso-reader` service account token to
authenticate to the management cluster.  This service account is limited
to reading secrets within the namespace it resides in.

For example:

```yaml
---
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: default
  namespace: external-secrets
spec:
  provider:
    kubernetes:
      auth:
        token:
          bearerToken:
            key: token
            name: eso-reader
      remoteNamespace: external-secrets
      server:
        caBundle: Long Base64 encoded string
        url: https://34.121.54.174
```
2024-05-25 15:02:06 -07:00
Jeff McCune
ecca40e9d5 (#178) Add holos platform eso-creds-manager
This patch adds the `eso-creds-manager` component which needs to be
applied to the management cluster prior to the `eso-creds-refreher`
component being applied to workload clusters.

The manager component configures rbac to allow the creds-refresher job
to complete.

This patch also adjusts the behavior to only create secrets for the
eso-reader account by default.

Namespaces with the label `holos.run/eso.writer=true` will also have an
eso-writer secret provisioned in their namespace, allowing secrets to be
written back to the management cluster.  This is intended for the
PushSecret resource.
2024-05-24 15:09:59 -07:00
Jeff McCune
9d08e27e31 (#178) Add cue.mod/gen/k8s.io/api/batch/v1 2024-05-23 16:33:58 -07:00
Jeff McCune
969bf5e867 (#178) Import k8s rbac api
cue get go k8s.io/api/rbac/v1beta1
cue get go k8s.io/api/rbac/v1
2024-05-23 16:26:24 -07:00
Jeff McCune
3b5f28f4df (#178) Fix holos generate writing executable files
Adhere to the umask to allow group writable or world writable, but do
not set the execute bit.
2024-05-23 11:37:04 -07:00
Jeff McCune
df5619f988 (#178) Add ArgoCD schematic and component to holos
Add the ArgoCD component which is a good example of how to wrap a plain
kustomize kustomization.yaml file with Holos.
2024-05-23 11:18:29 -07:00
Jeff McCune
a6d8383176 (#178) Do not write flux kustomization if empty
If the holos component returns no data for the flux kustomization, don't
bother writing an useless empty file.
2024-05-23 10:56:08 -07:00
Jeff McCune
dbc7e374cd (#178) Update buf 2024-05-23 09:37:46 -07:00
Jeff McCune
d81729857b (#178) v0.81.2 for holos
Use v0.81.2 to build out the holos platform.  Once we have the
components structured fairly well we can circle back around and copy the
components to schematics.  There's a bit of friction regenerating the
platform from schematic each time.
2024-05-23 09:14:27 -07:00
Jeff McCune
d3d8a7b73c (#178) Shape _Namespaces to corev1.#Namespace
Eliminate the need for a for loop by having _Namespaces be a struct of
name to k8s.io/api/core/v1.#Namespace
2024-05-23 09:12:08 -07:00
Jeff McCune
d9e6776b95 (#178) npm upgrade 2024-05-23 06:41:10 -07:00
Jeff McCune
bde98faffa (#178) Use private fields to store data
Using CUE definitions like #Platform to hold data is confusing.  Clarify
the use of fields, definitions like #Platform define the shape (schema)
of the data while private fields like _Platform represent and hold the
data.
2024-05-23 06:38:52 -07:00
Jeff McCune
c2847554e0 (#178) Add namespaces to holos platform 2024-05-22 17:04:47 -07:00
Jeff McCune
9411a65dd8 (#178) Add namespaces component schematic
The first thing most platforms need to do is come up with a strategy for
managing namespaces across multiple clusters.

This patch defines #Namespaces in the holos platform and adds a
namespaces component which loops over all values in the #Namespaces
struct and manages a kubernetes Namespace object.

The platform resource itself loops over all clusters in the platform to
manage all namespaces across all clusters.

From a blank slate:

```
❯ holos generate platform holos
4:26PM INF platform.go:79 wrote platform.metadata.json version=0.82.0 platform_id=018fa1cf-a609-7463-aa6e-fa53bfded1dc path=/home/jeff/workspace/holos-run/holos-infra/saas/platform.metadata.json
4:26PM INF platform.go:91 generated platform holos version=0.82.0 platform_id=018fa1cf-a609-7463-aa6e-fa53bfded1dc path=/home/jeff/workspace/holos-run/holos-infra/saas

❯ holos pull platform config .
4:26PM INF pull.go:64 pulled platform model version=0.82.0 server=https://jeff.app.dev.k2.holos.run:443 platform_id=018fa1cf-a609-7463-aa6e-fa53bfded1dc
4:26PM INF pull.go:75 saved platform config version=0.82.0 server=https://jeff.app.dev.k2.holos.run:443 platform_id=018fa1cf-a609-7463-aa6e-fa53bfded1dc path=platform.config.json

❯ (cd components && holos generate component cue namespaces)
4:26PM INF component.go:147 generated component version=0.82.0 name=namespaces path=/home/jeff/workspace/holos-run/holos-infra/saas/components/namespaces

❯ holos render platform ./platform/
4:26PM INF platform.go:29 ok render component version=0.82.0 path=components/namespaces cluster=management num=1 total=2 duration=464.055541ms
4:26PM INF platform.go:29 ok render component version=0.82.0 path=components/namespaces cluster=aws1 num=2 total=2 duration=467.978499ms
```

The result:

```sh
cat deploy/clusters/management/components/namespaces/namespaces.gen.yaml
```

```yaml
---
metadata:
  name: holos
  labels:
    kubernetes.io/metadata.name: holos
kind: Namespace
apiVersion: v1
```
2024-05-22 16:32:59 -07:00
Jeff McCune
9c1165e77e (#178) Save platform.config.json with multiple lines 2024-05-22 14:10:28 -07:00
Jeff McCune
a02c7a4015 (#178) Fix the PlatformService CreatePlatform rpc
Without this patch the
holos.platform.v1alpha1.PlatformService.CreatePlatform doesn't work as
expected.  The Platform message is used which incorrectly requires a
client supplied id which is ignored by the server.

This patch allows the creation of a new platform by reusing the update
operation as a mutation that applies to both create and update.  Only
modifiable fields are part of the PlatformMutation message.
2024-05-22 12:39:24 -07:00
Jeff McCune
bdcde88e6f (#175) Add git describe to --version output
Much easier to track changes between releases.
2024-05-21 13:21:27 -07:00
Jeff McCune
a32b100192 (#175) Output at the end
Flip the let definitions to before their use to avoid confusing /
distracting users who are just getting started.

User feedback from Nate.
2024-05-21 13:03:22 -07:00
Jeff McCune
670d716403 (#175) Add podinfo oci example
This patch adds to more example helm chart based components.  podinfo
installs as a normal https repository based helm chart.  podinfo-oci
uses an oci image to manage the helm chart.

The way holos handls OCI images is subtle, so it's good to include an
example right out of the chute.  Github actions uses OCI images for
example.
2024-05-21 12:36:45 -07:00
Jeff McCune
bba3895f35 (#175) Add holos generate component helm command
This patch adds a schematic to generate a holos component that wraps a
helm chart.  The cert-manager chart is the current example.

Usage:

```bash
set -euo pipefail

rm -rf ~/holos/dev/bare
mkdir ~/holos/dev/bare
cd ~/holos/dev/bare

holos generate platform bare
holos pull platform config .
holos render platform ./platform/
(cd components && holos generate component helm cert-manager)
```

The chart builds:

```bash
holos build ./components/cert-manager | yq .
```

And renders:

```bash
holos render component ./components/cert-manager --cluster-name k2
find deploy -type f
```

```txt
9:41PM INF render.go:83 rendered cert-manager version=0.81.1 cluster=k2 status=ok action=rendered name=cert-manager
deploy/clusters/k2/holos/components/cert-manager-kustomization.gen.yaml
deploy/clusters/k2/components/cert-manager/cert-manager.gen.yaml
```
2024-05-21 11:05:53 -07:00
277 changed files with 84207 additions and 672 deletions

8
Dockerfile Normal file
View File

@@ -0,0 +1,8 @@
FROM quay.io/holos-run/debian:bullseye AS final
USER root
WORKDIR /app
ADD bin bin
RUN chown -R app: /app
# Kubernetes requires the user to be numeric
USER 8192
ENTRYPOINT bin/holos server

View File

@@ -7,7 +7,7 @@ REPO_PATH=$(ORG_PATH)/$(PROJ)
VERSION := $(shell cat version/embedded/major version/embedded/minor version/embedded/patch | xargs printf "%s.%s.%s")
BIN_NAME := holos
DOCKER_REPO=quay.io/openinfrastructure/holos
DOCKER_REPO=quay.io/holos-run/holos
IMAGE_NAME=$(DOCKER_REPO)
$( shell mkdir -p bin)
@@ -16,10 +16,12 @@ $( shell mkdir -p bin)
export PATH := $(PWD)/internal/frontend/holos/node_modules/.bin:$(PATH)
GIT_COMMIT=$(shell git rev-parse HEAD)
GIT_SUFFIX=$(shell test -n "`git status --porcelain`" && echo "-dirty" || echo "")
GIT_DETAIL=$(shell git describe --tags HEAD)
GIT_TREE_STATE=$(shell test -n "`git status --porcelain`" && echo "dirty" || echo "clean")
BUILD_DATE=$(shell date -Iseconds)
LD_FLAGS="-w -X ${ORG_PATH}/${PROJ}/version.GitCommit=${GIT_COMMIT} -X ${ORG_PATH}/${PROJ}/version.GitTreeState=${GIT_TREE_STATE} -X ${ORG_PATH}/${PROJ}/version.BuildDate=${BUILD_DATE}"
LD_FLAGS="-w -X ${ORG_PATH}/${PROJ}/version.GitDescribe=${GIT_DETAIL}${GIT_SUFFIX} -X ${ORG_PATH}/${PROJ}/version.GitCommit=${GIT_COMMIT} -X ${ORG_PATH}/${PROJ}/version.GitTreeState=${GIT_TREE_STATE} -X ${ORG_PATH}/${PROJ}/version.BuildDate=${BUILD_DATE}"
.PHONY: default
default: test
@@ -145,6 +147,11 @@ frontend: buf
cd internal/frontend/holos && ng build
touch internal/frontend/frontend.go
.PHONY: image
image: build ## Docker image build
docker build . -t ${DOCKER_REPO}:v$(shell ./bin/holos --version)
docker push ${DOCKER_REPO}:v$(shell ./bin/holos --version)
.PHONY: help
help: ## Display this help menu.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

View File

@@ -16,6 +16,10 @@ type BuildPlan struct {
type BuildPlanSpec struct {
Disabled bool `json:"disabled,omitempty" yaml:"disabled,omitempty"`
Components BuildPlanComponents `json:"components,omitempty" yaml:"components,omitempty"`
// DeployFiles keys represent file paths relative to the cluster deploy
// directory. Map values represent the string encoded file contents. Used to
// write the argocd Application, but may be used to render any file from CUE.
DeployFiles FileContentMap `json:"deployFiles,omitempty" yaml:"deployFiles,omitempty"`
}
type BuildPlanComponents struct {

View File

@@ -20,3 +20,11 @@ type HolosComponent struct {
func (hc *HolosComponent) NewResult() *Result {
return &Result{HolosComponent: *hc}
}
func (hc *HolosComponent) GetAPIVersion() string {
return hc.APIVersion
}
func (hc *HolosComponent) GetKind() string {
return hc.Kind
}

View File

@@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"strings"
"syscall"
"github.com/holos-run/holos"
"github.com/holos-run/holos/internal/errors"
@@ -121,6 +122,14 @@ func (hc *HelmChart) helm(ctx context.Context, r *Result, path holos.InstancePat
}
// cacheChart stores a cached copy of Chart in the chart subdirectory of path.
//
// It is assumed that the only method responsible for writing to chartDir is
// cacheChart itself.
//
// This relies on the atomicity of moving temporary directories into place on
// the same filesystem via os.Rename. If a syscall.EEXIST error occurs during
// renaming, it indicates that the cached chart already exists, which is an
// expected scenario when this function is called concurrently.
func cacheChart(ctx context.Context, path holos.InstancePath, chartDir string, chart Chart) error {
log := logger.FromContext(ctx)
@@ -156,11 +165,16 @@ func cacheChart(ctx context.Context, path holos.InstancePath, chartDir string, c
dst := filepath.Join(cachePath, item.Name())
log.DebugContext(ctx, "rename", "src", src, "dst", dst)
if err := os.Rename(src, dst); err != nil {
return errors.Wrap(fmt.Errorf("could not rename: %w", err))
var linkErr *os.LinkError
if errors.As(err, &linkErr) && errors.Is(linkErr.Err, syscall.EEXIST) {
log.DebugContext(ctx, "cache already exists", "chart", chart.Name, "chart_version", chart.Version, "path", cachePath)
} else {
return errors.Wrap(fmt.Errorf("could not rename: %w", err))
}
}
}
log.InfoContext(ctx, "cached", "chart", chart.Name, "version", chart.Version, "path", cachePath)
log.InfoContext(ctx, "cached", "chart", chart.Name, "chart_version", chart.Version, "path", cachePath)
return nil
}

View File

@@ -17,6 +17,10 @@ type Result struct {
HolosComponent
// accumulatedOutput accumulates rendered api objects.
accumulatedOutput string
// DeployFiles keys represent file paths relative to the cluster deploy
// directory. Map values represent the string encoded file contents. Used to
// write the argocd Application, but may be used to render any file from CUE.
DeployFiles FileContentMap `json:"deployFiles,omitempty" yaml:"deployFiles,omitempty"`
}
// Continue returns true if Skip is true indicating the result is to be skipped over.
@@ -133,6 +137,21 @@ func (r *Result) kustomize(ctx context.Context) error {
return nil
}
func (r *Result) WriteDeployFiles(ctx context.Context, path string) error {
log := logger.FromContext(ctx)
if len(r.DeployFiles) == 0 {
return nil
}
for k, content := range r.DeployFiles {
path := filepath.Join(path, k)
if err := r.Save(ctx, path, content); err != nil {
return errors.Wrap(err)
}
log.InfoContext(ctx, "wrote deploy file", "path", path, "bytes", len(content))
}
return nil
}
// Save writes the content to the filesystem for git ops.
func (r *Result) Save(ctx context.Context, path string, content string) error {
log := logger.FromContext(ctx)
@@ -141,7 +160,7 @@ func (r *Result) Save(ctx context.Context, path string, content string) error {
log.WarnContext(ctx, "could not mkdir", "path", dir, "err", err)
return errors.Wrap(err)
}
// Write the kube api objects
// Write the file content
if err := os.WriteFile(path, []byte(content), os.FileMode(0644)); err != nil {
log.WarnContext(ctx, "could not write", "path", path, "err", err)
return errors.Wrap(err)

View File

@@ -0,0 +1,3 @@
package holos
_platform_config: string @tag(platform_config, type=string)

View File

@@ -0,0 +1 @@
{}

14
docs/runbooks/argocd.md Normal file
View File

@@ -0,0 +1,14 @@
# ArgoCD
Create the deploy key secret in the management cluster.
```bash
tmp="$(mktemp -d)"
(cd $tmp && ssh-keygen -t ed25519 -f sshPrivateKey -m pem -C argocd -N '')
echo git@github.com:holos-run/holos-infra.git > "${tmp}/url"
holos create secret -n argocd --append-hash=false creds-holos-infra --from-file $tmp
rm -rf "$tmp"
```
When syncing the secret, the ExternalSecret needs to set the label
`argocd.argoproj.io/secret-type: repo-creds`.

View File

@@ -0,0 +1,97 @@
# PostgresCluster Backups
This document describes how the S3 bucket for `PostgresCluster` backups is configured. These buckets are configured both for ZITADEL and for Holos
Server and are applicable to any service in Holos that stores data in a pgo `PostgresCluster` resource.
## Create the Bucket
Name: `holos-zitadel-backups` for `zitadel`
Name: `holos-server-backups` for `holos server`
> [!NOTE]
> The settings below match the default settings recommended by AWS.
Object Ownership: `ACLs disabled` (recommended) Checked.
Block Public Access settings for this bucket: **`Block all public access`** Checked.
Bucket Versioning: `Disable`
Default encryption: `Server-side encryption with Amazon S3 managed keys (SSE-S3)`
Bucket Key: `Enable`
Object Lock: `Disable`
## Create an IAM Policy
Create one IAM Policy for each bucket to grant full access to the bucket. Replace the resource with each bucket name.
Name: `holos-zitadel-backups` for `zitadel`
Name: `holos-server-backups` for `holos server`
Description: `Read and write access to a specific bucket for pgrest operating within a pgo PostgresCluster.`
Policy JSON:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::holos-zitadel-backups",
"arn:aws:s3:::holos-zitadel-backups/*"
]
}
]
}
```
## Create an IAM Group
Create an IAM Group to attach the policy granting access to the bucket.
Name: `holos-zitadel-backups` for `zitadel`
Attach permission policies: `holos-zitadel-backups`
Name: `holos-server-backups` for `holos server`
Attach permission policies: `holos-server-backups`
## Create the IAM User
Create an IAM User entity for each PostgresCluster. Do not provide user access to the AWS Management Console.
Name: `holos-zitadel-backups` for `zitadel`
Group: `holos-zitadel-backups`
Name: `holos-server-backups` for `holos server`
Group: `holos-server-backups`
## Create an Access Key
Create an access key for `pgbackrest` associated with the `PostgresCluster`.
Description:
> Used by pgbackrest associated with the PostgresCluster resource. Refer to the PostgresCluster resource pgbackrest.cofiguration.secret.name for the stored location of the access key. Synced from the Management Cluster using an ExternalSecret.
## Create the Secret
Create a `Secret` in the holos management cluster usable by pgbackrest. This is a secret with a single key, `s3.conf` with the following format:
```
[global]
repo2-cipher-pass=
repo2-s3-key=
repo2-s3-key-secret=
repo3-cipher-pass=
repo3-s3-key=
repo3-s3-key-secret=
```
> [!NOTE]
> Use the same values for repo2 and repo3. The purpose is to make space for migrating if need be in the future.
Generate the cipher pass using. This password is used to encrypt all backups using client side before the backup is written to the bucket.
```
tr -dc A-Za-z0-9 </dev/urandom | head -c 64
```
Store the secret into the management cluster:
```
holos create secret --namespace zitadel holos-zitadel-backups \
--append-hash=false --from-file .
```
```
holos create secret --namespace holos holos-server-backups \
--append-hash=false --from-file .
```

View File

@@ -0,0 +1,30 @@
# Namespaces
Holos follows the [Namespace Sameness - Sig Multicluster Position][1]. A
namespace is the same on all clusters within the scope of a platform.
Namespaces are also security boundaries for role based access control. As such,
permission to read a secret in a namespace means the secret is readable on all
clusters in the platform.
When adding a component to a platform, create a namespace using the following
process. This ensures a namespace scoped `SecretStore` is created to sync
`ExternalSecret` resources from the management cluster.
1. Add a new project to the `_Projects` struct in `platform.cue`.
2. Add the namespace to the `spec.namespaces` field of the project.
3. Render the platform
4. Apply the `namespaces` component to the management cluster
5. Apply the `eso-creds-manager` component to the management cluster to create the `eso-reader` ksa for the namespace `SecretStore`
6. Get a timestamp: `STAMP="$(date +%s)"`
7. Run the job to populate ecr creds: `kubectl create job -n holos-system --from=cronjob/ecr-creds-manager ecr-creds-manager-$STAMP`
8. Wait for the job to complete: `kubectl -n holos-system logs -l job-name=ecr-creds-manager-$STAMP -f`
9. Apply the `namespaces` component to the workload clusters
10. On the workload cluster, run the job to fetch the eso-reader creds: `kubectl create job -n holos-system --from=cronjob/eso-creds-refresher eso-creds-refresher-${STAMP}`
11. Wait for the job to complete: `kubectl -n holos-system logs -l job-name=eso-creds-refresher-${STAMP}`
12. Apply the secretstores component to the workload cluster.
13. Apply any other cluster specific components which were modified by the `holos render platform ./platform` command.
Your namespace is created and you have the ability to create secrets in the management cluster and pull them using ExternalSecret resources. (edited)
[1]: https://github.com/kubernetes/community/blob/dd4c8b704ef1c9c3bfd928c6fa9234276d61ad18/sig-multicluster/namespace-sameness-position-statement.md

View File

@@ -0,0 +1,31 @@
# Workload Identity
When a new workload cluster is provisioned, allow it to access the Management
Cluster using workload identity. This is necessary for the
`eso-creds-refresher` component and `Job` that executes in each workload
cluster, which in turn enables the `SecretStore` in each namespace to sync
secrets.
Build the cluster with Cluster API.
See https://github.com/holos-run/holos-infra/blob/main/hack/capi/eks/aws2/aws2-managedmachinepool.yaml#L81-L84
## Workload Identity Provider
Add the Cluster as a workload identity provider to the `holos-ops` gcp project.
Pool: [holos](https://console.cloud.google.com/iam-admin/workload-identity-pools/pool/holos?organizationId=358674006047&project=holos-ops)
Name: `k8s-aws1`, `k8s-aws2`, etc...
### Issuer URL:
```
kubectl create -n default token default | cut -d. -f2 | base64 -d | jq -r .iss
```
### Audience
Use the default audience.
### Attribute Mapping
| Google | OIDC |
| -------------------------------- | ------------------------------------------------------ |
| `google.subject` | `assertion.sub` |
| `attribute.service_account_name` | `assertion['kubernetes.io']['serviceaccount']['name']` |
| `attribute.uid` | `assertion['kubernetes.io']['serviceaccount']['uid']` |
| `attribute.pod` | `assertion['kubernetes.io']['pod']['name']` |

View File

@@ -10,6 +10,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/cuecontext"
@@ -91,7 +92,18 @@ func (b *Builder) Instances(ctx context.Context, cfg *client.Config) ([]*build.I
if err != nil {
return nil, errors.Wrap(err)
}
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
cueConfig.Tags = append(cueConfig.Tags, "platform_config="+string(data))
if b.Cluster() != "" {
cueConfig.Tags = append(cueConfig.Tags, "cluster="+b.Cluster())
}
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cueConfig.Tags))
prefix := []string{"cue", "export", "--out", "yaml"}
for _, tag := range cueConfig.Tags {
prefix = append(prefix, "-t", fmt.Sprintf("'%s'", tag))
}
// Make args relative to the module directory
args := make([]string, len(b.cfg.args))
@@ -106,15 +118,12 @@ func (b *Builder) Instances(ctx context.Context, cfg *client.Config) ([]*build.I
}
relPath = "./" + relPath
args[idx] = relPath
equiv := fmt.Sprintf("cue export --out yaml -t cluster=%v %v", b.Cluster(), relPath)
log.Debug("cue: equivalent command: " + equiv)
}
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
if b.Cluster() != "" {
cueConfig.Tags = append(cueConfig.Tags, "cluster="+b.Cluster())
equiv := make([]string, len(prefix), 1+len(prefix))
copy(equiv, prefix)
equiv = append(equiv, relPath)
log.Debug(strings.Join(equiv, " "), "comment", "cue equivalent command")
}
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cueConfig.Tags))
return load.Instances(args, &cueConfig), nil
}
@@ -175,6 +184,10 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
// New decoder for the full object
decoder = json.NewDecoder(bytes.NewReader(jsonBytes))
// TODO: When we release v1, explicitly allow unknown fields so we can add
// fields without needing to bump the major version. Disallow until we reach
// v1 for clear error reporting.
decoder.DisallowUnknownFields()
switch tm.Kind {
@@ -186,11 +199,14 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
return
}
results, err = b.buildPlan(ctx, &bp, path)
if err != nil {
return results, err
}
default:
err = errors.Wrap(fmt.Errorf("unknown kind: %v", tm.Kind))
}
return
return results, err
}
func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha1.BuildPlan, path holos.InstancePath) (results []*v1alpha1.Result, err error) {
@@ -239,6 +255,17 @@ func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha1.BuildPlan,
}
}
// Add a separate Result if there are DeployFiles from the BuildPlan.
if len(buildPlan.Spec.DeployFiles) > 0 {
results = append(results, &v1alpha1.Result{
HolosComponent: v1alpha1.HolosComponent{
TypeMeta: buildPlan.TypeMeta,
Metadata: buildPlan.Metadata,
},
DeployFiles: buildPlan.Spec.DeployFiles,
})
}
log.DebugContext(ctx, "returning results", "len", len(results))
return results, nil

View File

@@ -10,6 +10,7 @@ import (
"github.com/holos-run/holos/internal/client"
"github.com/holos-run/holos/internal/errors"
"github.com/holos-run/holos/internal/holos"
"github.com/holos-run/holos/internal/server/middleware/logger"
"github.com/spf13/cobra"
)
@@ -17,6 +18,7 @@ import (
func makeBuildRunFunc(cfg *client.Config) command.RunFunc {
return func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
logger.FromContext(ctx).DebugContext(ctx, "RunE", "args", args)
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.Holos().ClusterName()))
results, err := build.Run(ctx, cfg)
if err != nil {

View File

@@ -3,21 +3,52 @@ package create
import (
"github.com/holos-run/holos/internal/cli/command"
"github.com/holos-run/holos/internal/cli/secret"
"github.com/holos-run/holos/internal/client"
"github.com/holos-run/holos/internal/holos"
"github.com/holos-run/holos/internal/server/middleware/logger"
"github.com/spf13/cobra"
)
// New returns the create command for the cli
func New(hc *holos.Config) *cobra.Command {
func New(cfg *holos.Config) *cobra.Command {
cmd := command.New("create")
cmd.Short = "create resources"
cmd.Flags().SortFlags = false
cmd.RunE = func(c *cobra.Command, args []string) error {
return c.Usage()
}
// api client config
config := client.NewConfig(cfg)
// flags
cmd.PersistentFlags().SortFlags = false
// commands
cmd.AddCommand(secret.NewCreateCmd(hc))
cmd.AddCommand(secret.NewCreateCmd(cfg))
cmd.AddCommand(NewPlatform(config))
return cmd
}
func NewPlatform(cfg *client.Config) *cobra.Command {
cmd := command.New("platform")
cmd.Short = "create a platform"
cmd.Args = cobra.NoArgs
pm := client.PlatformMutation{}
cmd.Flags().AddGoFlagSet(pm.FlagSet())
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
client := client.New(cfg)
pf, err := client.CreatePlatform(ctx, pm)
if err != nil {
return err
}
log := logger.FromContext(ctx)
log.InfoContext(ctx, "created platform", "name", pf.GetName(), "id", pf.GetId(), "org", pf.GetOwner().GetOrgId())
return nil
}
return cmd
}

View File

@@ -2,6 +2,8 @@ package generate
import (
"fmt"
"log/slog"
"path/filepath"
"strings"
"github.com/holos-run/holos/internal/cli/command"
@@ -41,6 +43,7 @@ func NewPlatform(cfg *holos.Config) *cobra.Command {
return errors.Wrap(err)
}
}
return nil
}
@@ -53,33 +56,47 @@ func NewComponent() *cobra.Command {
cmd.Short = "generate a component from an embedded schematic"
cmd.AddCommand(NewCueComponent())
cmd.AddCommand(NewHelmComponent())
return cmd
}
func NewHelmComponent() *cobra.Command {
cmd := command.New("helm")
cmd.Short = "generate a helm component from a schematic"
for _, name := range generate.HelmComponents() {
cmd.AddCommand(makeSchematicCommand("helm", name))
}
return cmd
}
func NewCueComponent() *cobra.Command {
cmd := command.New("cue")
cmd.Short = "generate a cue component from an embedded schematic"
cmd.Short = "generate a cue component from a schematic"
components := generate.CueComponents()
cmd.Long = fmt.Sprintf("Embedded cue components available to generate:\n\n %s", strings.Join(components, "\n "))
for _, name := range components {
cmd.AddCommand(makeCueCommand(name))
for _, name := range generate.CueComponents() {
cmd.AddCommand(makeSchematicCommand("cue", name))
}
return cmd
}
func makeCueCommand(name string) *cobra.Command {
func makeSchematicCommand(kind, name string) *cobra.Command {
cmd := command.New(name)
cmd.Short = fmt.Sprintf("generate a %s cue component from an embedded schematic", name)
cfg, err := generate.NewSchematic(filepath.Join("components", kind), name)
if err != nil {
slog.Error("could not get schematic", "err", err)
return nil
}
cmd.Short = cfg.Short
cmd.Long = cfg.Long
cmd.Args = cobra.NoArgs
cfg := &generate.CueConfig{}
cmd.Flags().AddGoFlagSet(cfg.FlagSet())
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
if err := generate.GenerateCueComponent(ctx, name, cfg); err != nil {
if err := generate.GenerateComponent(ctx, kind, name, cfg); err != nil {
return errors.Wrap(err)
}
return nil

View File

@@ -38,8 +38,9 @@ func NewPlatform(cfg *client.Config) *cobra.Command {
}
func NewPlatformConfig(cfg *client.Config) *cobra.Command {
cmd := command.New("config")
cmd.Short = "pull platform config"
cmd := command.New("model")
cmd.Aliases = []string{"config"}
cmd.Short = "pull platform model"
cmd.Args = cobra.MinimumNArgs(1)
cmd.RunE = func(cmd *cobra.Command, args []string) error {

View File

@@ -35,7 +35,7 @@ func NewPlatform(cfg *client.Config) *cobra.Command {
cmd.Args = cobra.NoArgs
cmd.AddCommand(NewPlatformForm(cfg))
// cmd.AddCommand(NewPlatformModel(cfg))
cmd.AddCommand(NewPlatformModel(cfg))
return cmd
}
@@ -74,3 +74,34 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
return cmd
}
func NewPlatformModel(cfg *client.Config) *cobra.Command {
cmd := command.New("model")
cmd.Short = "push platform model to holos server"
cmd.Args = cobra.MinimumNArgs(1)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
if ctx == nil {
return errors.Wrap(errors.New("cannot execute: no context"))
}
ctx = logger.NewContext(ctx, logger.FromContext(ctx).With("server", cfg.Client().Server()))
rpc := client.New(cfg)
for _, name := range args {
// Get the platform config for the platform id.
p, err := client.LoadPlatformConfig(ctx, name)
if err != nil {
return errors.Wrap(err)
}
// Make the rpc call to update the platform form.
if err := rpc.UpdatePlatformModel(ctx, p.PlatformId, p.PlatformModel); err != nil {
return errors.Wrap(err)
}
slog.Default().InfoContext(ctx, fmt.Sprintf("pushed: %s/ui/platform/%s", cfg.Client().Server(), p.PlatformId))
}
return nil
}
return cmd
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"flag"
"fmt"
"runtime"
"github.com/holos-run/holos/internal/builder"
"github.com/holos-run/holos/internal/cli/command"
@@ -43,7 +44,6 @@ func NewComponent(cfg *holos.Config) *cobra.Command {
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
log := logger.FromContext(ctx).With("cluster", cfg.ClusterName())
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
if printInstances {
@@ -67,20 +67,38 @@ func NewComponent(cfg *holos.Config) *cobra.Command {
// place.
var result Result
for _, result = range results {
log := logger.FromContext(ctx).With(
"cluster", cfg.ClusterName(),
"name", result.Name(),
)
if result.Continue() {
continue
}
// DeployFiles from the BuildPlan
if err := result.WriteDeployFiles(ctx, cfg.WriteTo()); err != nil {
return errors.Wrap(err)
}
// Build plans don't have anything but DeployFiles to write.
if result.GetKind() == "BuildPlan" {
continue
}
// API Objects
path := result.Filename(cfg.WriteTo(), cfg.ClusterName())
if err := result.Save(ctx, path, result.AccumulatedOutput()); err != nil {
return errors.Wrap(err)
}
// Kustomization
path = result.KustomizationFilename(cfg.WriteTo(), cfg.ClusterName())
if err := result.Save(ctx, path, result.KustomizationContent()); err != nil {
return errors.Wrap(err)
if result.KustomizationContent() == "" {
log.DebugContext(ctx, "flux kustomization: skipped "+result.Name(), "status", "ok", "action", "skipped")
} else {
path = result.KustomizationFilename(cfg.WriteTo(), cfg.ClusterName())
if err := result.Save(ctx, path, result.KustomizationContent()); err != nil {
return errors.Wrap(err)
}
}
log.InfoContext(ctx, "rendered "+result.Name(), "status", "ok", "action", "rendered", "name", result.Name())
log.InfoContext(ctx, "rendered "+result.Name(), "status", "ok", "action", "rendered")
}
return nil
}
@@ -96,6 +114,9 @@ func NewPlatform(cfg *holos.Config) *cobra.Command {
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
var concurrency int
cmd.Flags().IntVar(&concurrency, "concurrency", min(runtime.NumCPU(), 8), "Number of concurrent components to render")
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
build := builder.New(builder.Entrypoints(args))
@@ -105,7 +126,7 @@ func NewPlatform(cfg *holos.Config) *cobra.Command {
return errors.Wrap(err)
}
return render.Platform(ctx, platform, cmd.ErrOrStderr())
return render.Platform(ctx, concurrency, platform, cmd.ErrOrStderr())
}
return cmd
@@ -119,4 +140,7 @@ type Result interface {
Save(ctx context.Context, path string, content string) error
AccumulatedOutput() string
KustomizationContent() string
WriteDeployFiles(ctx context.Context, writeTo string) error
GetKind() string
GetAPIVersion() string
}

View File

@@ -36,7 +36,7 @@ func New(cfg *holos.Config) *cobra.Command {
rootCmd := &cobra.Command{
Use: "holos",
Short: "holos manages a holistic integrated software development platform",
Version: version.Version,
Version: version.GetVersion(),
Args: cobra.NoArgs,
CompletionOptions: cobra.CompletionOptions{
HiddenDefaultCmd: true, // Don't complete the complete subcommand itself

View File

@@ -3,6 +3,7 @@ package client
import (
"context"
"flag"
"time"
"connectrpc.com/connect"
@@ -18,6 +19,26 @@ import (
"google.golang.org/protobuf/types/known/structpb"
)
type PlatformMutation struct {
Name string
DisplayName string
flagSet *flag.FlagSet
}
func (pm *PlatformMutation) FlagSet() *flag.FlagSet {
if pm == nil {
return nil
}
if pm.flagSet != nil {
return pm.flagSet
}
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.StringVar(&pm.Name, "name", "example", "platform name")
fs.StringVar(&pm.DisplayName, "display-name", "Example Platform", "platform display name")
pm.flagSet = fs
return fs
}
func New(cfg *Config) *Client {
t := token.NewClient(cfg.Token())
s := cfg.Client().Server()
@@ -57,7 +78,8 @@ func (c *Client) Platforms(ctx context.Context, orgID string) ([]*platform.Platf
func (c *Client) UpdateForm(ctx context.Context, platformID string, form *object.Form) error {
start := time.Now()
req := &platform.UpdatePlatformRequest{
Update: &platform.UpdatePlatformOperation{PlatformId: platformID, Form: form},
PlatformId: platformID,
Update: &platform.PlatformMutation{Form: form},
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"form"}},
}
_, err := c.pltSvc.UpdatePlatform(ctx, connect.NewRequest(req))
@@ -69,6 +91,22 @@ func (c *Client) UpdateForm(ctx context.Context, platformID string, form *object
return nil
}
func (c *Client) UpdatePlatformModel(ctx context.Context, platformID string, model *structpb.Struct) error {
start := time.Now()
req := &platform.UpdatePlatformRequest{
PlatformId: platformID,
Update: &platform.PlatformMutation{Model: model},
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"model"}},
}
_, err := c.pltSvc.UpdatePlatform(ctx, connect.NewRequest(req))
if err != nil {
return errors.Wrap(err)
}
log := logger.FromContext(ctx)
log.DebugContext(ctx, "updated platform", "platform_id", platformID, "duration", time.Since(start))
return nil
}
// PlatformModel gets the platform model from the PlatformService.
func (c *Client) PlatformModel(ctx context.Context, platformID string) (*structpb.Struct, error) {
start := time.Now()
@@ -84,3 +122,22 @@ func (c *Client) PlatformModel(ctx context.Context, platformID string) (*structp
log.DebugContext(ctx, "get platform", "platform_id", platformID, "duration", time.Since(start))
return pf.Msg.GetPlatform().GetSpec().GetModel(), nil
}
func (c *Client) CreatePlatform(ctx context.Context, pm PlatformMutation) (*platform.Platform, error) {
log := logger.FromContext(ctx).With("platform", pm.Name)
start := time.Now()
req := &platform.CreatePlatformRequest{
OrgId: c.cfg.context.OrgID,
Create: &platform.PlatformMutation{
Name: &pm.Name,
DisplayName: &pm.DisplayName,
},
}
pf, err := c.pltSvc.CreatePlatform(ctx, connect.NewRequest(req))
if err != nil {
return nil, errors.Wrap(err)
}
log = log.With("platform_id", pf.Msg.GetPlatform().GetId())
log.DebugContext(ctx, "create platform", "duration", time.Since(start))
return pf.Msg.GetPlatform(), nil
}

View File

@@ -52,7 +52,8 @@ func LoadPlatformConfig(ctx context.Context, name string) (*object.PlatformConfi
// SavePlatformConfig writes pc to the platform root directory path identified by name.
func SavePlatformConfig(ctx context.Context, name string, pc *object.PlatformConfig) (string, error) {
data, err := protojson.Marshal(pc)
encoder := protojson.MarshalOptions{Multiline: true}
data, err := encoder.Marshal(pc)
if err != nil {
return "", err
}

File diff suppressed because it is too large Load Diff

View File

@@ -21,9 +21,9 @@
"@angular/platform-browser": "^17.3.0",
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"@bufbuild/protobuf": "^1.9.0",
"@bufbuild/protobuf": "^1.10.0",
"@connectrpc/connect": "^1.4.0",
"@connectrpc/connect-query": "^1.4.0",
"@connectrpc/connect-query": "^1.4.1",
"@connectrpc/connect-web": "^1.4.0",
"@ngx-formly/core": "^6.3.0",
"@ngx-formly/material": "^6.3.0",
@@ -40,10 +40,10 @@
"@angular-eslint/template-parser": "17.3.0",
"@angular/cli": "^17.3.4",
"@angular/compiler-cli": "^17.3.0",
"@bufbuild/buf": "^1.32.0",
"@bufbuild/protoc-gen-es": "^1.9.0",
"@bufbuild/buf": "^1.32.2",
"@bufbuild/protoc-gen-es": "^1.10.0",
"@connectrpc/protoc-gen-connect-es": "^1.4.0",
"@connectrpc/protoc-gen-connect-query": "^1.4.0",
"@connectrpc/protoc-gen-connect-query": "^1.4.1",
"@ngx-formly/schematics": "^6.3.0",
"@types/jasmine": "~5.1.0",
"@typescript-eslint/eslint-plugin": "7.2.0",

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/object/v1alpha1/object.proto (package holos.object.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/organization/v1alpha1/organization.proto (package holos.organization.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/organization/v1alpha1/organization_service.proto (package holos.organization.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/platform/v1alpha1/platform.proto (package holos.platform.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/platform/v1alpha1/platform_service.proto (package holos.platform.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
@@ -13,9 +13,14 @@ import { Form } from "../../object/v1alpha1/object_pb.js";
*/
export class CreatePlatformRequest extends Message<CreatePlatformRequest> {
/**
* @generated from field: holos.platform.v1alpha1.Platform platform = 1;
* @generated from field: string org_id = 1;
*/
platform?: Platform;
orgId = "";
/**
* @generated from field: holos.platform.v1alpha1.PlatformMutation create = 2;
*/
create?: PlatformMutation;
constructor(data?: PartialMessage<CreatePlatformRequest>) {
super();
@@ -25,7 +30,8 @@ export class CreatePlatformRequest extends Message<CreatePlatformRequest> {
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.CreatePlatformRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform", kind: "message", T: Platform },
{ no: 1, name: "org_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "create", kind: "message", T: PlatformMutation },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreatePlatformRequest {
@@ -168,20 +174,27 @@ export class GetPlatformResponse extends Message<GetPlatformResponse> {
* @generated from message holos.platform.v1alpha1.UpdatePlatformRequest
*/
export class UpdatePlatformRequest extends Message<UpdatePlatformRequest> {
/**
* Platform UUID to update.
*
* @generated from field: string platform_id = 1;
*/
platformId = "";
/**
* Update operations to perform. Fields are set to the provided value if
* selected by the mask. Absent fields are cleared if they are selected by
* the mask.
*
* @generated from field: holos.platform.v1alpha1.UpdatePlatformOperation update = 1;
* @generated from field: holos.platform.v1alpha1.PlatformMutation update = 2;
*/
update?: UpdatePlatformOperation;
update?: PlatformMutation;
/**
* FieldMask represents the mutation operations to perform. Marked optional
* for the nil guard check. Required.
*
* @generated from field: optional google.protobuf.FieldMask update_mask = 2;
* @generated from field: optional google.protobuf.FieldMask update_mask = 3;
*/
updateMask?: FieldMask;
@@ -193,8 +206,9 @@ export class UpdatePlatformRequest extends Message<UpdatePlatformRequest> {
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.UpdatePlatformRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "update", kind: "message", T: UpdatePlatformOperation },
{ no: 2, name: "update_mask", kind: "message", T: FieldMask, opt: true },
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "update", kind: "message", T: PlatformMutation },
{ no: 3, name: "update_mask", kind: "message", T: FieldMask, opt: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UpdatePlatformRequest {
@@ -334,16 +348,11 @@ export class ListPlatformsResponse extends Message<ListPlatformsResponse> {
}
/**
* @generated from message holos.platform.v1alpha1.UpdatePlatformOperation
* PlatformMutation represents the fields to create or update.
*
* @generated from message holos.platform.v1alpha1.PlatformMutation
*/
export class UpdatePlatformOperation extends Message<UpdatePlatformOperation> {
/**
* Platform UUID to update.
*
* @generated from field: string platform_id = 1;
*/
platformId = "";
export class PlatformMutation extends Message<PlatformMutation> {
/**
* Update the platform name.
*
@@ -372,35 +381,34 @@ export class UpdatePlatformOperation extends Message<UpdatePlatformOperation> {
*/
form?: Form;
constructor(data?: PartialMessage<UpdatePlatformOperation>) {
constructor(data?: PartialMessage<PlatformMutation>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.UpdatePlatformOperation";
static readonly typeName = "holos.platform.v1alpha1.PlatformMutation";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
{ no: 3, name: "display_name", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
{ no: 4, name: "model", kind: "message", T: Struct, opt: true },
{ no: 5, name: "form", kind: "message", T: Form, opt: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UpdatePlatformOperation {
return new UpdatePlatformOperation().fromBinary(bytes, options);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PlatformMutation {
return new PlatformMutation().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): UpdatePlatformOperation {
return new UpdatePlatformOperation().fromJson(jsonValue, options);
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PlatformMutation {
return new PlatformMutation().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): UpdatePlatformOperation {
return new UpdatePlatformOperation().fromJsonString(jsonString, options);
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PlatformMutation {
return new PlatformMutation().fromJsonString(jsonString, options);
}
static equals(a: UpdatePlatformOperation | PlainMessage<UpdatePlatformOperation> | undefined, b: UpdatePlatformOperation | PlainMessage<UpdatePlatformOperation> | undefined): boolean {
return proto3.util.equals(UpdatePlatformOperation, a, b);
static equals(a: PlatformMutation | PlainMessage<PlatformMutation> | undefined, b: PlatformMutation | PlainMessage<PlatformMutation> | undefined): boolean {
return proto3.util.equals(PlatformMutation, a, b);
}
}

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/storage/v1alpha1/storage.proto (package holos.storage.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/system/v1alpha1/system.proto (package holos.system.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/system/v1alpha1/system_service.proto (package holos.system.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/user/v1alpha1/user.proto (package holos.user.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -1,4 +1,4 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file holos/user/v1alpha1/user_service.proto (package holos.user.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck

View File

@@ -5,7 +5,7 @@ import { ObservableClient } from '../../connect/observable-client';
import { Organization } from '../gen/holos/organization/v1alpha1/organization_pb';
import { Platform } from '../gen/holos/platform/v1alpha1/platform_pb';
import { PlatformService as ConnectPlatformService } from '../gen/holos/platform/v1alpha1/platform_service_connect';
import { GetPlatformRequest, ListPlatformsRequest, UpdatePlatformOperation, UpdatePlatformRequest } from '../gen/holos/platform/v1alpha1/platform_service_pb';
import { GetPlatformRequest, ListPlatformsRequest, PlatformMutation, UpdatePlatformRequest } from '../gen/holos/platform/v1alpha1/platform_service_pb';
@Injectable({
providedIn: 'root'
@@ -26,9 +26,9 @@ export class PlatformService {
}
updateModel(platformId: string, model: JsonValue): Observable<Platform | undefined> {
const update = new UpdatePlatformOperation({ platformId: platformId, model: Struct.fromJson(model) })
const update = new PlatformMutation({ model: Struct.fromJson(model) })
const updateMask = new FieldMask({ paths: ["model"] })
const req = new UpdatePlatformRequest({ update: update, updateMask: updateMask })
const req = new UpdatePlatformRequest({ platformId: platformId, update: update, updateMask: updateMask })
return this.client.updatePlatform(req).pipe(
switchMap(resp => { return of(resp.platform) })
)

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"embed"
"encoding/json"
"flag"
"io/fs"
"log/slog"
@@ -21,22 +22,62 @@ var components embed.FS
// componentsRoot is the root path to copy component cue code from.
const componentsRoot = "components"
// CueConfig represents the config values passed to cue go templates.
type CueConfig struct {
ComponentName string
flagSet *flag.FlagSet
func NewSchematic(root string, name string) (*Schematic, error) {
data, err := components.ReadFile(filepath.Join(root, name, "schematic.json"))
if err != nil {
return nil, errors.Wrap(err)
}
schematic := Schematic{Name: name}
if err := json.Unmarshal(data, &schematic); err != nil {
return nil, errors.Wrap(err)
}
return &schematic, nil
}
func (c *CueConfig) FlagSet() *flag.FlagSet {
if c == nil {
// Schematic represents the flags and command metadata stored in the
// schematic.yaml file along side each schematic.
type Schematic struct {
// Name represents the name of the resource the schematic generates.
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Short string `json:"short,omitempty" yaml:"short,omitempty"`
Long string `json:"long,omitempty" yaml:"long,omitempty"`
Chart *string `json:"chart,omitempty" yaml:"chart,omitempty"`
Version *string `json:"version,omitempty" yaml:"version,omitempty"`
Namespace *string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
RepoName *string `json:"reponame,omitempty" yaml:"reponame,omitempty"`
RepoURL *string `json:"repourl,omitempty" yaml:"repourl,omitempty"`
flagSet *flag.FlagSet
}
func (s *Schematic) FlagSet() *flag.FlagSet {
if s == nil {
return nil
}
if c.flagSet != nil {
return c.flagSet
if s.flagSet != nil {
return s.flagSet
}
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.StringVar(&c.ComponentName, "name", "example", "component name")
c.flagSet = fs
fs.StringVar(&s.Name, "name", s.Name, "component name")
if s.Chart != nil {
fs.StringVar(s.Chart, "chart", *s.Chart, "chart name")
}
if s.Version != nil {
fs.StringVar(s.Version, "component-version", *s.Version, "component version")
}
if s.Namespace != nil {
fs.StringVar(s.Namespace, "namespace", *s.Namespace, "namespace")
}
if s.RepoName != nil {
fs.StringVar(s.RepoName, "repo-name", *s.RepoName, "chart repository name")
}
if s.RepoURL != nil {
fs.StringVar(s.RepoURL, "repo-url", *s.RepoURL, "chart repository url")
}
s.flagSet = fs
return fs
}
@@ -53,8 +94,21 @@ func CueComponents() []string {
return dirs
}
// HelmComponents returns a slice of embedded component schematics or nil if there are none.
func HelmComponents() []string {
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "helm"))
if err != nil {
return nil
}
dirs := make([]string, 0, len(entries))
for _, entry := range entries {
dirs = append(dirs, entry.Name())
}
return dirs
}
// makeRenderFunc makes a template rendering function for embedded files.
func makeRenderFunc(log *slog.Logger, path string, cfg *CueConfig) func([]byte) *bytes.Buffer {
func makeRenderFunc[T any](log *slog.Logger, path string, cfg T) func([]byte) *bytes.Buffer {
return func(content []byte) *bytes.Buffer {
tmpl, err := template.New(filepath.Base(path)).Parse(string(content))
if err != nil {
@@ -72,12 +126,14 @@ func makeRenderFunc(log *slog.Logger, path string, cfg *CueConfig) func([]byte)
}
}
// GenerateCueComponent writes the cue code for a component to the local working
// GenerateComponent writes the cue code for a component to the local working
// directory.
func GenerateCueComponent(ctx context.Context, name string, cfg *CueConfig) error {
path := filepath.Join(componentsRoot, "cue", name)
dstPath := filepath.Join(getCwd(ctx), cfg.ComponentName)
log := logger.FromContext(ctx).With("name", cfg.ComponentName, "path", dstPath)
func GenerateComponent(ctx context.Context, kind string, name string, cfg *Schematic) error {
// use name from args to build the source path
path := filepath.Join(componentsRoot, kind, name)
// use cfg.Name from flags to build the destination path
dstPath := filepath.Join(getCwd(ctx), cfg.Name)
log := logger.FromContext(ctx).With("name", cfg.Name, "path", dstPath)
log.DebugContext(ctx, "mkdir")
if err := os.MkdirAll(dstPath, os.ModePerm); err != nil {
return errors.Wrap(err)

View File

@@ -0,0 +1,4 @@
package holos
// Produce a kubectl kustomize build plan.
(#Kustomize & {Name: "{{ .Name }}"}).Output

View File

@@ -0,0 +1,7 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: "{{ .Namespace }}"
resources:
- "https://raw.githubusercontent.com/argoproj/argo-cd/v{{ .Version }}/manifests/install.yaml"

View File

@@ -0,0 +1,7 @@
{
"name": "argocd",
"namespace": "argocd",
"short": "argocd kustomize",
"long": "Manage argocd using a kustomization.yaml build plan.",
"version": "2.11.2"
}

View File

@@ -0,0 +1,21 @@
package holos
import "encoding/yaml"
let Objects = {
Name: "{{ .Name }}"
Namespace: "{{ .Namespace }}"
Resources: {
ConfigMap: {
example: {
metadata: namespace: "{{ .Namespace }}"
// _Platform.Model represents the web form model
data: platform: yaml.Marshal({model: _Platform.Model})
}
}
}
}
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).Output

View File

@@ -0,0 +1,6 @@
{
"name": "configmap",
"namespace": "default",
"short": "simple configmap example",
"long": "End-to-end demonstration of data flowing from the web ui to a cluster resource"
}

View File

@@ -1,32 +0,0 @@
package holos
import v1 "github.com/holos-run/holos/api/v1alpha1"
import "encoding/yaml"
let ComponentName = "{{ .ComponentName }}"
// The BuildPlan represents the kubernetes api objects to manage. CUE returns
// the build plan to the holos CLI for rendering to plain yaml files.
v1.#BuildPlan & {
spec: components: resources: "\(ComponentName)": {
metadata: name: ComponentName
apiObjectMap: OBJECTS.apiObjectMap
}
}
// OBJECTS represents the kubernetes api objects to manage.
let OBJECTS = v1.#APIObjects & {
// Add Kubernetes API Objects to manage here.
apiObjects: ConfigMap: "\(ComponentName)": {
metadata: {
name: ComponentName
namespace: "default"
}
data: platform: yaml.Marshal(PLATFORM)
}
}
// This is an example of how to refer to the Platform model.
let PLATFORM = {
spec: model: _Platform.spec.model
}

View File

@@ -0,0 +1,11 @@
package holos
let Objects = {
Name: "{{ .Name }}"
Namespace: "{{ .Namespace }}"
Resources: Namespace: _Namespaces
}
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).Output

View File

@@ -0,0 +1,6 @@
{
"name": "namespaces",
"namespace": "default",
"short": "manage namespaces on multiple clusters",
"long": "Manage namespaces across all clusters in the platform following sig-multicluster namespace sameness position."
}

View File

@@ -0,0 +1,20 @@
package holos
let Chart = {
Name: "{{ .Name }}"
Version: "{{ .Version }}"
Namespace: "{{ .Namespace }}"
Repo: name: "{{ .RepoName }}"
Repo: url: "{{ .RepoURL }}"
Values: {
installCRDs: true
startupapicheck: enabled: false
// Must not use kube-system on gke autopilot. GKE Warden blocks access.
global: leaderElection: namespace: Namespace
}
}
// Produce a helm chart build plan.
(#Helm & Chart).Output

View File

@@ -0,0 +1,10 @@
{
"name": "cert-manager",
"short": "cloud native certificate management",
"long": "Automatically provision and manage TLS certificates in Kubernetes",
"chart": "cert-manager",
"version": "1.14.5",
"namespace": "cert-manager",
"reponame": "jetstack",
"repourl": "https://charts.jetstack.io"
}

View File

@@ -0,0 +1,15 @@
package holos
let Chart = {
Name: "{{ .Name }}"
Version: "{{ .Version }}"
Namespace: "{{ .Namespace }}"
// OCI helm charts use the image url as the chart name
Chart: chart: name: "{{ .Chart }}"
Values: {}
}
// Produce a helm chart build plan.
(#Helm & Chart).Output

View File

@@ -0,0 +1,8 @@
{
"name": "podinfo-oci",
"short": "oci helm chart example",
"long": "Podinfo is a tiny web application made with Go that showcases best practices of running microservices in Kubernetes.",
"chart": "oci://ghcr.io/stefanprodan/charts/podinfo",
"version": "6.6.2",
"namespace": "default"
}

View File

@@ -0,0 +1,15 @@
package holos
let Chart = {
Name: "{{ .Name }}"
Version: "{{ .Version }}"
Namespace: "{{ .Namespace }}"
Repo: name: "{{ .RepoName }}"
Repo: url: "{{ .RepoURL }}"
Values: {}
}
// Produce a helm chart build plan.
(#Helm & Chart).Output

View File

@@ -0,0 +1,10 @@
{
"name": "podinfo",
"short": "simple helm chart example",
"long": "Podinfo is a tiny web application made with Go that showcases best practices of running microservices in Kubernetes.",
"chart": "podinfo",
"reponame": "podinfo",
"repourl": "https://stefanprodan.github.io/podinfo",
"version": "6.6.2",
"namespace": "default"
}

View File

@@ -41,17 +41,25 @@ func copyEmbedFS(ctx context.Context, srcFS embed.FS, srcPath, dstPath string, m
return errors.Wrap(err)
}
log.DebugContext(ctx, "created", "directory", dstFullPath)
} else {
data, err := srcFS.ReadFile(path)
if err != nil {
return errors.Wrap(err)
}
buf := mapFunc(data)
if err := os.WriteFile(dstFullPath, buf.Bytes(), os.ModePerm); err != nil {
return errors.Wrap(err)
}
log.DebugContext(ctx, "wrote", "file", dstFullPath)
return nil
}
if filepath.Base(path) == "schematic.json" {
log.DebugContext(ctx, "skipped", "file", dstFullPath)
return nil
}
data, err := srcFS.ReadFile(path)
if err != nil {
return errors.Wrap(err)
}
buf := mapFunc(data)
if err := os.WriteFile(dstFullPath, buf.Bytes(), 0666); err != nil {
return errors.Wrap(err)
}
log.DebugContext(ctx, "wrote", "file", dstFullPath)
return nil
})
}

View File

@@ -0,0 +1,33 @@
package holos
import "encoding/yaml"
import v1 "github.com/holos-run/holos/api/v1alpha1"
// #Helm represents a holos build plan composed of one or more helm charts.
#Helm: {
Name: string
Version: string
Namespace: string
Repo: {
name: string | *""
url: string | *""
}
Values: {...}
Chart: v1.#HelmChart & {
metadata: name: string | *Name
namespace: string | *Namespace
chart: name: string | *Name
chart: version: string | *Version
chart: repository: Repo
// Render the values to yaml for holos to provide to helm.
valuesContent: yaml.Marshal(Values)
}
// output represents the build plan provided to the holos cli.
Output: v1.#BuildPlan & {
spec: components: helmChartList: [Chart]
}
}

View File

@@ -1,6 +1,7 @@
package holos
import "encoding/yaml"
import v1 "github.com/holos-run/holos/api/v1alpha1"
// Provide a BuildPlan to the holos cli to render k8s api objects.

View File

@@ -140,7 +140,7 @@ let FormBuilder = v1.#FormBuilder & {
required: true
}
validation: messages: {
pattern: "It must be \(props.minLength) to \(props.maxLength) lowercase letters, digits, or hyphens. It must start with a letter. Trailing hyphens are prohibited."
pattern: "It must be \(props.minLength) to \(props.maxLength) lowercase letters, digits, or hyphens. It must start with a letter. Trailing hyphens are prohibited."
minLength: "Must be at least \(props.minLength) characters."
maxLength: "Must be at most \(props.maxLength) characters."
}

View File

@@ -3,11 +3,12 @@ package holos
import "encoding/json"
import v1 "github.com/holos-run/holos/api/v1alpha1"
import dto "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
// _PlatformConfig represents all of the data passed from holos to cue.
// Intended to carry the platform model and project models.
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
_PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
// _Platform provides a platform resource to the holos cli for rendering. The
@@ -16,7 +17,9 @@ _PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
// resource itself is output once when rendering the entire platform, see the
// platform/ subdirectory.
_Platform: v1.#Platform & {
metadata: name: string | *"bare" @tag(platform_name, type=string)
metadata: {
name: string | *"bare" @tag(platform_name, type=string)
}
// spec is the platform specification
spec: {
@@ -28,7 +31,7 @@ _Platform: v1.#Platform & {
_components: {
for WorkloadCluster in _Clusters.Workload {
"\(WorkloadCluster)-configmap": {
path: "components/configmap"
path: "components/configmap"
cluster: WorkloadCluster
}
}

View File

@@ -0,0 +1,189 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws2/components/argocd-crds/argocd-crds.gen.yaml
package v1alpha1
import "strings"
// AppProject provides a logical grouping of applications,
// providing controls for: * where the apps may deploy to
// (cluster whitelist) * what may be deployed (repository
// whitelist, resource whitelist/blacklist) * who can access
// these applications (roles, OIDC group claims bindings) * and
// what they can do (RBAC policies) * automation access to these
// roles (JWT tokens)
#AppProject: {
// 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
apiVersion: "argoproj.io/v1alpha1"
// 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
kind: "AppProject"
metadata: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// AppProjectSpec is the specification of an AppProject
spec!: #AppProjectSpec
}
// AppProjectSpec is the specification of an AppProject
#AppProjectSpec: {
// ClusterResourceBlacklist contains list of blacklisted cluster
// level resources
clusterResourceBlacklist?: [...{
group: string
kind: string
}]
// ClusterResourceWhitelist contains list of whitelisted cluster
// level resources
clusterResourceWhitelist?: [...{
group: string
kind: string
}]
// Description contains optional project description
description?: string
// Destinations contains list of destinations available for
// deployment
destinations?: [...{
// Name is an alternate way of specifying the target cluster by
// its symbolic name. This must be set if Server is not set.
name?: string
// Namespace specifies the target namespace for the application's
// resources. The namespace will only be set for namespace-scoped
// resources that have not set a value for .metadata.namespace
namespace?: string
// Server specifies the URL of the target cluster's Kubernetes
// control plane API. This must be set if Name is not set.
server?: string
}]
// NamespaceResourceBlacklist contains list of blacklisted
// namespace level resources
namespaceResourceBlacklist?: [...{
group: string
kind: string
}]
// NamespaceResourceWhitelist contains list of whitelisted
// namespace level resources
namespaceResourceWhitelist?: [...{
group: string
kind: string
}]
// OrphanedResources specifies if controller should monitor
// orphaned resources of apps in this project
orphanedResources?: {
// Ignore contains a list of resources that are to be excluded
// from orphaned resources monitoring
ignore?: [...{
group?: string
kind?: string
name?: string
}]
// Warn indicates if warning condition should be created for apps
// which have orphaned resources
warn?: bool
}
// PermitOnlyProjectScopedClusters determines whether destinations
// can only reference clusters which are project-scoped
permitOnlyProjectScopedClusters?: bool
// Roles are user defined RBAC roles associated with this project
roles?: [...{
// Description is a description of the role
description?: string
// Groups are a list of OIDC group claims bound to this role
groups?: [...string]
// JWTTokens are a list of generated JWT tokens bound to this role
jwtTokens?: [...{
exp?: int
iat: int
id?: string
}]
// Name is a name for this role
name: string
// Policies Stores a list of casbin formatted strings that define
// access policies for the role in the project
policies?: [...string]
}]
// SignatureKeys contains a list of PGP key IDs that commits in
// Git must be signed with in order to be allowed for sync
signatureKeys?: [...{
// The ID of the key in hexadecimal notation
keyID: string
}]
// SourceNamespaces defines the namespaces application resources
// are allowed to be created in
sourceNamespaces?: [...string]
// SourceRepos contains list of repository URLs which can be used
// for deployment
sourceRepos?: [...string]
// SyncWindows controls when syncs can be run for apps in this
// project
syncWindows?: [...{
// Applications contains a list of applications that the window
// will apply to
applications?: [...string]
// Clusters contains a list of clusters that the window will apply
// to
clusters?: [...string]
// Duration is the amount of time the sync window will be open
duration?: string
// Kind defines if the window allows or blocks syncs
kind?: string
// ManualSync enables manual syncs when they would otherwise be
// blocked
manualSync?: bool
// Namespaces contains a list of namespaces that the window will
// apply to
namespaces?: [...string]
// Schedule is the time the window will begin, specified in cron
// format
schedule?: string
// TimeZone of the sync that will be applied to the schedule
timeZone?: string
}]
}

View File

@@ -0,0 +1,340 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f https://raw.githubusercontent.com/crossplane-contrib/provider-upjet-aws/v1.5.0/package/crds/aws.upbound.io_providerconfigs.yaml
package v1beta1
import "strings"
// A ProviderConfig configures the AWS provider.
#ProviderConfig: {
// 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
apiVersion: "aws.upbound.io/v1beta1"
// 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
kind: "ProviderConfig"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// A ProviderConfigSpec defines the desired state of a
// ProviderConfig.
spec!: #ProviderConfigSpec
}
// A ProviderConfigSpec defines the desired state of a
// ProviderConfig.
#ProviderConfigSpec: {
// AssumeRoleChain defines the options for assuming an IAM role
assumeRoleChain?: [...{
// ExternalID is the external ID used when assuming role.
externalID?: string
// AssumeRoleARN to assume with provider credentials
roleARN?: string
// Tags is list of session tags that you want to pass. Each
// session tag consists of a key
// name and an associated value. For more information about
// session tags, see
// Tagging STS Sessions
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html).
tags?: [...{
// Name of the tag.
// Key is a required field
key: string
// Value of the tag.
// Value is a required field
value: string
}]
// TransitiveTagKeys is a list of keys for session tags that you
// want to set as transitive. If you set a
// tag key as transitive, the corresponding key and value passes
// to subsequent
// sessions in a role chain. For more information, see Chaining
// Roles with Session Tags
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining).
transitiveTagKeys?: [...string]
}]
// Credentials required to authenticate to this provider.
credentials: {
env?: {
// Name is the name of an environment variable.
name: string
}
fs?: {
// Path is a filesystem path.
path: string
}
// A SecretRef is a reference to a secret key that contains the
// credentials
// that must be used to connect to the provider.
secretRef?: {
// The key to select.
key: string
// Name of the secret.
name: string
// Namespace of the secret.
namespace: string
}
// Source of the provider credentials.
source: "None" | "Secret" | "IRSA" | "WebIdentity" | "Upbound"
upbound?: {
// WebIdentity defines the options for assuming an IAM role with a
// Web
// Identity.
webIdentity?: {
// AssumeRoleARN to assume with provider credentials
roleARN?: string
// RoleSessionName is the session name, if you wish to uniquely
// identify this session.
roleSessionName?: string
// TokenConfig is the Web Identity Token config to assume the
// role.
tokenConfig?: {
fs?: {
// Path is a filesystem path.
path: string
}
// A SecretRef is a reference to a secret key that contains the
// credentials
// that must be used to obtain the web identity token.
secretRef?: {
// The key to select.
key: string
// Name of the secret.
name: string
// Namespace of the secret.
namespace: string
}
// Source is the source of the web identity token.
source: "Secret" | "Filesystem"
}
}
}
// WebIdentity defines the options for assuming an IAM role with a
// Web Identity.
webIdentity?: {
// AssumeRoleARN to assume with provider credentials
roleARN?: string
// RoleSessionName is the session name, if you wish to uniquely
// identify this session.
roleSessionName?: string
// TokenConfig is the Web Identity Token config to assume the
// role.
tokenConfig?: {
fs?: {
// Path is a filesystem path.
path: string
}
// A SecretRef is a reference to a secret key that contains the
// credentials
// that must be used to obtain the web identity token.
secretRef?: {
// The key to select.
key: string
// Name of the secret.
name: string
// Namespace of the secret.
namespace: string
}
// Source is the source of the web identity token.
source: "Secret" | "Filesystem"
}
}
}
// Endpoint is where you can override the default endpoint
// configuration
// of AWS calls made by the provider.
endpoint?: {
// Specifies if the endpoint's hostname can be modified by the
// SDK's API
// client.
//
//
// If the hostname is mutable the SDK API clients may modify any
// part of
// the hostname based on the requirements of the API, (e.g.
// adding, or
// removing content in the hostname). Such as, Amazon S3 API
// client
// prefixing "bucketname" to the hostname, or changing the
// hostname service name component from "s3." to
// "s3-accesspoint.dualstack."
// for the dualstack endpoint of an S3 Accesspoint resource.
//
//
// Care should be taken when providing a custom endpoint for an
// API. If the
// endpoint hostname is mutable, and the client cannot modify the
// endpoint
// correctly, the operation call will most likely fail, or have
// undefined
// behavior.
//
//
// If hostname is immutable, the SDK API clients will not modify
// the
// hostname of the URL. This may cause the API client not to
// function
// correctly if the API requires the operation specific hostname
// values
// to be used by the client.
//
//
// This flag does not modify the API client's behavior if this
// endpoint
// will be used instead of Endpoint Discovery, or if the endpoint
// will be
// used to perform Endpoint Discovery. That behavior is configured
// via the
// API Client's Options.
// Note that this is effective only for resources that use AWS SDK
// v2.
hostnameImmutable?: bool
// The AWS partition the endpoint belongs to.
partitionId?: string
// Specifies the list of services you want endpoint to be used for
services?: [...string]
// The signing method that should be used for signing the requests
// to the
// endpoint.
signingMethod?: string
// The service name that should be used for signing the requests
// to the
// endpoint.
signingName?: string
// The region that should be used for signing the request to the
// endpoint.
// For IAM, which doesn't have any region, us-east-1 is used to
// sign the
// requests, which is the only signing region of IAM.
signingRegion?: string
// The source of the Endpoint. By default, this will be
// ServiceMetadata.
// When providing a custom endpoint, you should set the source as
// Custom.
// If source is not provided when providing a custom endpoint, the
// SDK may not
// perform required host mutations correctly. Source should be
// used along with
// HostnameImmutable property as per the usage requirement.
// Note that this is effective only for resources that use AWS SDK
// v2.
source?: "ServiceMetadata" | "Custom"
// URL lets you configure the endpoint URL to be used in SDK
// calls.
url: {
// Dynamic lets you configure the behavior of endpoint URL
// resolver.
dynamic?: {
// Host is the address of the main host that the resolver will use
// to
// prepend protocol, service and region configurations.
// For example, the final URL for EC2 in us-east-1 looks like
// https://ec2.us-east-1.amazonaws.com
// You would need to use "amazonaws.com" as Host and "https" as
// protocol
// to have the resolver construct it.
host: string
// Protocol is the HTTP protocol that will be used in the URL.
// Currently,
// only http and https are supported.
protocol: "http" | "https"
}
// Static is the full URL you'd like the AWS SDK to use.
// Recommended for using tools like localstack where a single host
// is exposed
// for all services and regions.
static?: string
// You can provide a static URL that will be used regardless of
// the service
// and region by choosing Static type. Alternatively, you can
// provide
// configuration for dynamically resolving the URL with the config
// you provide
// once you set the type as Dynamic.
type: "Static" | "Dynamic"
}
}
// Whether to enable the request to use path-style addressing,
// i.e., https://s3.amazonaws.com/BUCKET/KEY.
s3_use_path_style?: bool
// Whether to skip credentials validation via the STS API.
// This can be useful for testing and for AWS API implementations
// that do not have STS available.
skip_credentials_validation?: bool
// Whether to skip the AWS Metadata API check
// Useful for AWS API implementations that do not have a metadata
// API endpoint.
skip_metadata_api_check?: bool
// Whether to skip validation of provided region name.
// Useful for AWS-like implementations that use their own region
// names or to bypass the validation for
// regions that aren't publicly available yet.
skip_region_validation?: bool
// Whether to skip requesting the account ID.
// Useful for AWS API implementations that do not have the IAM,
// STS API, or metadata API
skip_requesting_account_id?: bool
}

View File

@@ -0,0 +1,422 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-mesh-certmanager/prod-mesh-certmanager.gen.yaml
package v1
import "strings"
// A Certificate resource should be created to ensure an up to
// date and signed X.509 certificate is stored in the Kubernetes
// Secret resource named in `spec.secretName`.
// The stored certificate will be renewed before it expires (as
// configured by `spec.renewBefore`).
#Certificate: {
// 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
apiVersion: "cert-manager.io/v1"
// 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
kind: "Certificate"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// Specification of the desired state of the Certificate resource.
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
spec!: #CertificateSpec
}
// Specification of the desired state of the Certificate resource.
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
#CertificateSpec: {
// Defines extra output formats of the private key and signed
// certificate chain to be written to this Certificate's target
// Secret.
// This is an Alpha Feature and is only enabled with the
// `--feature-gates=AdditionalCertificateOutputFormats=true`
// option set on both the controller and webhook components.
additionalOutputFormats?: [...{
// Type is the name of the format type that should be written to
// the Certificate's target Secret.
type: "DER" | "CombinedPEM"
}]
// Requested common name X509 certificate subject attribute. More
// info:
// https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
// NOTE: TLS clients will ignore this value when any subject
// alternative name is set (see
// https://tools.ietf.org/html/rfc6125#section-6.4.4).
// Should have a length of 64 characters or fewer to avoid
// generating invalid CSRs. Cannot be set if the `literalSubject`
// field is set.
commonName?: string
// Requested DNS subject alternative names.
dnsNames?: [...string]
// Requested 'duration' (i.e. lifetime) of the Certificate. Note
// that the issuer may choose to ignore the requested duration,
// just like any other requested attribute.
// If unset, this defaults to 90 days. Minimum accepted duration
// is 1 hour. Value must be in units accepted by Go
// time.ParseDuration https://golang.org/pkg/time/#ParseDuration.
duration?: string
// Requested email subject alternative names.
emailAddresses?: [...string]
// Whether the KeyUsage and ExtKeyUsage extensions should be set
// in the encoded CSR.
// This option defaults to true, and should only be disabled if
// the target issuer does not support CSRs with these X509
// KeyUsage/ ExtKeyUsage extensions.
encodeUsagesInRequest?: bool
// Requested IP address subject alternative names.
ipAddresses?: [...string]
// Requested basic constraints isCA value. The isCA value is used
// to set the `isCA` field on the created CertificateRequest
// resources. Note that the issuer may choose to ignore the
// requested isCA value, just like any other requested attribute.
// If true, this will automatically add the `cert sign` usage to
// the list of requested `usages`.
isCA?: bool
// Reference to the issuer responsible for issuing the
// certificate. If the issuer is namespace-scoped, it must be in
// the same namespace as the Certificate. If the issuer is
// cluster-scoped, it can be used from any namespace.
// The `name` field of the reference must always be specified.
issuerRef: {
// Group of the resource being referred to.
group?: string
// Kind of the resource being referred to.
kind?: string
// Name of the resource being referred to.
name: string
}
// Additional keystore output formats to be stored in the
// Certificate's Secret.
keystores?: {
// JKS configures options for storing a JKS keystore in the
// `spec.secretName` Secret resource.
jks?: {
// Create enables JKS keystore creation for the Certificate. If
// true, a file named `keystore.jks` will be created in the
// target Secret resource, encrypted using the password stored in
// `passwordSecretRef`. The keystore file will be updated
// immediately. If the issuer provided a CA certificate, a file
// named `truststore.jks` will also be created in the target
// Secret resource, encrypted using the password stored in
// `passwordSecretRef` containing the issuing Certificate
// Authority
create: bool
// PasswordSecretRef is a reference to a key in a Secret resource
// containing the password used to encrypt the JKS keystore.
passwordSecretRef: {
// The key of the entry in the Secret resource's `data` field to
// be used. Some instances of this field may be defaulted, in
// others it may be required.
key?: string
// Name of the resource being referred to. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: string
}
}
// PKCS12 configures options for storing a PKCS12 keystore in the
// `spec.secretName` Secret resource.
pkcs12?: {
// Create enables PKCS12 keystore creation for the Certificate. If
// true, a file named `keystore.p12` will be created in the
// target Secret resource, encrypted using the password stored in
// `passwordSecretRef`. The keystore file will be updated
// immediately. If the issuer provided a CA certificate, a file
// named `truststore.p12` will also be created in the target
// Secret resource, encrypted using the password stored in
// `passwordSecretRef` containing the issuing Certificate
// Authority
create: bool
// PasswordSecretRef is a reference to a key in a Secret resource
// containing the password used to encrypt the PKCS12 keystore.
passwordSecretRef: {
// The key of the entry in the Secret resource's `data` field to
// be used. Some instances of this field may be defaulted, in
// others it may be required.
key?: string
// Name of the resource being referred to. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name: string
}
// Profile specifies the key and certificate encryption algorithms
// and the HMAC algorithm used to create the PKCS12 keystore.
// Default value is `LegacyRC2` for backward compatibility.
// If provided, allowed values are: `LegacyRC2`: Deprecated. Not
// supported by default in OpenSSL 3 or Java 20. `LegacyDES`:
// Less secure algorithm. Use this option for maximal
// compatibility. `Modern2023`: Secure algorithm. Use this option
// in case you have to always use secure algorithms (eg. because
// of company policy). Please note that the security of the
// algorithm is not that important in reality, because the
// unencrypted certificate and private key are also stored in the
// Secret.
profile?: "LegacyRC2" | "LegacyDES" | "Modern2023"
}
}
// Requested X.509 certificate subject, represented using the LDAP
// "String Representation of a Distinguished Name" [1].
// Important: the LDAP string format also specifies the order of
// the attributes in the subject, this is important when issuing
// certs for LDAP authentication. Example:
// `CN=foo,DC=corp,DC=example,DC=com` More info [1]:
// https://datatracker.ietf.org/doc/html/rfc4514 More info:
// https://github.com/cert-manager/cert-manager/issues/3203 More
// info: https://github.com/cert-manager/cert-manager/issues/4424
// Cannot be set if the `subject` or `commonName` field is set.
// This is an Alpha Feature and is only enabled with the
// `--feature-gates=LiteralCertificateSubject=true` option set on
// both the controller and webhook components.
literalSubject?: string
// x.509 certificate NameConstraint extension which MUST NOT be
// used in a non-CA certificate. More Info:
// https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10
// This is an Alpha Feature and is only enabled with the
// `--feature-gates=NameConstraints=true` option set on both the
// controller and webhook components.
nameConstraints?: {
// if true then the name constraints are marked critical.
critical?: bool
// Excluded contains the constraints which must be disallowed. Any
// name matching a restriction in the excluded field is invalid
// regardless of information appearing in the permitted
excluded?: {
// DNSDomains is a list of DNS domains that are permitted or
// excluded.
dnsDomains?: [...string]
// EmailAddresses is a list of Email Addresses that are permitted
// or excluded.
emailAddresses?: [...string]
// IPRanges is a list of IP Ranges that are permitted or excluded.
// This should be a valid CIDR notation.
ipRanges?: [...string]
// URIDomains is a list of URI domains that are permitted or
// excluded.
uriDomains?: [...string]
}
// Permitted contains the constraints in which the names must be
// located.
permitted?: {
// DNSDomains is a list of DNS domains that are permitted or
// excluded.
dnsDomains?: [...string]
// EmailAddresses is a list of Email Addresses that are permitted
// or excluded.
emailAddresses?: [...string]
// IPRanges is a list of IP Ranges that are permitted or excluded.
// This should be a valid CIDR notation.
ipRanges?: [...string]
// URIDomains is a list of URI domains that are permitted or
// excluded.
uriDomains?: [...string]
}
}
// `otherNames` is an escape hatch for SAN that allows any type.
// We currently restrict the support to string like otherNames,
// cf RFC 5280 p 37 Any UTF8 String valued otherName can be
// passed with by setting the keys oid: x.x.x.x and UTF8Value:
// somevalue for `otherName`. Most commonly this would be UPN set
// with oid: 1.3.6.1.4.1.311.20.2.3 You should ensure that any
// OID passed is valid for the UTF8String type as we do not
// explicitly validate this.
otherNames?: [...{
// OID is the object identifier for the otherName SAN. The object
// identifier must be expressed as a dotted string, for example,
// "1.2.840.113556.1.4.221".
oid?: string
// utf8Value is the string value of the otherName SAN. The
// utf8Value accepts any valid UTF8 string to set as value for
// the otherName SAN.
utf8Value?: string
}]
// Private key options. These include the key algorithm and size,
// the used encoding and the rotation policy.
privateKey?: {
// Algorithm is the private key algorithm of the corresponding
// private key for this certificate.
// If provided, allowed values are either `RSA`, `ECDSA` or
// `Ed25519`. If `algorithm` is specified and `size` is not
// provided, key size of 2048 will be used for `RSA` key
// algorithm and key size of 256 will be used for `ECDSA` key
// algorithm. key size is ignored when using the `Ed25519` key
// algorithm.
algorithm?: "RSA" | "ECDSA" | "Ed25519"
// The private key cryptography standards (PKCS) encoding for this
// certificate's private key to be encoded in.
// If provided, allowed values are `PKCS1` and `PKCS8` standing
// for PKCS#1 and PKCS#8, respectively. Defaults to `PKCS1` if
// not specified.
encoding?: "PKCS1" | "PKCS8"
// RotationPolicy controls how private keys should be regenerated
// when a re-issuance is being processed.
// If set to `Never`, a private key will only be generated if one
// does not already exist in the target `spec.secretName`. If one
// does exists but it does not have the correct algorithm or
// size, a warning will be raised to await user intervention. If
// set to `Always`, a private key matching the specified
// requirements will be generated whenever a re-issuance occurs.
// Default is `Never` for backward compatibility.
rotationPolicy?: "Never" | "Always"
// Size is the key bit size of the corresponding private key for
// this certificate.
// If `algorithm` is set to `RSA`, valid values are `2048`, `4096`
// or `8192`, and will default to `2048` if not specified. If
// `algorithm` is set to `ECDSA`, valid values are `256`, `384`
// or `521`, and will default to `256` if not specified. If
// `algorithm` is set to `Ed25519`, Size is ignored. No other
// values are allowed.
size?: int
}
// How long before the currently issued certificate's expiry
// cert-manager should renew the certificate. For example, if a
// certificate is valid for 60 minutes, and `renewBefore=10m`,
// cert-manager will begin to attempt to renew the certificate 50
// minutes after it was issued (i.e. when there are 10 minutes
// remaining until the certificate is no longer valid).
// NOTE: The actual lifetime of the issued certificate is used to
// determine the renewal time. If an issuer returns a certificate
// with a different lifetime than the one requested, cert-manager
// will use the lifetime of the issued certificate.
// If unset, this defaults to 1/3 of the issued certificate's
// lifetime. Minimum accepted value is 5 minutes. Value must be
// in units accepted by Go time.ParseDuration
// https://golang.org/pkg/time/#ParseDuration.
renewBefore?: string
// The maximum number of CertificateRequest revisions that are
// maintained in the Certificate's history. Each revision
// represents a single `CertificateRequest` created by this
// Certificate, either when it was created, renewed, or Spec was
// changed. Revisions will be removed by oldest first if the
// number of revisions exceeds this number.
// If set, revisionHistoryLimit must be a value of `1` or greater.
// If unset (`nil`), revisions will not be garbage collected.
// Default value is `nil`.
revisionHistoryLimit?: int
// Name of the Secret resource that will be automatically created
// and managed by this Certificate resource. It will be populated
// with a private key and certificate, signed by the denoted
// issuer. The Secret resource lives in the same namespace as the
// Certificate resource.
secretName: string
// Defines annotations and labels to be copied to the
// Certificate's Secret. Labels and annotations on the Secret
// will be changed as they appear on the SecretTemplate when
// added or removed. SecretTemplate annotations are added in
// conjunction with, and cannot overwrite, the base set of
// annotations cert-manager sets on the Certificate's Secret.
secretTemplate?: {
// Annotations is a key value map to be copied to the target
// Kubernetes Secret.
annotations?: {
[string]: string
}
// Labels is a key value map to be copied to the target Kubernetes
// Secret.
labels?: {
[string]: string
}
}
// Requested set of X509 certificate subject attributes. More
// info:
// https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
// The common name attribute is specified separately in the
// `commonName` field. Cannot be set if the `literalSubject`
// field is set.
subject?: {
// Countries to be used on the Certificate.
countries?: [...string]
// Cities to be used on the Certificate.
localities?: [...string]
// Organizational Units to be used on the Certificate.
organizationalUnits?: [...string]
// Organizations to be used on the Certificate.
organizations?: [...string]
// Postal codes to be used on the Certificate.
postalCodes?: [...string]
// State/Provinces to be used on the Certificate.
provinces?: [...string]
// Serial number to be used on the Certificate.
serialNumber?: string
// Street addresses to be used on the Certificate.
streetAddresses?: [...string]
}
// Requested URI subject alternative names.
uris?: [...string]
// Requested key usages and extended key usages. These usages are
// used to set the `usages` field on the created
// CertificateRequest resources. If `encodeUsagesInRequest` is
// unset or set to `true`, the usages will additionally be
// encoded in the `request` field which contains the CSR blob.
// If unset, defaults to `digital signature` and `key
// encipherment`.
usages?: [..."signing" | "digital signature" | "content commitment" | "key encipherment" | "key agreement" | "data encipherment" | "cert sign" | "crl sign" | "encipher only" | "decipher only" | "any" | "server auth" | "client auth" | "code signing" | "email protection" | "s/mime" | "ipsec end system" | "ipsec tunnel" | "ipsec user" | "timestamping" | "ocsp signing" | "microsoft sgc" | "netscape sgc"]
}

View File

@@ -0,0 +1,127 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-mesh-certmanager/prod-mesh-certmanager.gen.yaml
package v1
import "strings"
// A CertificateRequest is used to request a signed certificate
// from one of the configured issuers.
// All fields within the CertificateRequest's `spec` are immutable
// after creation. A CertificateRequest will either succeed or
// fail, as denoted by its `Ready` status condition and its
// `status.failureTime` field.
// A CertificateRequest is a one-shot resource, meaning it
// represents a single point in time request for a certificate
// and cannot be re-used.
#CertificateRequest: {
// 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
apiVersion: "cert-manager.io/v1"
// 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
kind: "CertificateRequest"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// Specification of the desired state of the CertificateRequest
// resource.
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
spec!: #CertificateRequestSpec
}
// Specification of the desired state of the CertificateRequest
// resource.
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
#CertificateRequestSpec: {
// Requested 'duration' (i.e. lifetime) of the Certificate. Note
// that the issuer may choose to ignore the requested duration,
// just like any other requested attribute.
duration?: string
// Extra contains extra attributes of the user that created the
// CertificateRequest. Populated by the cert-manager webhook on
// creation and immutable.
extra?: {
[string]: [...string]
}
// Groups contains group membership of the user that created the
// CertificateRequest. Populated by the cert-manager webhook on
// creation and immutable.
groups?: [...string]
// Requested basic constraints isCA value. Note that the issuer
// may choose to ignore the requested isCA value, just like any
// other requested attribute.
// NOTE: If the CSR in the `Request` field has a BasicConstraints
// extension, it must have the same isCA value as specified here.
// If true, this will automatically add the `cert sign` usage to
// the list of requested `usages`.
isCA?: bool
// Reference to the issuer responsible for issuing the
// certificate. If the issuer is namespace-scoped, it must be in
// the same namespace as the Certificate. If the issuer is
// cluster-scoped, it can be used from any namespace.
// The `name` field of the reference must always be specified.
issuerRef: {
// Group of the resource being referred to.
group?: string
// Kind of the resource being referred to.
kind?: string
// Name of the resource being referred to.
name: string
}
// The PEM-encoded X.509 certificate signing request to be
// submitted to the issuer for signing.
// If the CSR has a BasicConstraints extension, its isCA attribute
// must match the `isCA` value of this CertificateRequest. If the
// CSR has a KeyUsage extension, its key usages must match the
// key usages in the `usages` field of this CertificateRequest.
// If the CSR has a ExtKeyUsage extension, its extended key
// usages must match the extended key usages in the `usages`
// field of this CertificateRequest.
request: string
// UID contains the uid of the user that created the
// CertificateRequest. Populated by the cert-manager webhook on
// creation and immutable.
uid?: string
// Requested key usages and extended key usages.
// NOTE: If the CSR in the `Request` field has uses the KeyUsage
// or ExtKeyUsage extension, these extensions must have the same
// values as specified here without any additional values.
// If unset, defaults to `digital signature` and `key
// encipherment`.
usages?: [..."signing" | "digital signature" | "content commitment" | "key encipherment" | "key agreement" | "data encipherment" | "cert sign" | "crl sign" | "encipher only" | "decipher only" | "any" | "server auth" | "client auth" | "code signing" | "email protection" | "s/mime" | "ipsec end system" | "ipsec tunnel" | "ipsec user" | "timestamping" | "ocsp signing" | "microsoft sgc" | "netscape sgc"]
// Username contains the name of the user that created the
// CertificateRequest. Populated by the cert-manager webhook on
// creation and immutable.
username?: string
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,148 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws2/components/istio-base/istio-base.gen.yaml
package v1alpha1
import (
"strings"
"list"
)
#WasmPlugin: {
// Extend the functionality provided by the Istio proxy through
// WebAssembly filters. See more details at:
// https://istio.io/docs/reference/config/proxy_extensions/wasm-plugin.html
spec!: #WasmPluginSpec
apiVersion: "extensions.istio.io/v1alpha1"
kind: "WasmPlugin"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
}
// Extend the functionality provided by the Istio proxy through
// WebAssembly filters. See more details at:
// https://istio.io/docs/reference/config/proxy_extensions/wasm-plugin.html
#WasmPluginSpec: {
// Specifies the failure behavior for the plugin due to fatal
// errors.
//
// Valid Options: FAIL_CLOSE, FAIL_OPEN
failStrategy?: "FAIL_CLOSE" | "FAIL_OPEN"
// The pull behaviour to be applied when fetching Wasm module by
// either OCI image or `http/https`.
//
// Valid Options: IfNotPresent, Always
imagePullPolicy?: "UNSPECIFIED_POLICY" | "IfNotPresent" | "Always"
// Credentials to use for OCI image pulling.
imagePullSecret?: strings.MaxRunes(253) & strings.MinRunes(1)
// Specifies the criteria to determine which traffic is passed to
// WasmPlugin.
match?: [...{
// Criteria for selecting traffic by their direction.
//
// Valid Options: CLIENT, SERVER, CLIENT_AND_SERVER
mode?: "UNDEFINED" | "CLIENT" | "SERVER" | "CLIENT_AND_SERVER"
// Criteria for selecting traffic by their destination port.
ports?: [...{
number: uint16 & >=1
}]
}]
// Determines where in the filter chain this `WasmPlugin` is to be
// injected.
//
// Valid Options: AUTHN, AUTHZ, STATS
phase?: "UNSPECIFIED_PHASE" | "AUTHN" | "AUTHZ" | "STATS"
// The configuration that will be passed on to the plugin.
pluginConfig?: {
...
}
// The plugin name to be used in the Envoy configuration (used to
// be called `rootID`).
pluginName?: strings.MaxRunes(256) & strings.MinRunes(1)
// Determines ordering of `WasmPlugins` in the same `phase`.
priority?: null | int
selector?: {
// One or more labels that indicate a specific set of pods/VMs on
// which a policy should be applied.
matchLabels?: {
[string]: string
}
}
// SHA256 checksum that will be used to verify Wasm module or OCI
// container.
sha256?: =~"(^$|^[a-f0-9]{64}$)"
targetRef?: {
// group is the group of the target resource.
group?: string
// kind is kind of the target resource.
kind?: string
// name is the name of the target resource.
name?: string
// namespace is the namespace of the referent.
namespace?: string
}
// Optional.
targetRefs?: [...{
// group is the group of the target resource.
group?: string
// kind is kind of the target resource.
kind?: string
// name is the name of the target resource.
name?: string
// namespace is the namespace of the referent.
namespace?: string
}]
// Specifies the type of Wasm Extension to be used.
//
// Valid Options: HTTP, NETWORK
type?: "UNSPECIFIED_PLUGIN_TYPE" | "HTTP" | "NETWORK"
// URL of a Wasm module or OCI container.
url: strings.MinRunes(1)
verificationKey?: string
vmConfig?: {
// Specifies environment variables to be injected to this VM.
env?: list.MaxItems(256) & [...{
// Name of the environment variable.
name: strings.MaxRunes(256) & strings.MinRunes(1)
// Value for the environment variable.
value?: strings.MaxRunes(2048)
// Source for the environment variable's value.
//
// Valid Options: INLINE, HOST
valueFrom?: "INLINE" | "HOST"
}]
}
}

View File

@@ -0,0 +1,378 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-secrets-eso/prod-secrets-eso.gen.yaml
package v1beta1
import (
"strings"
"struct"
)
// ClusterExternalSecret is the Schema for the
// clusterexternalsecrets API.
#ClusterExternalSecret: {
// 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
apiVersion: "external-secrets.io/v1beta1"
// 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
kind: "ClusterExternalSecret"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ClusterExternalSecretSpec defines the desired state of
// ClusterExternalSecret.
spec!: #ClusterExternalSecretSpec
}
// ClusterExternalSecretSpec defines the desired state of
// ClusterExternalSecret.
#ClusterExternalSecretSpec: {
// The metadata of the external secrets to be created
externalSecretMetadata?: {
annotations?: {
[string]: string
}
labels?: {
[string]: string
}
}
// The name of the external secrets to be created defaults to the
// name of the ClusterExternalSecret
externalSecretName?: string
// The spec for the ExternalSecrets to be created
externalSecretSpec: {
// Data defines the connection between the Kubernetes Secret keys
// and the Provider data
data?: [...{
// RemoteRef points to the remote secret and defines
// which secret (version/property/..) to fetch.
remoteRef: {
// Used to define a conversion Strategy
conversionStrategy?: "Default" | "Unicode" | *"Default"
// Used to define a decoding Strategy
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
// Key is the key used in the Provider, mandatory
key: string
// Policy for fetching tags/labels from provider secrets, possible
// options are Fetch, None. Defaults to None
metadataPolicy?: "None" | "Fetch" | *"None"
// Used to select a specific property of the Provider value (if a
// map), if supported
property?: string
// Used to select a specific version of the Provider value, if
// supported
version?: string
}
// SecretKey defines the key in which the controller stores
// the value. This is the key in the Kind=Secret
secretKey: string
// SourceRef allows you to override the source
// from which the value will pulled from.
sourceRef?: struct.MaxFields(1) & {
// GeneratorRef points to a generator custom resource.
//
//
// Deprecated: The generatorRef is not implemented in .data[].
// this will be removed with v1.
generatorRef?: {
// Specify the apiVersion of the generator resource
apiVersion?: string | *"generators.external-secrets.io/v1alpha1"
// Specify the Kind of the resource, e.g. Password, ACRAccessToken
// etc.
kind: string
// Specify the name of the generator resource
name: string
}
// SecretStoreRef defines which SecretStore to fetch the
// ExternalSecret data.
storeRef?: {
// Kind of the SecretStore resource (SecretStore or
// ClusterSecretStore)
// Defaults to `SecretStore`
kind?: string
// Name of the SecretStore resource
name: string
}
}
}]
// DataFrom is used to fetch all properties from a specific
// Provider data
// If multiple entries are specified, the Secret keys are merged
// in the specified order
dataFrom?: [...{
// Used to extract multiple key/value pairs from one secret
// Note: Extract does not support sourceRef.Generator or
// sourceRef.GeneratorRef.
extract?: {
// Used to define a conversion Strategy
conversionStrategy?: "Default" | "Unicode" | *"Default"
// Used to define a decoding Strategy
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
// Key is the key used in the Provider, mandatory
key: string
// Policy for fetching tags/labels from provider secrets, possible
// options are Fetch, None. Defaults to None
metadataPolicy?: "None" | "Fetch" | *"None"
// Used to select a specific property of the Provider value (if a
// map), if supported
property?: string
// Used to select a specific version of the Provider value, if
// supported
version?: string
}
// Used to find secrets based on tags or regular expressions
// Note: Find does not support sourceRef.Generator or
// sourceRef.GeneratorRef.
find?: {
// Used to define a conversion Strategy
conversionStrategy?: "Default" | "Unicode" | *"Default"
// Used to define a decoding Strategy
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
name?: {
// Finds secrets base
regexp?: string
}
// A root path to start the find operations.
path?: string
// Find secrets based on tags.
tags?: {
[string]: string
}
}
// Used to rewrite secret Keys after getting them from the secret
// Provider
// Multiple Rewrite operations can be provided. They are applied
// in a layered order (first to last)
rewrite?: [...{
// Used to rewrite with regular expressions.
// The resulting key will be the output of a regexp.ReplaceAll
// operation.
regexp?: {
// Used to define the regular expression of a re.Compiler.
source: string
// Used to define the target pattern of a ReplaceAll operation.
target: string
}
transform?: {
// Used to define the template to apply on the secret name.
// `.value ` will specify the secret name in the template.
template: string
}
}]
// SourceRef points to a store or generator
// which contains secret values ready to use.
// Use this in combination with Extract or Find pull values out of
// a specific SecretStore.
// When sourceRef points to a generator Extract or Find is not
// supported.
// The generator returns a static map of values
sourceRef?: struct.MaxFields(1) & {
// GeneratorRef points to a generator custom resource.
generatorRef?: {
// Specify the apiVersion of the generator resource
apiVersion?: string | *"generators.external-secrets.io/v1alpha1"
// Specify the Kind of the resource, e.g. Password, ACRAccessToken
// etc.
kind: string
// Specify the name of the generator resource
name: string
}
// SecretStoreRef defines which SecretStore to fetch the
// ExternalSecret data.
storeRef?: {
// Kind of the SecretStore resource (SecretStore or
// ClusterSecretStore)
// Defaults to `SecretStore`
kind?: string
// Name of the SecretStore resource
name: string
}
}
}]
// RefreshInterval is the amount of time before the values are
// read again from the SecretStore provider
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
// May be set to zero to fetch and create it once. Defaults to 1h.
refreshInterval?: string | *"1h"
// SecretStoreRef defines which SecretStore to fetch the
// ExternalSecret data.
secretStoreRef?: {
// Kind of the SecretStore resource (SecretStore or
// ClusterSecretStore)
// Defaults to `SecretStore`
kind?: string
// Name of the SecretStore resource
name: string
}
// ExternalSecretTarget defines the Kubernetes Secret to be
// created
// There can be only one target per ExternalSecret.
target?: {
// CreationPolicy defines rules on how to create the resulting
// Secret
// Defaults to 'Owner'
creationPolicy?: "Owner" | "Orphan" | "Merge" | "None" | *"Owner"
// DeletionPolicy defines rules on how to delete the resulting
// Secret
// Defaults to 'Retain'
deletionPolicy?: "Delete" | "Merge" | "Retain" | *"Retain"
// Immutable defines if the final secret will be immutable
immutable?: bool
// Name defines the name of the Secret resource to be managed
// This field is immutable
// Defaults to the .metadata.name of the ExternalSecret resource
name?: string
// Template defines a blueprint for the created Secret resource.
template?: {
data?: {
[string]: string
}
// EngineVersion specifies the template engine version
// that should be used to compile/execute the
// template specified in .data and .templateFrom[].
engineVersion?: "v1" | "v2" | *"v2"
mergePolicy?: "Replace" | "Merge" | *"Replace"
// ExternalSecretTemplateMetadata defines metadata fields for the
// Secret blueprint.
metadata?: {
annotations?: {
[string]: string
}
labels?: {
[string]: string
}
}
templateFrom?: [...{
configMap?: {
items: [...{
key: string
templateAs?: "Values" | "KeysAndValues" | *"Values"
}]
name: string
}
literal?: string
secret?: {
items: [...{
key: string
templateAs?: "Values" | "KeysAndValues" | *"Values"
}]
name: string
}
target?: "Data" | "Annotations" | "Labels" | *"Data"
}]
type?: string
}
} | *{
creationPolicy: "Owner"
deletionPolicy: "Retain"
}
}
// The labels to select by to find the Namespaces to create the
// ExternalSecrets in.
namespaceSelector?: {
// matchExpressions is a list of label selector requirements. The
// requirements are ANDed.
matchExpressions?: [...{
// key is the label key that the selector applies to.
key: string
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
operator: string
// 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.
values?: [...string]
}]
// 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.
matchLabels?: {
[string]: string
}
}
// Choose namespaces by name. This field is ORed with anything
// that NamespaceSelector ends up choosing.
namespaces?: [...string]
// The time in which the controller should reconcile its objects
// and recheck namespaces for labels.
refreshTime?: string
}

View File

@@ -0,0 +1,168 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-secrets-eso/prod-secrets-eso.gen.yaml
package v1alpha1
import (
"strings"
"struct"
)
// ExternalSecret is the Schema for the external-secrets API.
#ExternalSecret: {
// 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
apiVersion: "external-secrets.io/v1alpha1"
// 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
kind: "ExternalSecret"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ExternalSecretSpec defines the desired state of ExternalSecret.
spec!: #ExternalSecretSpec
}
// ExternalSecretSpec defines the desired state of ExternalSecret.
#ExternalSecretSpec: {
// Data defines the connection between the Kubernetes Secret keys
// and the Provider data
data?: [...{
// ExternalSecretDataRemoteRef defines Provider data location.
remoteRef: {
// Used to define a conversion Strategy
conversionStrategy?: "Default" | "Unicode" | *"Default"
// Key is the key used in the Provider, mandatory
key: string
// Used to select a specific property of the Provider value (if a
// map), if supported
property?: string
// Used to select a specific version of the Provider value, if
// supported
version?: string
}
secretKey: string
}]
// DataFrom is used to fetch all properties from a specific
// Provider data
// If multiple entries are specified, the Secret keys are merged
// in the specified order
dataFrom?: [...{
// Used to define a conversion Strategy
conversionStrategy?: "Default" | "Unicode" | *"Default"
// Key is the key used in the Provider, mandatory
key: string
// Used to select a specific property of the Provider value (if a
// map), if supported
property?: string
// Used to select a specific version of the Provider value, if
// supported
version?: string
}]
// RefreshInterval is the amount of time before the values are
// read again from the SecretStore provider
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
// May be set to zero to fetch and create it once. Defaults to 1h.
refreshInterval?: string | *"1h"
// SecretStoreRef defines which SecretStore to fetch the
// ExternalSecret data.
secretStoreRef: {
// Kind of the SecretStore resource (SecretStore or
// ClusterSecretStore)
// Defaults to `SecretStore`
kind?: string
// Name of the SecretStore resource
name: string
}
// ExternalSecretTarget defines the Kubernetes Secret to be
// created
// There can be only one target per ExternalSecret.
target: {
// CreationPolicy defines rules on how to create the resulting
// Secret
// Defaults to 'Owner'
creationPolicy?: "Owner" | "Merge" | "None" | *"Owner"
// Immutable defines if the final secret will be immutable
immutable?: bool
// Name defines the name of the Secret resource to be managed
// This field is immutable
// Defaults to the .metadata.name of the ExternalSecret resource
name?: string
// Template defines a blueprint for the created Secret resource.
template?: {
data?: {
[string]: string
}
// EngineVersion specifies the template engine version
// that should be used to compile/execute the
// template specified in .data and .templateFrom[].
engineVersion?: "v1" | "v2" | *"v1"
// ExternalSecretTemplateMetadata defines metadata fields for the
// Secret blueprint.
metadata?: {
annotations?: {
[string]: string
}
labels?: {
[string]: string
}
}
templateFrom?: [...struct.MaxFields(1) & {
configMap?: {
items: [...{
key: string
}]
name: string
}
secret?: {
items: [...{
key: string
}]
name: string
}
}]
type?: string
}
}
}

View File

@@ -0,0 +1,316 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-secrets-eso/prod-secrets-eso.gen.yaml
package v1beta1
import (
"strings"
"struct"
)
// ExternalSecret is the Schema for the external-secrets API.
#ExternalSecret: {
// 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
apiVersion: "external-secrets.io/v1beta1"
// 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
kind: "ExternalSecret"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ExternalSecretSpec defines the desired state of ExternalSecret.
spec!: #ExternalSecretSpec
}
// ExternalSecretSpec defines the desired state of ExternalSecret.
#ExternalSecretSpec: {
// Data defines the connection between the Kubernetes Secret keys
// and the Provider data
data?: [...{
// RemoteRef points to the remote secret and defines
// which secret (version/property/..) to fetch.
remoteRef: {
// Used to define a conversion Strategy
conversionStrategy?: "Default" | "Unicode" | *"Default"
// Used to define a decoding Strategy
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
// Key is the key used in the Provider, mandatory
key: string
// Policy for fetching tags/labels from provider secrets, possible
// options are Fetch, None. Defaults to None
metadataPolicy?: "None" | "Fetch" | *"None"
// Used to select a specific property of the Provider value (if a
// map), if supported
property?: string
// Used to select a specific version of the Provider value, if
// supported
version?: string
}
// SecretKey defines the key in which the controller stores
// the value. This is the key in the Kind=Secret
secretKey: string
// SourceRef allows you to override the source
// from which the value will pulled from.
sourceRef?: struct.MaxFields(1) & {
// GeneratorRef points to a generator custom resource.
//
//
// Deprecated: The generatorRef is not implemented in .data[].
// this will be removed with v1.
generatorRef?: {
// Specify the apiVersion of the generator resource
apiVersion?: string | *"generators.external-secrets.io/v1alpha1"
// Specify the Kind of the resource, e.g. Password, ACRAccessToken
// etc.
kind: string
// Specify the name of the generator resource
name: string
}
// SecretStoreRef defines which SecretStore to fetch the
// ExternalSecret data.
storeRef?: {
// Kind of the SecretStore resource (SecretStore or
// ClusterSecretStore)
// Defaults to `SecretStore`
kind?: string
// Name of the SecretStore resource
name: string
}
}
}]
// DataFrom is used to fetch all properties from a specific
// Provider data
// If multiple entries are specified, the Secret keys are merged
// in the specified order
dataFrom?: [...{
// Used to extract multiple key/value pairs from one secret
// Note: Extract does not support sourceRef.Generator or
// sourceRef.GeneratorRef.
extract?: {
// Used to define a conversion Strategy
conversionStrategy?: "Default" | "Unicode" | *"Default"
// Used to define a decoding Strategy
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
// Key is the key used in the Provider, mandatory
key: string
// Policy for fetching tags/labels from provider secrets, possible
// options are Fetch, None. Defaults to None
metadataPolicy?: "None" | "Fetch" | *"None"
// Used to select a specific property of the Provider value (if a
// map), if supported
property?: string
// Used to select a specific version of the Provider value, if
// supported
version?: string
}
// Used to find secrets based on tags or regular expressions
// Note: Find does not support sourceRef.Generator or
// sourceRef.GeneratorRef.
find?: {
// Used to define a conversion Strategy
conversionStrategy?: "Default" | "Unicode" | *"Default"
// Used to define a decoding Strategy
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
name?: {
// Finds secrets base
regexp?: string
}
// A root path to start the find operations.
path?: string
// Find secrets based on tags.
tags?: {
[string]: string
}
}
// Used to rewrite secret Keys after getting them from the secret
// Provider
// Multiple Rewrite operations can be provided. They are applied
// in a layered order (first to last)
rewrite?: [...{
// Used to rewrite with regular expressions.
// The resulting key will be the output of a regexp.ReplaceAll
// operation.
regexp?: {
// Used to define the regular expression of a re.Compiler.
source: string
// Used to define the target pattern of a ReplaceAll operation.
target: string
}
transform?: {
// Used to define the template to apply on the secret name.
// `.value ` will specify the secret name in the template.
template: string
}
}]
// SourceRef points to a store or generator
// which contains secret values ready to use.
// Use this in combination with Extract or Find pull values out of
// a specific SecretStore.
// When sourceRef points to a generator Extract or Find is not
// supported.
// The generator returns a static map of values
sourceRef?: struct.MaxFields(1) & {
// GeneratorRef points to a generator custom resource.
generatorRef?: {
// Specify the apiVersion of the generator resource
apiVersion?: string | *"generators.external-secrets.io/v1alpha1"
// Specify the Kind of the resource, e.g. Password, ACRAccessToken
// etc.
kind: string
// Specify the name of the generator resource
name: string
}
// SecretStoreRef defines which SecretStore to fetch the
// ExternalSecret data.
storeRef?: {
// Kind of the SecretStore resource (SecretStore or
// ClusterSecretStore)
// Defaults to `SecretStore`
kind?: string
// Name of the SecretStore resource
name: string
}
}
}]
// RefreshInterval is the amount of time before the values are
// read again from the SecretStore provider
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
// May be set to zero to fetch and create it once. Defaults to 1h.
refreshInterval?: string | *"1h"
// SecretStoreRef defines which SecretStore to fetch the
// ExternalSecret data.
secretStoreRef?: {
// Kind of the SecretStore resource (SecretStore or
// ClusterSecretStore)
// Defaults to `SecretStore`
kind?: string
// Name of the SecretStore resource
name: string
}
// ExternalSecretTarget defines the Kubernetes Secret to be
// created
// There can be only one target per ExternalSecret.
target?: {
// CreationPolicy defines rules on how to create the resulting
// Secret
// Defaults to 'Owner'
creationPolicy?: "Owner" | "Orphan" | "Merge" | "None" | *"Owner"
// DeletionPolicy defines rules on how to delete the resulting
// Secret
// Defaults to 'Retain'
deletionPolicy?: "Delete" | "Merge" | "Retain" | *"Retain"
// Immutable defines if the final secret will be immutable
immutable?: bool
// Name defines the name of the Secret resource to be managed
// This field is immutable
// Defaults to the .metadata.name of the ExternalSecret resource
name?: string
// Template defines a blueprint for the created Secret resource.
template?: {
data?: {
[string]: string
}
// EngineVersion specifies the template engine version
// that should be used to compile/execute the
// template specified in .data and .templateFrom[].
engineVersion?: "v1" | "v2" | *"v2"
mergePolicy?: "Replace" | "Merge" | *"Replace"
// ExternalSecretTemplateMetadata defines metadata fields for the
// Secret blueprint.
metadata?: {
annotations?: {
[string]: string
}
labels?: {
[string]: string
}
}
templateFrom?: [...{
configMap?: {
items: [...{
key: string
templateAs?: "Values" | "KeysAndValues" | *"Values"
}]
name: string
}
literal?: string
secret?: {
items: [...{
key: string
templateAs?: "Values" | "KeysAndValues" | *"Values"
}]
name: string
}
target?: "Data" | "Annotations" | "Labels" | *"Data"
}]
type?: string
}
} | *{
creationPolicy: "Owner"
deletionPolicy: "Retain"
}
}

View File

@@ -0,0 +1,171 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-secrets-eso/prod-secrets-eso.gen.yaml
package v1alpha1
import "strings"
#PushSecret: {
// 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
apiVersion: "external-secrets.io/v1alpha1"
// 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
kind: "PushSecret"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// PushSecretSpec configures the behavior of the PushSecret.
spec!: #PushSecretSpec
}
// PushSecretSpec configures the behavior of the PushSecret.
#PushSecretSpec: {
// Secret Data that should be pushed to providers
data?: [...{
// Match a given Secret Key to be pushed to the provider.
match: {
// Remote Refs to push to providers.
remoteRef: {
// Name of the property in the resulting secret
property?: string
// Name of the resulting provider secret.
remoteKey: string
}
// Secret Key to be pushed
secretKey?: string
}
// Metadata is metadata attached to the secret.
// The structure of metadata is provider specific, please look it
// up in the provider documentation.
metadata?: _
}]
// Deletion Policy to handle Secrets in the provider. Possible
// Values: "Delete/None". Defaults to "None".
deletionPolicy?: "Delete" | "None" | *"None"
// The Interval to which External Secrets will try to push a
// secret definition
refreshInterval?: string
secretStoreRefs: [...{
// Kind of the SecretStore resource (SecretStore or
// ClusterSecretStore)
// Defaults to `SecretStore`
kind?: string | *"SecretStore"
// Optionally, sync to secret stores with label selector
labelSelector?: {
// matchExpressions is a list of label selector requirements. The
// requirements are ANDed.
matchExpressions?: [...{
// key is the label key that the selector applies to.
key: string
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
operator: string
// 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.
values?: [...string]
}]
// 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.
matchLabels?: {
[string]: string
}
}
// Optionally, sync to the SecretStore of the given name
name?: string
}]
selector: {
secret: {
// Name of the Secret. The Secret must exist in the same namespace
// as the PushSecret manifest.
name: string
}
}
// Template defines a blueprint for the created Secret resource.
template?: {
data?: {
[string]: string
}
// EngineVersion specifies the template engine version
// that should be used to compile/execute the
// template specified in .data and .templateFrom[].
engineVersion?: "v1" | "v2" | *"v2"
mergePolicy?: "Replace" | "Merge" | *"Replace"
// ExternalSecretTemplateMetadata defines metadata fields for the
// Secret blueprint.
metadata?: {
annotations?: {
[string]: string
}
labels?: {
[string]: string
}
}
templateFrom?: [...{
configMap?: {
items: [...{
key: string
templateAs?: "Values" | "KeysAndValues" | *"Values"
}]
name: string
}
literal?: string
secret?: {
items: [...{
key: string
templateAs?: "Values" | "KeysAndValues" | *"Values"
}]
name: string
}
target?: "Data" | "Annotations" | "Labels" | *"Data"
}]
type?: string
}
}

View File

@@ -0,0 +1,672 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
package v1
import (
"strings"
"list"
"struct"
)
// Gateway represents an instance of a service-traffic handling
// infrastructure
// by binding Listeners to a set of IP addresses.
#Gateway: {
// 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
apiVersion: "gateway.networking.k8s.io/v1"
// 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
kind: "Gateway"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// Spec defines the desired state of Gateway.
spec!: #GatewaySpec
}
// Spec defines the desired state of Gateway.
#GatewaySpec: {
// 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.
//
//
// 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.
//
//
// If no Addresses are specified, the implementation MAY schedule
// the
// Gateway in an implementation-specific manner, assigning an
// appropriate
// set of Addresses.
//
//
// The implementation MUST bind all Listeners to every
// GatewayAddress that
// it assigns to the Gateway and add a corresponding entry in
// GatewayStatus.Addresses.
//
//
// Support: Extended
addresses?: list.MaxItems(16) & [...({
type?: "IPAddress"
value?: (_ | _) & {
_
}
} | {
type?: _
}) & {
// Type of the address.
type?: strings.MaxRunes(253) & strings.MinRunes(1) & =~"^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$" | *"IPAddress"
// Value of the address. The validity of the values will depend
// on the type and support by the controller.
//
//
// Examples: `1.2.3.4`, `128::1`, `my-ip-address`.
value: strings.MaxRunes(253) & strings.MinRunes(1)
}]
// GatewayClassName used for this Gateway. This is the name of a
// GatewayClass resource.
gatewayClassName: strings.MaxRunes(253) & strings.MinRunes(1)
// Listeners associated with this Gateway. Listeners define
// logical endpoints that are bound on this Gateway's addresses.
// At least one Listener MUST be specified.
//
//
// Each Listener in a set of Listeners (for example, in a single
// Gateway)
// MUST be _distinct_, in that a traffic flow MUST be able to be
// assigned to
// exactly one listener. (This section uses "set of Listeners"
// rather than
// "Listeners in a single Gateway" because implementations MAY
// merge configuration
// from multiple Gateways onto a single data plane, and these
// rules _also_
// apply in that case).
//
//
// Practically, this means that each listener in a set MUST have a
// unique
// combination of Port, Protocol, and, if supported by the
// protocol, Hostname.
//
//
// Some combinations of port, protocol, and TLS settings are
// considered
// Core support and MUST be supported by implementations based on
// their
// targeted conformance profile:
//
//
// HTTP Profile
//
//
// 1. HTTPRoute, Port: 80, Protocol: HTTP
// 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate,
// TLS keypair provided
//
//
// TLS Profile
//
//
// 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough
//
//
// "Distinct" Listeners have the following property:
//
//
// The implementation can match inbound requests to a single
// distinct
// Listener. When multiple Listeners share values for fields (for
// example, two Listeners with the same Port value), the
// implementation
// can match requests to only one of the Listeners using other
// Listener fields.
//
//
// For example, the following Listener scenarios are distinct:
//
//
// 1. Multiple Listeners with the same Port that all use the
// "HTTP"
// Protocol that all have unique Hostname values.
// 2. Multiple Listeners with the same Port that use either the
// "HTTPS" or
// "TLS" Protocol that all have unique Hostname values.
// 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no
// Listener
// with the same Protocol has the same Port value.
//
//
// Some fields in the Listener struct have possible values that
// affect
// whether the Listener is distinct. Hostname is particularly
// relevant
// for HTTP or HTTPS protocols.
//
//
// When using the Hostname value to select between same-Port,
// same-Protocol
// Listeners, the Hostname value must be different on each
// Listener for the
// Listener to be distinct.
//
//
// When the Listeners are distinct based on Hostname, inbound
// request
// hostnames MUST match from the most specific to least specific
// Hostname
// values to choose the correct Listener and its associated set of
// Routes.
//
//
// Exact matches must be processed before wildcard matches, and
// wildcard
// matches must be processed before fallback (empty Hostname
// value)
// matches. For example, `"foo.example.com"` takes precedence over
// `"*.example.com"`, and `"*.example.com"` takes precedence over
// `""`.
//
//
// Additionally, if there are multiple wildcard entries, more
// specific
// wildcard entries must be processed before less specific
// wildcard entries.
// For example, `"*.foo.example.com"` takes precedence over
// `"*.example.com"`.
// The precise definition here is that the higher the number of
// dots in the
// hostname to the right of the wildcard character, the higher the
// precedence.
//
//
// The wildcard character will match any number of characters _and
// dots_ to
// the left, however, so `"*.example.com"` will match both
// `"foo.bar.example.com"` _and_ `"bar.example.com"`.
//
//
// If a set of Listeners contains Listeners that are not distinct,
// then those
// Listeners are Conflicted, and the implementation MUST set the
// "Conflicted"
// condition in the Listener Status to "True".
//
//
// Implementations MAY choose to accept a Gateway with some
// Conflicted
// Listeners only if they only accept the partial Listener set
// that contains
// no Conflicted Listeners. To put this another way,
// implementations may
// accept a partial Listener set only if they throw out *all* the
// conflicting
// Listeners. No picking one of the conflicting listeners as the
// winner.
// This also means that the Gateway must have at least one
// non-conflicting
// Listener in this case, otherwise it violates the requirement
// that at
// least one Listener must be present.
//
//
// The implementation MUST set a "ListenersNotValid" condition on
// the
// Gateway Status when the Gateway contains Conflicted Listeners
// whether or
// not they accept the Gateway. That Condition SHOULD clearly
// indicate in the Message which Listeners are conflicted, and
// which are
// Accepted. Additionally, the Listener status for those listeners
// SHOULD
// indicate which Listeners are conflicted and not Accepted.
//
//
// A Gateway's Listeners are considered "compatible" if:
//
//
// 1. They are distinct.
// 2. The implementation can serve them in compliance with the
// Addresses
// requirement that all Listeners are available on all assigned
// addresses.
//
//
// Compatible combinations in Extended support are expected to
// vary across
// implementations. A combination that is compatible for one
// implementation
// may not be compatible for another.
//
//
// For example, an implementation that cannot serve both TCP and
// UDP listeners
// on the same address, or cannot mix HTTPS and generic TLS
// listens on the same port
// would not consider those cases compatible, even though they are
// distinct.
//
//
// Note that requests SHOULD match at most one Listener. For
// example, if
// Listeners are defined for "foo.example.com" and
// "*.example.com", a
// request to "foo.example.com" SHOULD only be routed using routes
// attached
// to the "foo.example.com" Listener (and not the "*.example.com"
// Listener).
// This concept is known as "Listener Isolation". Implementations
// that do
// not support Listener Isolation MUST clearly document this.
//
//
// Implementations MAY merge separate Gateways onto a single set
// of
// Addresses if all Listeners across all Gateways are compatible.
//
//
// Support: Core
listeners: list.MaxItems(64) & [...{
// AllowedRoutes defines the types of routes that MAY be attached
// to a
// Listener and the trusted namespaces where those Route resources
// MAY be
// present.
//
//
// 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:
//
//
// * 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.
//
//
// 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.
//
//
// Support: Core
allowedRoutes?: {
// 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.
//
//
// 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
// "InvalidRouteKinds" reason.
//
//
// Support: Core
kinds?: list.MaxItems(8) & [...{
// Group is the group of the Route.
group?: strings.MaxRunes(253) & =~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | *"gateway.networking.k8s.io"
// Kind is the kind of the Route.
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
}
}]
// Namespaces indicates namespaces from which Routes may be
// attached to this
// Listener. This is restricted to the namespace of this Gateway
// by default.
//
//
// Support: Core
namespaces?: {
// 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.
//
//
// Support: Core
from?: "All" | "Selector" | "Same" | *"Same"
// 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".
//
//
// Support: Core
selector?: {
// matchExpressions is a list of label selector requirements. The
// requirements are ANDed.
matchExpressions?: [...{
// key is the label key that the selector applies to.
key: string
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
operator: string
// 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.
values?: [...string]
}]
// 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.
matchLabels?: {
[string]: string
}
}
} | *{
from: "Same"
}
} | *{
namespaces: {
from: "Same"
}
}
// 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.
//
//
// Implementations MUST apply Hostname matching appropriately for
// each of
// the following protocols:
//
//
// * 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.
//
//
// 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.
//
//
// Hostnames that are prefixed with a wildcard label (`*.`) are
// interpreted
// as a suffix match. That means that a match for `*.example.com`
// would match
// both `test.example.com`, and `foo.test.example.com`, but not
// `example.com`.
//
//
// Support: Core
hostname?: strings.MaxRunes(253) & strings.MinRunes(1) & {
=~"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// Name is the name of the Listener. This name MUST be unique
// within a
// Gateway.
//
//
// Support: Core
name: strings.MaxRunes(253) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// Port is the network port. Multiple listeners may use the
// same port, subject to the Listener compatibility rules.
//
//
// Support: Core
port: uint16 & >=1
// Protocol specifies the network protocol this listener expects
// to receive.
//
//
// Support: Core
protocol: strings.MaxRunes(255) & strings.MinRunes(1) & {
=~"^[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]+$"
}
// 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".
//
//
// The association of SNIs to Certificate defined in
// GatewayTLSConfig is
// defined based on the Hostname field for this listener.
//
//
// The GatewayClass MUST use the longest matching SNI out of all
// available certificates for any TLS handshake.
//
//
// Support: Core
tls?: {
// 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.
//
//
// 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.
//
//
// References to a resource in different namespace are invalid
// UNLESS there
// is a ReferenceGrant in the target namespace that allows the
// certificate
// to be attached. If a ReferenceGrant does not allow this
// reference, the
// "ResolvedRefs" condition MUST be set to False for this listener
// with the
// "RefNotPermitted" reason.
//
//
// This field is required to have at least one element when the
// mode is set
// to "Terminate" (default) and is optional otherwise.
//
//
// CertificateRefs can reference to standard Kubernetes resources,
// i.e.
// Secret, or implementation-specific custom resources.
//
//
// Support: Core - A single reference to a Kubernetes Secret of
// type kubernetes.io/tls
//
//
// Support: Implementation-specific (More than one reference or
// other resource types)
certificateRefs?: list.MaxItems(64) & [...{
// Group is the group of the referent. For example,
// "gateway.networking.k8s.io".
// When unspecified or empty string, core API group is inferred.
group?: strings.MaxRunes(253) & =~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | *""
// Kind is kind of the referent. For example "Secret".
kind?: strings.MaxRunes(63) & strings.MinRunes(1) & =~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$" | *"Secret"
// Name is the name of the referent.
name: strings.MaxRunes(253) & strings.MinRunes(1)
// Namespace is the namespace of the referenced object. When
// unspecified, the local
// namespace is inferred.
//
//
// Note that when a namespace different than the local namespace
// is specified,
// a ReferenceGrant object is required in the referent namespace
// to allow that
// namespace's owner to accept the reference. See the
// ReferenceGrant
// documentation for details.
//
//
// Support: Core
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
}
}]
// Mode defines the TLS behavior for the TLS session initiated by
// the client.
// There are two possible modes:
//
//
// - Terminate: The TLS session between the downstream client and
// the
// Gateway is terminated at the Gateway. This mode requires
// certificates
// to be specified in some way, such as populating the
// certificateRefs
// field.
// - 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. The
// certificateRefs field
// is ignored in this mode.
//
//
// Support: Core
mode?: "Terminate" | "Passthrough" | *"Terminate"
// 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.
//
//
// 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.
//
//
// Support: Implementation-specific
options?: struct.MaxFields(16) & {
{
[string]: strings.MaxRunes(4096) & strings.MinRunes(0)
}
}
}
}] & [_, ...]
}

View File

@@ -0,0 +1,672 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
package v1beta1
import (
"strings"
"list"
"struct"
)
// Gateway represents an instance of a service-traffic handling
// infrastructure
// by binding Listeners to a set of IP addresses.
#Gateway: {
// 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
apiVersion: "gateway.networking.k8s.io/v1beta1"
// 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
kind: "Gateway"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// Spec defines the desired state of Gateway.
spec!: #GatewaySpec
}
// Spec defines the desired state of Gateway.
#GatewaySpec: {
// 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.
//
//
// 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.
//
//
// If no Addresses are specified, the implementation MAY schedule
// the
// Gateway in an implementation-specific manner, assigning an
// appropriate
// set of Addresses.
//
//
// The implementation MUST bind all Listeners to every
// GatewayAddress that
// it assigns to the Gateway and add a corresponding entry in
// GatewayStatus.Addresses.
//
//
// Support: Extended
addresses?: list.MaxItems(16) & [...({
type?: "IPAddress"
value?: (_ | _) & {
_
}
} | {
type?: _
}) & {
// Type of the address.
type?: strings.MaxRunes(253) & strings.MinRunes(1) & =~"^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$" | *"IPAddress"
// Value of the address. The validity of the values will depend
// on the type and support by the controller.
//
//
// Examples: `1.2.3.4`, `128::1`, `my-ip-address`.
value: strings.MaxRunes(253) & strings.MinRunes(1)
}]
// GatewayClassName used for this Gateway. This is the name of a
// GatewayClass resource.
gatewayClassName: strings.MaxRunes(253) & strings.MinRunes(1)
// Listeners associated with this Gateway. Listeners define
// logical endpoints that are bound on this Gateway's addresses.
// At least one Listener MUST be specified.
//
//
// Each Listener in a set of Listeners (for example, in a single
// Gateway)
// MUST be _distinct_, in that a traffic flow MUST be able to be
// assigned to
// exactly one listener. (This section uses "set of Listeners"
// rather than
// "Listeners in a single Gateway" because implementations MAY
// merge configuration
// from multiple Gateways onto a single data plane, and these
// rules _also_
// apply in that case).
//
//
// Practically, this means that each listener in a set MUST have a
// unique
// combination of Port, Protocol, and, if supported by the
// protocol, Hostname.
//
//
// Some combinations of port, protocol, and TLS settings are
// considered
// Core support and MUST be supported by implementations based on
// their
// targeted conformance profile:
//
//
// HTTP Profile
//
//
// 1. HTTPRoute, Port: 80, Protocol: HTTP
// 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate,
// TLS keypair provided
//
//
// TLS Profile
//
//
// 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough
//
//
// "Distinct" Listeners have the following property:
//
//
// The implementation can match inbound requests to a single
// distinct
// Listener. When multiple Listeners share values for fields (for
// example, two Listeners with the same Port value), the
// implementation
// can match requests to only one of the Listeners using other
// Listener fields.
//
//
// For example, the following Listener scenarios are distinct:
//
//
// 1. Multiple Listeners with the same Port that all use the
// "HTTP"
// Protocol that all have unique Hostname values.
// 2. Multiple Listeners with the same Port that use either the
// "HTTPS" or
// "TLS" Protocol that all have unique Hostname values.
// 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no
// Listener
// with the same Protocol has the same Port value.
//
//
// Some fields in the Listener struct have possible values that
// affect
// whether the Listener is distinct. Hostname is particularly
// relevant
// for HTTP or HTTPS protocols.
//
//
// When using the Hostname value to select between same-Port,
// same-Protocol
// Listeners, the Hostname value must be different on each
// Listener for the
// Listener to be distinct.
//
//
// When the Listeners are distinct based on Hostname, inbound
// request
// hostnames MUST match from the most specific to least specific
// Hostname
// values to choose the correct Listener and its associated set of
// Routes.
//
//
// Exact matches must be processed before wildcard matches, and
// wildcard
// matches must be processed before fallback (empty Hostname
// value)
// matches. For example, `"foo.example.com"` takes precedence over
// `"*.example.com"`, and `"*.example.com"` takes precedence over
// `""`.
//
//
// Additionally, if there are multiple wildcard entries, more
// specific
// wildcard entries must be processed before less specific
// wildcard entries.
// For example, `"*.foo.example.com"` takes precedence over
// `"*.example.com"`.
// The precise definition here is that the higher the number of
// dots in the
// hostname to the right of the wildcard character, the higher the
// precedence.
//
//
// The wildcard character will match any number of characters _and
// dots_ to
// the left, however, so `"*.example.com"` will match both
// `"foo.bar.example.com"` _and_ `"bar.example.com"`.
//
//
// If a set of Listeners contains Listeners that are not distinct,
// then those
// Listeners are Conflicted, and the implementation MUST set the
// "Conflicted"
// condition in the Listener Status to "True".
//
//
// Implementations MAY choose to accept a Gateway with some
// Conflicted
// Listeners only if they only accept the partial Listener set
// that contains
// no Conflicted Listeners. To put this another way,
// implementations may
// accept a partial Listener set only if they throw out *all* the
// conflicting
// Listeners. No picking one of the conflicting listeners as the
// winner.
// This also means that the Gateway must have at least one
// non-conflicting
// Listener in this case, otherwise it violates the requirement
// that at
// least one Listener must be present.
//
//
// The implementation MUST set a "ListenersNotValid" condition on
// the
// Gateway Status when the Gateway contains Conflicted Listeners
// whether or
// not they accept the Gateway. That Condition SHOULD clearly
// indicate in the Message which Listeners are conflicted, and
// which are
// Accepted. Additionally, the Listener status for those listeners
// SHOULD
// indicate which Listeners are conflicted and not Accepted.
//
//
// A Gateway's Listeners are considered "compatible" if:
//
//
// 1. They are distinct.
// 2. The implementation can serve them in compliance with the
// Addresses
// requirement that all Listeners are available on all assigned
// addresses.
//
//
// Compatible combinations in Extended support are expected to
// vary across
// implementations. A combination that is compatible for one
// implementation
// may not be compatible for another.
//
//
// For example, an implementation that cannot serve both TCP and
// UDP listeners
// on the same address, or cannot mix HTTPS and generic TLS
// listens on the same port
// would not consider those cases compatible, even though they are
// distinct.
//
//
// Note that requests SHOULD match at most one Listener. For
// example, if
// Listeners are defined for "foo.example.com" and
// "*.example.com", a
// request to "foo.example.com" SHOULD only be routed using routes
// attached
// to the "foo.example.com" Listener (and not the "*.example.com"
// Listener).
// This concept is known as "Listener Isolation". Implementations
// that do
// not support Listener Isolation MUST clearly document this.
//
//
// Implementations MAY merge separate Gateways onto a single set
// of
// Addresses if all Listeners across all Gateways are compatible.
//
//
// Support: Core
listeners: list.MaxItems(64) & [...{
// AllowedRoutes defines the types of routes that MAY be attached
// to a
// Listener and the trusted namespaces where those Route resources
// MAY be
// present.
//
//
// 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:
//
//
// * 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.
//
//
// 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.
//
//
// Support: Core
allowedRoutes?: {
// 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.
//
//
// 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
// "InvalidRouteKinds" reason.
//
//
// Support: Core
kinds?: list.MaxItems(8) & [...{
// Group is the group of the Route.
group?: strings.MaxRunes(253) & =~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | *"gateway.networking.k8s.io"
// Kind is the kind of the Route.
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
}
}]
// Namespaces indicates namespaces from which Routes may be
// attached to this
// Listener. This is restricted to the namespace of this Gateway
// by default.
//
//
// Support: Core
namespaces?: {
// 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.
//
//
// Support: Core
from?: "All" | "Selector" | "Same" | *"Same"
// 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".
//
//
// Support: Core
selector?: {
// matchExpressions is a list of label selector requirements. The
// requirements are ANDed.
matchExpressions?: [...{
// key is the label key that the selector applies to.
key: string
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
operator: string
// 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.
values?: [...string]
}]
// 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.
matchLabels?: {
[string]: string
}
}
} | *{
from: "Same"
}
} | *{
namespaces: {
from: "Same"
}
}
// 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.
//
//
// Implementations MUST apply Hostname matching appropriately for
// each of
// the following protocols:
//
//
// * 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.
//
//
// 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.
//
//
// Hostnames that are prefixed with a wildcard label (`*.`) are
// interpreted
// as a suffix match. That means that a match for `*.example.com`
// would match
// both `test.example.com`, and `foo.test.example.com`, but not
// `example.com`.
//
//
// Support: Core
hostname?: strings.MaxRunes(253) & strings.MinRunes(1) & {
=~"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// Name is the name of the Listener. This name MUST be unique
// within a
// Gateway.
//
//
// Support: Core
name: strings.MaxRunes(253) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// Port is the network port. Multiple listeners may use the
// same port, subject to the Listener compatibility rules.
//
//
// Support: Core
port: uint16 & >=1
// Protocol specifies the network protocol this listener expects
// to receive.
//
//
// Support: Core
protocol: strings.MaxRunes(255) & strings.MinRunes(1) & {
=~"^[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]+$"
}
// 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".
//
//
// The association of SNIs to Certificate defined in
// GatewayTLSConfig is
// defined based on the Hostname field for this listener.
//
//
// The GatewayClass MUST use the longest matching SNI out of all
// available certificates for any TLS handshake.
//
//
// Support: Core
tls?: {
// 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.
//
//
// 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.
//
//
// References to a resource in different namespace are invalid
// UNLESS there
// is a ReferenceGrant in the target namespace that allows the
// certificate
// to be attached. If a ReferenceGrant does not allow this
// reference, the
// "ResolvedRefs" condition MUST be set to False for this listener
// with the
// "RefNotPermitted" reason.
//
//
// This field is required to have at least one element when the
// mode is set
// to "Terminate" (default) and is optional otherwise.
//
//
// CertificateRefs can reference to standard Kubernetes resources,
// i.e.
// Secret, or implementation-specific custom resources.
//
//
// Support: Core - A single reference to a Kubernetes Secret of
// type kubernetes.io/tls
//
//
// Support: Implementation-specific (More than one reference or
// other resource types)
certificateRefs?: list.MaxItems(64) & [...{
// Group is the group of the referent. For example,
// "gateway.networking.k8s.io".
// When unspecified or empty string, core API group is inferred.
group?: strings.MaxRunes(253) & =~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | *""
// Kind is kind of the referent. For example "Secret".
kind?: strings.MaxRunes(63) & strings.MinRunes(1) & =~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$" | *"Secret"
// Name is the name of the referent.
name: strings.MaxRunes(253) & strings.MinRunes(1)
// Namespace is the namespace of the referenced object. When
// unspecified, the local
// namespace is inferred.
//
//
// Note that when a namespace different than the local namespace
// is specified,
// a ReferenceGrant object is required in the referent namespace
// to allow that
// namespace's owner to accept the reference. See the
// ReferenceGrant
// documentation for details.
//
//
// Support: Core
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
}
}]
// Mode defines the TLS behavior for the TLS session initiated by
// the client.
// There are two possible modes:
//
//
// - Terminate: The TLS session between the downstream client and
// the
// Gateway is terminated at the Gateway. This mode requires
// certificates
// to be specified in some way, such as populating the
// certificateRefs
// field.
// - 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. The
// certificateRefs field
// is ignored in this mode.
//
//
// Support: Core
mode?: "Terminate" | "Passthrough" | *"Terminate"
// 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.
//
//
// 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.
//
//
// Support: Implementation-specific
options?: struct.MaxFields(16) & {
{
[string]: strings.MaxRunes(4096) & strings.MinRunes(0)
}
}
}
}] & [_, ...]
}

View File

@@ -0,0 +1,149 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
package v1
import "strings"
// GatewayClass describes a class of Gateways available to the
// user for creating
// Gateway resources.
//
//
// 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.
//
//
// Whenever one or more Gateways are using a GatewayClass,
// implementations SHOULD
// 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.
//
//
// GatewayClass is a Cluster level resource.
#GatewayClass: {
// 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
apiVersion: "gateway.networking.k8s.io/v1"
// 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
kind: "GatewayClass"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// Spec defines the desired state of GatewayClass.
spec!: #GatewayClassSpec
}
// Spec defines the desired state of GatewayClass.
#GatewayClassSpec: {
// 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.
//
//
// Example: "example.net/gateway-controller".
//
//
// This field is not mutable and cannot be empty.
//
//
// Support: Core
controllerName: strings.MaxRunes(253) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$"
}
// Description helps describe a GatewayClass with more details.
description?: strings.MaxRunes(64)
// 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.
//
//
// 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.
//
//
// If the referent cannot be found, the GatewayClass's
// "InvalidParameters"
// status condition will be true.
//
//
// A Gateway for this GatewayClass may provide its own
// `parametersRef`. When both are specified,
// the merging behavior is implementation specific.
// It is generally recommended that GatewayClass provides defaults
// that can be overridden by a Gateway.
//
//
// Support: Implementation-specific
parametersRef?: {
// Group is the group of the referent.
group: strings.MaxRunes(253) & {
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// Kind is kind of the referent.
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
}
// Name is the name of the referent.
name: strings.MaxRunes(253) & strings.MinRunes(1)
// 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.
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
}
}
}

View File

@@ -0,0 +1,149 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
package v1beta1
import "strings"
// GatewayClass describes a class of Gateways available to the
// user for creating
// Gateway resources.
//
//
// 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.
//
//
// Whenever one or more Gateways are using a GatewayClass,
// implementations SHOULD
// 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.
//
//
// GatewayClass is a Cluster level resource.
#GatewayClass: {
// 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
apiVersion: "gateway.networking.k8s.io/v1beta1"
// 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
kind: "GatewayClass"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// Spec defines the desired state of GatewayClass.
spec!: #GatewayClassSpec
}
// Spec defines the desired state of GatewayClass.
#GatewayClassSpec: {
// 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.
//
//
// Example: "example.net/gateway-controller".
//
//
// This field is not mutable and cannot be empty.
//
//
// Support: Core
controllerName: strings.MaxRunes(253) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$"
}
// Description helps describe a GatewayClass with more details.
description?: strings.MaxRunes(64)
// 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.
//
//
// 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.
//
//
// If the referent cannot be found, the GatewayClass's
// "InvalidParameters"
// status condition will be true.
//
//
// A Gateway for this GatewayClass may provide its own
// `parametersRef`. When both are specified,
// the merging behavior is implementation specific.
// It is generally recommended that GatewayClass provides defaults
// that can be overridden by a Gateway.
//
//
// Support: Implementation-specific
parametersRef?: {
// Group is the group of the referent.
group: strings.MaxRunes(253) & {
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// Kind is kind of the referent.
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
}
// Name is the name of the referent.
name: strings.MaxRunes(253) & strings.MinRunes(1)
// 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.
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
}
}
}

View File

@@ -0,0 +1,183 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
package v1alpha2
import (
"strings"
"list"
)
// ReferenceGrant identifies kinds of resources in other
// namespaces that are
// trusted to reference the specified kinds of resources in the
// same namespace
// as the policy.
//
//
// Each ReferenceGrant can be used to represent a unique trust
// relationship.
// Additional Reference Grants can be used to add to the set of
// trusted
// sources of inbound references for the namespace they are
// defined within.
//
//
// A ReferenceGrant is required for all cross-namespace references
// in Gateway API
// (with the exception of cross-namespace Route-Gateway
// attachment, which is
// governed by the AllowedRoutes configuration on the Gateway, and
// cross-namespace
// Service ParentRefs on a "consumer" mesh Route, which defines
// routing rules
// applicable only to workloads in the Route namespace).
// ReferenceGrants allowing
// a reference from a Route to a Service are only applicable to
// BackendRefs.
//
//
// ReferenceGrant is a form of runtime verification allowing users
// to assert
// which cross-namespace object references are permitted.
// Implementations that
// support ReferenceGrant MUST NOT permit cross-namespace
// references which have
// no grant, and MUST respond to the removal of a grant by
// revoking the access
// that the grant allowed.
#ReferenceGrant: {
// 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
apiVersion: "gateway.networking.k8s.io/v1alpha2"
// 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
kind: "ReferenceGrant"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// Spec defines the desired state of ReferenceGrant.
spec!: #ReferenceGrantSpec
}
// Spec defines the desired state of ReferenceGrant.
#ReferenceGrantSpec: {
// 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.
//
//
// Support: Core
from: list.MaxItems(16) & [...{
// Group is the group of the referent.
// When empty, the Kubernetes core API group is inferred.
//
//
// Support: Core
group: strings.MaxRunes(253) & {
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// 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.
//
//
// When used to permit a SecretObjectReference:
//
//
// * Gateway
//
//
// When used to permit a BackendObjectReference:
//
//
// * GRPCRoute
// * HTTPRoute
// * TCPRoute
// * TLSRoute
// * UDPRoute
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
}
// Namespace is the namespace of the referent.
//
//
// Support: Core
namespace: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
}
}] & [_, ...]
// 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.
//
//
// Support: Core
to: list.MaxItems(16) & [...{
// Group is the group of the referent.
// When empty, the Kubernetes core API group is inferred.
//
//
// Support: Core
group: strings.MaxRunes(253) & {
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// 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:
//
//
// * Secret when used to permit a SecretObjectReference
// * Service when used to permit a BackendObjectReference
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
}
// Name is the name of the referent. When unspecified, this policy
// refers to all resources of the specified Group and Kind in the
// local
// namespace.
name?: strings.MaxRunes(253) & strings.MinRunes(1)
}] & [_, ...]
}

View File

@@ -0,0 +1,174 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
package v1beta1
import (
"strings"
"list"
)
// ReferenceGrant identifies kinds of resources in other
// namespaces that are
// trusted to reference the specified kinds of resources in the
// same namespace
// as the policy.
//
//
// Each ReferenceGrant can be used to represent a unique trust
// relationship.
// Additional Reference Grants can be used to add to the set of
// trusted
// sources of inbound references for the namespace they are
// defined within.
//
//
// All cross-namespace references in Gateway API (with the
// exception of cross-namespace
// Gateway-route attachment) require a ReferenceGrant.
//
//
// ReferenceGrant is a form of runtime verification allowing users
// to assert
// which cross-namespace object references are permitted.
// Implementations that
// support ReferenceGrant MUST NOT permit cross-namespace
// references which have
// no grant, and MUST respond to the removal of a grant by
// revoking the access
// that the grant allowed.
#ReferenceGrant: {
// 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
apiVersion: "gateway.networking.k8s.io/v1beta1"
// 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
kind: "ReferenceGrant"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// Spec defines the desired state of ReferenceGrant.
spec!: #ReferenceGrantSpec
}
// Spec defines the desired state of ReferenceGrant.
#ReferenceGrantSpec: {
// 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.
//
//
// Support: Core
from: list.MaxItems(16) & [...{
// Group is the group of the referent.
// When empty, the Kubernetes core API group is inferred.
//
//
// Support: Core
group: strings.MaxRunes(253) & {
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// 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.
//
//
// When used to permit a SecretObjectReference:
//
//
// * Gateway
//
//
// When used to permit a BackendObjectReference:
//
//
// * GRPCRoute
// * HTTPRoute
// * TCPRoute
// * TLSRoute
// * UDPRoute
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
}
// Namespace is the namespace of the referent.
//
//
// Support: Core
namespace: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
}
}] & [_, ...]
// 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.
//
//
// Support: Core
to: list.MaxItems(16) & [...{
// Group is the group of the referent.
// When empty, the Kubernetes core API group is inferred.
//
//
// Support: Core
group: strings.MaxRunes(253) & {
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
}
// 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:
//
//
// * Secret when used to permit a SecretObjectReference
// * Service when used to permit a BackendObjectReference
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
}
// Name is the name of the referent. When unspecified, this policy
// refers to all resources of the specified Group and Kind in the
// local
// namespace.
name?: strings.MaxRunes(253) & strings.MinRunes(1)
}] & [_, ...]
}

View File

@@ -16,6 +16,11 @@ package v1alpha1
#BuildPlanSpec: {
disabled?: bool @go(Disabled)
components?: #BuildPlanComponents @go(Components)
// DeployFiles keys represent file paths relative to the cluster deploy
// directory. Map values represent the string encoded file contents. Used to
// write the argocd Application, but may be used to render any file from CUE.
deployFiles?: #FileContentMap @go(DeployFiles)
}
#BuildPlanComponents: {

View File

@@ -7,4 +7,9 @@ package v1alpha1
// Result is the build result for display or writing. Holos components Render the Result as a data pipeline.
#Result: {
HolosComponent: #HolosComponent
// DeployFiles keys represent file paths relative to the cluster deploy
// directory. Map values represent the string encoded file contents. Used to
// write the argocd Application, but may be used to render any file from CUE.
deployFiles?: #FileContentMap @go(DeployFiles)
}

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/apps/v1
package v1
#GroupName: "apps"

View File

@@ -0,0 +1,946 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/apps/v1
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
)
#ControllerRevisionHashLabelKey: "controller-revision-hash"
#StatefulSetRevisionLabel: "controller-revision-hash"
#DeprecatedRollbackTo: "deprecated.deployment.rollback.to"
#DeprecatedTemplateGeneration: "deprecated.daemonset.template.generation"
#StatefulSetPodNameLabel: "statefulset.kubernetes.io/pod-name"
#PodIndexLabel: "apps.kubernetes.io/pod-index"
// StatefulSet represents a set of pods with consistent identities.
// Identities are defined as:
// - Network: A single stable DNS and hostname.
// - Storage: As many VolumeClaims as requested.
//
// The StatefulSet guarantees that a given network identity will always
// map to the same storage identity.
#StatefulSet: {
metav1.#TypeMeta
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Spec defines the desired identities of pods in this set.
// +optional
spec?: #StatefulSetSpec @go(Spec) @protobuf(2,bytes,opt)
// Status is the current status of Pods in this StatefulSet. This data
// may be out of date by some window of time.
// +optional
status?: #StatefulSetStatus @go(Status) @protobuf(3,bytes,opt)
}
// PodManagementPolicyType defines the policy for creating pods under a stateful set.
// +enum
#PodManagementPolicyType: string // #enumPodManagementPolicyType
#enumPodManagementPolicyType:
#OrderedReadyPodManagement |
#ParallelPodManagement
// OrderedReadyPodManagement will create pods in strictly increasing order on
// scale up and strictly decreasing order on scale down, progressing only when
// the previous pod is ready or terminated. At most one pod will be changed
// at any time.
#OrderedReadyPodManagement: #PodManagementPolicyType & "OrderedReady"
// ParallelPodManagement will create and delete pods as soon as the stateful set
// replica count is changed, and will not wait for pods to be ready or complete
// termination.
#ParallelPodManagement: #PodManagementPolicyType & "Parallel"
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
// controller will use to perform updates. It includes any additional parameters
// necessary to perform the update for the indicated strategy.
#StatefulSetUpdateStrategy: {
// Type indicates the type of the StatefulSetUpdateStrategy.
// Default is RollingUpdate.
// +optional
type?: #StatefulSetUpdateStrategyType @go(Type) @protobuf(1,bytes,opt,casttype=StatefulSetStrategyType)
// RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType.
// +optional
rollingUpdate?: null | #RollingUpdateStatefulSetStrategy @go(RollingUpdate,*RollingUpdateStatefulSetStrategy) @protobuf(2,bytes,opt)
}
// StatefulSetUpdateStrategyType is a string enumeration type that enumerates
// all possible update strategies for the StatefulSet controller.
// +enum
#StatefulSetUpdateStrategyType: string // #enumStatefulSetUpdateStrategyType
#enumStatefulSetUpdateStrategyType:
#RollingUpdateStatefulSetStrategyType |
#OnDeleteStatefulSetStrategyType
// RollingUpdateStatefulSetStrategyType indicates that update will be
// applied to all Pods in the StatefulSet with respect to the StatefulSet
// ordering constraints. When a scale operation is performed with this
// strategy, new Pods will be created from the specification version indicated
// by the StatefulSet's updateRevision.
#RollingUpdateStatefulSetStrategyType: #StatefulSetUpdateStrategyType & "RollingUpdate"
// OnDeleteStatefulSetStrategyType triggers the legacy behavior. Version
// tracking and ordered rolling restarts are disabled. Pods are recreated
// from the StatefulSetSpec when they are manually deleted. When a scale
// operation is performed with this strategy,specification version indicated
// by the StatefulSet's currentRevision.
#OnDeleteStatefulSetStrategyType: #StatefulSetUpdateStrategyType & "OnDelete"
// RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.
#RollingUpdateStatefulSetStrategy: {
// Partition indicates the ordinal at which the StatefulSet should be partitioned
// for updates. During a rolling update, all pods from ordinal Replicas-1 to
// Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched.
// This is helpful in being able to do a canary based deployment. The default value is 0.
// +optional
partition?: null | int32 @go(Partition,*int32) @protobuf(1,varint,opt)
// The maximum number of pods that can be unavailable during the update.
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
// Absolute number is calculated from percentage by rounding up. This can not be 0.
// Defaults to 1. This field is alpha-level and is only honored by servers that enable the
// MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to
// Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it
// will be counted towards MaxUnavailable.
// +optional
maxUnavailable?: null | intstr.#IntOrString @go(MaxUnavailable,*intstr.IntOrString) @protobuf(2,varint,opt)
}
// PersistentVolumeClaimRetentionPolicyType is a string enumeration of the policies that will determine
// when volumes from the VolumeClaimTemplates will be deleted when the controlling StatefulSet is
// deleted or scaled down.
#PersistentVolumeClaimRetentionPolicyType: string // #enumPersistentVolumeClaimRetentionPolicyType
#enumPersistentVolumeClaimRetentionPolicyType:
#RetainPersistentVolumeClaimRetentionPolicyType |
#DeletePersistentVolumeClaimRetentionPolicyType
// RetainPersistentVolumeClaimRetentionPolicyType is the default
// PersistentVolumeClaimRetentionPolicy and specifies that
// PersistentVolumeClaims associated with StatefulSet VolumeClaimTemplates
// will not be deleted.
#RetainPersistentVolumeClaimRetentionPolicyType: #PersistentVolumeClaimRetentionPolicyType & "Retain"
// RetentionPersistentVolumeClaimRetentionPolicyType specifies that
// PersistentVolumeClaims associated with StatefulSet VolumeClaimTemplates
// will be deleted in the scenario specified in
// StatefulSetPersistentVolumeClaimRetentionPolicy.
#DeletePersistentVolumeClaimRetentionPolicyType: #PersistentVolumeClaimRetentionPolicyType & "Delete"
// StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs
// created from the StatefulSet VolumeClaimTemplates.
#StatefulSetPersistentVolumeClaimRetentionPolicy: {
// WhenDeleted specifies what happens to PVCs created from StatefulSet
// VolumeClaimTemplates when the StatefulSet is deleted. The default policy
// of `Retain` causes PVCs to not be affected by StatefulSet deletion. The
// `Delete` policy causes those PVCs to be deleted.
whenDeleted?: #PersistentVolumeClaimRetentionPolicyType @go(WhenDeleted) @protobuf(1,bytes,opt,casttype=PersistentVolumeClaimRetentionPolicyType)
// WhenScaled specifies what happens to PVCs created from StatefulSet
// VolumeClaimTemplates when the StatefulSet is scaled down. The default
// policy of `Retain` causes PVCs to not be affected by a scaledown. The
// `Delete` policy causes the associated PVCs for any excess pods above
// the replica count to be deleted.
whenScaled?: #PersistentVolumeClaimRetentionPolicyType @go(WhenScaled) @protobuf(2,bytes,opt,casttype=PersistentVolumeClaimRetentionPolicyType)
}
// StatefulSetOrdinals describes the policy used for replica ordinal assignment
// in this StatefulSet.
#StatefulSetOrdinals: {
// start is the number representing the first replica's index. It may be used
// to number replicas from an alternate index (eg: 1-indexed) over the default
// 0-indexed names, or to orchestrate progressive movement of replicas from
// one StatefulSet to another.
// If set, replica indices will be in the range:
// [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas).
// If unset, defaults to 0. Replica indices will be in the range:
// [0, .spec.replicas).
// +optional
start?: int32 @go(Start) @protobuf(1,varint,opt)
}
// A StatefulSetSpec is the specification of a StatefulSet.
#StatefulSetSpec: {
// replicas is the desired number of replicas of the given Template.
// These are replicas in the sense that they are instantiations of the
// same Template, but individual replicas also have a consistent identity.
// If unspecified, defaults to 1.
// TODO: Consider a rename of this field.
// +optional
replicas?: null | int32 @go(Replicas,*int32) @protobuf(1,varint,opt)
// selector is a label query over pods that should match the replica count.
// It must match the pod template's labels.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
selector?: null | metav1.#LabelSelector @go(Selector,*metav1.LabelSelector) @protobuf(2,bytes,opt)
// template is the object that describes the pod that will be created if
// insufficient replicas are detected. Each pod stamped out by the StatefulSet
// will fulfill this Template, but have a unique identity from the rest
// of the StatefulSet. Each pod will be named with the format
// <statefulsetname>-<podindex>. For example, a pod in a StatefulSet named
// "web" with index number "3" would be named "web-3".
// The only allowed template.spec.restartPolicy value is "Always".
template: v1.#PodTemplateSpec @go(Template) @protobuf(3,bytes,opt)
// volumeClaimTemplates is a list of claims that pods are allowed to reference.
// The StatefulSet controller is responsible for mapping network identities to
// claims in a way that maintains the identity of a pod. Every claim in
// this list must have at least one matching (by name) volumeMount in one
// container in the template. A claim in this list takes precedence over
// any volumes in the template, with the same name.
// TODO: Define the behavior if a claim already exists with the same name.
// +optional
volumeClaimTemplates?: [...v1.#PersistentVolumeClaim] @go(VolumeClaimTemplates,[]v1.PersistentVolumeClaim) @protobuf(4,bytes,rep)
// serviceName is the name of the service that governs this StatefulSet.
// This service must exist before the StatefulSet, and is responsible for
// the network identity of the set. Pods get DNS/hostnames that follow the
// pattern: pod-specific-string.serviceName.default.svc.cluster.local
// where "pod-specific-string" is managed by the StatefulSet controller.
serviceName: string @go(ServiceName) @protobuf(5,bytes,opt)
// podManagementPolicy controls how pods are created during initial scale up,
// when replacing pods on nodes, or when scaling down. The default policy is
// `OrderedReady`, where pods are created in increasing order (pod-0, then
// pod-1, etc) and the controller will wait until each pod is ready before
// continuing. When scaling down, the pods are removed in the opposite order.
// The alternative policy is `Parallel` which will create pods in parallel
// to match the desired scale without waiting, and on scale down will delete
// all pods at once.
// +optional
podManagementPolicy?: #PodManagementPolicyType @go(PodManagementPolicy) @protobuf(6,bytes,opt,casttype=PodManagementPolicyType)
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
// employed to update Pods in the StatefulSet when a revision is made to
// Template.
updateStrategy?: #StatefulSetUpdateStrategy @go(UpdateStrategy) @protobuf(7,bytes,opt)
// revisionHistoryLimit is the maximum number of revisions that will
// be maintained in the StatefulSet's revision history. The revision history
// consists of all revisions not represented by a currently applied
// StatefulSetSpec version. The default value is 10.
revisionHistoryLimit?: null | int32 @go(RevisionHistoryLimit,*int32) @protobuf(8,varint,opt)
// Minimum number of seconds for which a newly created pod should be ready
// without any of its container crashing for it to be considered available.
// Defaults to 0 (pod will be considered available as soon as it is ready)
// +optional
minReadySeconds?: int32 @go(MinReadySeconds) @protobuf(9,varint,opt)
// persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent
// volume claims created from volumeClaimTemplates. By default, all persistent
// volume claims are created as needed and retained until manually deleted. This
// policy allows the lifecycle to be altered, for example by deleting persistent
// volume claims when their stateful set is deleted, or when their pod is scaled
// down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled,
// which is alpha. +optional
persistentVolumeClaimRetentionPolicy?: null | #StatefulSetPersistentVolumeClaimRetentionPolicy @go(PersistentVolumeClaimRetentionPolicy,*StatefulSetPersistentVolumeClaimRetentionPolicy) @protobuf(10,bytes,opt)
// ordinals controls the numbering of replica indices in a StatefulSet. The
// default ordinals behavior assigns a "0" index to the first replica and
// increments the index by one for each additional replica requested. Using
// the ordinals field requires the StatefulSetStartOrdinal feature gate to be
// enabled, which is beta.
// +optional
ordinals?: null | #StatefulSetOrdinals @go(Ordinals,*StatefulSetOrdinals) @protobuf(11,bytes,opt)
}
// StatefulSetStatus represents the current state of a StatefulSet.
#StatefulSetStatus: {
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
// StatefulSet's generation, which is updated on mutation by the API Server.
// +optional
observedGeneration?: int64 @go(ObservedGeneration) @protobuf(1,varint,opt)
// replicas is the number of Pods created by the StatefulSet controller.
replicas: int32 @go(Replicas) @protobuf(2,varint,opt)
// readyReplicas is the number of pods created for this StatefulSet with a Ready Condition.
readyReplicas?: int32 @go(ReadyReplicas) @protobuf(3,varint,opt)
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
// indicated by currentRevision.
currentReplicas?: int32 @go(CurrentReplicas) @protobuf(4,varint,opt)
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
// indicated by updateRevision.
updatedReplicas?: int32 @go(UpdatedReplicas) @protobuf(5,varint,opt)
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
// sequence [0,currentReplicas).
currentRevision?: string @go(CurrentRevision) @protobuf(6,bytes,opt)
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
// [replicas-updatedReplicas,replicas)
updateRevision?: string @go(UpdateRevision) @protobuf(7,bytes,opt)
// collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller
// uses this field as a collision avoidance mechanism when it needs to create the name for the
// newest ControllerRevision.
// +optional
collisionCount?: null | int32 @go(CollisionCount,*int32) @protobuf(9,varint,opt)
// Represents the latest available observations of a statefulset's current state.
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
conditions?: [...#StatefulSetCondition] @go(Conditions,[]StatefulSetCondition) @protobuf(10,bytes,rep)
// Total number of available pods (ready for at least minReadySeconds) targeted by this statefulset.
// +optional
availableReplicas?: int32 @go(AvailableReplicas) @protobuf(11,varint,opt)
}
#StatefulSetConditionType: string
// StatefulSetCondition describes the state of a statefulset at a certain point.
#StatefulSetCondition: {
// Type of statefulset condition.
type: #StatefulSetConditionType @go(Type) @protobuf(1,bytes,opt,casttype=StatefulSetConditionType)
// Status of the condition, one of True, False, Unknown.
status: v1.#ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=k8s.io/api/core/v1.ConditionStatus)
// Last time the condition transitioned from one status to another.
// +optional
lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(3,bytes,opt)
// The reason for the condition's last transition.
// +optional
reason?: string @go(Reason) @protobuf(4,bytes,opt)
// A human readable message indicating details about the transition.
// +optional
message?: string @go(Message) @protobuf(5,bytes,opt)
}
// StatefulSetList is a collection of StatefulSets.
#StatefulSetList: {
metav1.#TypeMeta
// Standard list's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is the list of stateful sets.
items: [...#StatefulSet] @go(Items,[]StatefulSet) @protobuf(2,bytes,rep)
}
// Deployment enables declarative updates for Pods and ReplicaSets.
#Deployment: {
metav1.#TypeMeta
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Specification of the desired behavior of the Deployment.
// +optional
spec?: #DeploymentSpec @go(Spec) @protobuf(2,bytes,opt)
// Most recently observed status of the Deployment.
// +optional
status?: #DeploymentStatus @go(Status) @protobuf(3,bytes,opt)
}
// DeploymentSpec is the specification of the desired behavior of the Deployment.
#DeploymentSpec: {
// Number of desired pods. This is a pointer to distinguish between explicit
// zero and not specified. Defaults to 1.
// +optional
replicas?: null | int32 @go(Replicas,*int32) @protobuf(1,varint,opt)
// Label selector for pods. Existing ReplicaSets whose pods are
// selected by this will be the ones affected by this deployment.
// It must match the pod template's labels.
selector?: null | metav1.#LabelSelector @go(Selector,*metav1.LabelSelector) @protobuf(2,bytes,opt)
// Template describes the pods that will be created.
// The only allowed template.spec.restartPolicy value is "Always".
template: v1.#PodTemplateSpec @go(Template) @protobuf(3,bytes,opt)
// The deployment strategy to use to replace existing pods with new ones.
// +optional
// +patchStrategy=retainKeys
strategy?: #DeploymentStrategy @go(Strategy) @protobuf(4,bytes,opt)
// Minimum number of seconds for which a newly created pod should be ready
// without any of its container crashing, for it to be considered available.
// Defaults to 0 (pod will be considered available as soon as it is ready)
// +optional
minReadySeconds?: int32 @go(MinReadySeconds) @protobuf(5,varint,opt)
// The number of old ReplicaSets to retain to allow rollback.
// This is a pointer to distinguish between explicit zero and not specified.
// Defaults to 10.
// +optional
revisionHistoryLimit?: null | int32 @go(RevisionHistoryLimit,*int32) @protobuf(6,varint,opt)
// Indicates that the deployment is paused.
// +optional
paused?: bool @go(Paused) @protobuf(7,varint,opt)
// The maximum time in seconds for a deployment to make progress before it
// is considered to be failed. The deployment controller will continue to
// process failed deployments and a condition with a ProgressDeadlineExceeded
// reason will be surfaced in the deployment status. Note that progress will
// not be estimated during the time a deployment is paused. Defaults to 600s.
progressDeadlineSeconds?: null | int32 @go(ProgressDeadlineSeconds,*int32) @protobuf(9,varint,opt)
}
// DefaultDeploymentUniqueLabelKey is the default key of the selector that is added
// to existing ReplicaSets (and label key that is added to its pods) to prevent the existing ReplicaSets
// to select new pods (and old pods being select by new ReplicaSet).
#DefaultDeploymentUniqueLabelKey: "pod-template-hash"
// DeploymentStrategy describes how to replace existing pods with new ones.
#DeploymentStrategy: {
// Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate.
// +optional
type?: #DeploymentStrategyType @go(Type) @protobuf(1,bytes,opt,casttype=DeploymentStrategyType)
// Rolling update config params. Present only if DeploymentStrategyType =
// RollingUpdate.
//---
// TODO: Update this to follow our convention for oneOf, whatever we decide it
// to be.
// +optional
rollingUpdate?: null | #RollingUpdateDeployment @go(RollingUpdate,*RollingUpdateDeployment) @protobuf(2,bytes,opt)
}
// +enum
#DeploymentStrategyType: string // #enumDeploymentStrategyType
#enumDeploymentStrategyType:
#RecreateDeploymentStrategyType |
#RollingUpdateDeploymentStrategyType
// Kill all existing pods before creating new ones.
#RecreateDeploymentStrategyType: #DeploymentStrategyType & "Recreate"
// Replace the old ReplicaSets by new one using rolling update i.e gradually scale down the old ReplicaSets and scale up the new one.
#RollingUpdateDeploymentStrategyType: #DeploymentStrategyType & "RollingUpdate"
// Spec to control the desired behavior of rolling update.
#RollingUpdateDeployment: {
// The maximum number of pods that can be unavailable during the update.
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
// Absolute number is calculated from percentage by rounding down.
// This can not be 0 if MaxSurge is 0.
// Defaults to 25%.
// Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods
// immediately when the rolling update starts. Once new pods are ready, old ReplicaSet
// can be scaled down further, followed by scaling up the new ReplicaSet, ensuring
// that the total number of pods available at all times during the update is at
// least 70% of desired pods.
// +optional
maxUnavailable?: null | intstr.#IntOrString @go(MaxUnavailable,*intstr.IntOrString) @protobuf(1,bytes,opt)
// The maximum number of pods that can be scheduled above the desired number of
// pods.
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
// This can not be 0 if MaxUnavailable is 0.
// Absolute number is calculated from percentage by rounding up.
// Defaults to 25%.
// Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when
// the rolling update starts, such that the total number of old and new pods do not exceed
// 130% of desired pods. Once old pods have been killed,
// new ReplicaSet can be scaled up further, ensuring that total number of pods running
// at any time during the update is at most 130% of desired pods.
// +optional
maxSurge?: null | intstr.#IntOrString @go(MaxSurge,*intstr.IntOrString) @protobuf(2,bytes,opt)
}
// DeploymentStatus is the most recently observed status of the Deployment.
#DeploymentStatus: {
// The generation observed by the deployment controller.
// +optional
observedGeneration?: int64 @go(ObservedGeneration) @protobuf(1,varint,opt)
// Total number of non-terminated pods targeted by this deployment (their labels match the selector).
// +optional
replicas?: int32 @go(Replicas) @protobuf(2,varint,opt)
// Total number of non-terminated pods targeted by this deployment that have the desired template spec.
// +optional
updatedReplicas?: int32 @go(UpdatedReplicas) @protobuf(3,varint,opt)
// readyReplicas is the number of pods targeted by this Deployment with a Ready Condition.
// +optional
readyReplicas?: int32 @go(ReadyReplicas) @protobuf(7,varint,opt)
// Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.
// +optional
availableReplicas?: int32 @go(AvailableReplicas) @protobuf(4,varint,opt)
// Total number of unavailable pods targeted by this deployment. This is the total number of
// pods that are still required for the deployment to have 100% available capacity. They may
// either be pods that are running but not yet available or pods that still have not been created.
// +optional
unavailableReplicas?: int32 @go(UnavailableReplicas) @protobuf(5,varint,opt)
// Represents the latest available observations of a deployment's current state.
// +patchMergeKey=type
// +patchStrategy=merge
conditions?: [...#DeploymentCondition] @go(Conditions,[]DeploymentCondition) @protobuf(6,bytes,rep)
// Count of hash collisions for the Deployment. The Deployment controller uses this
// field as a collision avoidance mechanism when it needs to create the name for the
// newest ReplicaSet.
// +optional
collisionCount?: null | int32 @go(CollisionCount,*int32) @protobuf(8,varint,opt)
}
#DeploymentConditionType: string // #enumDeploymentConditionType
#enumDeploymentConditionType:
#DeploymentAvailable |
#DeploymentProgressing |
#DeploymentReplicaFailure
// Available means the deployment is available, ie. at least the minimum available
// replicas required are up and running for at least minReadySeconds.
#DeploymentAvailable: #DeploymentConditionType & "Available"
// Progressing means the deployment is progressing. Progress for a deployment is
// considered when a new replica set is created or adopted, and when new pods scale
// up or old pods scale down. Progress is not estimated for paused deployments or
// when progressDeadlineSeconds is not specified.
#DeploymentProgressing: #DeploymentConditionType & "Progressing"
// ReplicaFailure is added in a deployment when one of its pods fails to be created
// or deleted.
#DeploymentReplicaFailure: #DeploymentConditionType & "ReplicaFailure"
// DeploymentCondition describes the state of a deployment at a certain point.
#DeploymentCondition: {
// Type of deployment condition.
type: #DeploymentConditionType @go(Type) @protobuf(1,bytes,opt,casttype=DeploymentConditionType)
// Status of the condition, one of True, False, Unknown.
status: v1.#ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=k8s.io/api/core/v1.ConditionStatus)
// The last time this condition was updated.
lastUpdateTime?: metav1.#Time @go(LastUpdateTime) @protobuf(6,bytes,opt)
// Last time the condition transitioned from one status to another.
lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(7,bytes,opt)
// The reason for the condition's last transition.
reason?: string @go(Reason) @protobuf(4,bytes,opt)
// A human readable message indicating details about the transition.
message?: string @go(Message) @protobuf(5,bytes,opt)
}
// DeploymentList is a list of Deployments.
#DeploymentList: {
metav1.#TypeMeta
// Standard list metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is the list of Deployments.
items: [...#Deployment] @go(Items,[]Deployment) @protobuf(2,bytes,rep)
}
// DaemonSetUpdateStrategy is a struct used to control the update strategy for a DaemonSet.
#DaemonSetUpdateStrategy: {
// Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate.
// +optional
type?: #DaemonSetUpdateStrategyType @go(Type) @protobuf(1,bytes,opt)
// Rolling update config params. Present only if type = "RollingUpdate".
//---
// TODO: Update this to follow our convention for oneOf, whatever we decide it
// to be. Same as Deployment `strategy.rollingUpdate`.
// See https://github.com/kubernetes/kubernetes/issues/35345
// +optional
rollingUpdate?: null | #RollingUpdateDaemonSet @go(RollingUpdate,*RollingUpdateDaemonSet) @protobuf(2,bytes,opt)
}
// +enum
#DaemonSetUpdateStrategyType: string // #enumDaemonSetUpdateStrategyType
#enumDaemonSetUpdateStrategyType:
#RollingUpdateDaemonSetStrategyType |
#OnDeleteDaemonSetStrategyType
// Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.
#RollingUpdateDaemonSetStrategyType: #DaemonSetUpdateStrategyType & "RollingUpdate"
// Replace the old daemons only when it's killed
#OnDeleteDaemonSetStrategyType: #DaemonSetUpdateStrategyType & "OnDelete"
// Spec to control the desired behavior of daemon set rolling update.
#RollingUpdateDaemonSet: {
// The maximum number of DaemonSet pods that can be unavailable during the
// update. Value can be an absolute number (ex: 5) or a percentage of total
// number of DaemonSet pods at the start of the update (ex: 10%). Absolute
// number is calculated from percentage by rounding up.
// This cannot be 0 if MaxSurge is 0
// Default value is 1.
// Example: when this is set to 30%, at most 30% of the total number of nodes
// that should be running the daemon pod (i.e. status.desiredNumberScheduled)
// can have their pods stopped for an update at any given time. The update
// starts by stopping at most 30% of those DaemonSet pods and then brings
// up new DaemonSet pods in their place. Once the new pods are available,
// it then proceeds onto other DaemonSet pods, thus ensuring that at least
// 70% of original number of DaemonSet pods are available at all times during
// the update.
// +optional
maxUnavailable?: null | intstr.#IntOrString @go(MaxUnavailable,*intstr.IntOrString) @protobuf(1,bytes,opt)
// The maximum number of nodes with an existing available DaemonSet pod that
// can have an updated DaemonSet pod during during an update.
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
// This can not be 0 if MaxUnavailable is 0.
// Absolute number is calculated from percentage by rounding up to a minimum of 1.
// Default value is 0.
// Example: when this is set to 30%, at most 30% of the total number of nodes
// that should be running the daemon pod (i.e. status.desiredNumberScheduled)
// can have their a new pod created before the old pod is marked as deleted.
// The update starts by launching new pods on 30% of nodes. Once an updated
// pod is available (Ready for at least minReadySeconds) the old DaemonSet pod
// on that node is marked deleted. If the old pod becomes unavailable for any
// reason (Ready transitions to false, is evicted, or is drained) an updated
// pod is immediatedly created on that node without considering surge limits.
// Allowing surge implies the possibility that the resources consumed by the
// daemonset on any given node can double if the readiness check fails, and
// so resource intensive daemonsets should take into account that they may
// cause evictions during disruption.
// +optional
maxSurge?: null | intstr.#IntOrString @go(MaxSurge,*intstr.IntOrString) @protobuf(2,bytes,opt)
}
// DaemonSetSpec is the specification of a daemon set.
#DaemonSetSpec: {
// A label query over pods that are managed by the daemon set.
// Must match in order to be controlled.
// It must match the pod template's labels.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
selector?: null | metav1.#LabelSelector @go(Selector,*metav1.LabelSelector) @protobuf(1,bytes,opt)
// An object that describes the pod that will be created.
// The DaemonSet will create exactly one copy of this pod on every node
// that matches the template's node selector (or on every node if no node
// selector is specified).
// The only allowed template.spec.restartPolicy value is "Always".
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template
template: v1.#PodTemplateSpec @go(Template) @protobuf(2,bytes,opt)
// An update strategy to replace existing DaemonSet pods with new pods.
// +optional
updateStrategy?: #DaemonSetUpdateStrategy @go(UpdateStrategy) @protobuf(3,bytes,opt)
// The minimum number of seconds for which a newly created DaemonSet pod should
// be ready without any of its container crashing, for it to be considered
// available. Defaults to 0 (pod will be considered available as soon as it
// is ready).
// +optional
minReadySeconds?: int32 @go(MinReadySeconds) @protobuf(4,varint,opt)
// The number of old history to retain to allow rollback.
// This is a pointer to distinguish between explicit zero and not specified.
// Defaults to 10.
// +optional
revisionHistoryLimit?: null | int32 @go(RevisionHistoryLimit,*int32) @protobuf(6,varint,opt)
}
// DaemonSetStatus represents the current status of a daemon set.
#DaemonSetStatus: {
// The number of nodes that are running at least 1
// daemon pod and are supposed to run the daemon pod.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
currentNumberScheduled: int32 @go(CurrentNumberScheduled) @protobuf(1,varint,opt)
// The number of nodes that are running the daemon pod, but are
// not supposed to run the daemon pod.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
numberMisscheduled: int32 @go(NumberMisscheduled) @protobuf(2,varint,opt)
// The total number of nodes that should be running the daemon
// pod (including nodes correctly running the daemon pod).
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
desiredNumberScheduled: int32 @go(DesiredNumberScheduled) @protobuf(3,varint,opt)
// numberReady is the number of nodes that should be running the daemon pod and have one
// or more of the daemon pod running with a Ready Condition.
numberReady: int32 @go(NumberReady) @protobuf(4,varint,opt)
// The most recent generation observed by the daemon set controller.
// +optional
observedGeneration?: int64 @go(ObservedGeneration) @protobuf(5,varint,opt)
// The total number of nodes that are running updated daemon pod
// +optional
updatedNumberScheduled?: int32 @go(UpdatedNumberScheduled) @protobuf(6,varint,opt)
// The number of nodes that should be running the
// daemon pod and have one or more of the daemon pod running and
// available (ready for at least spec.minReadySeconds)
// +optional
numberAvailable?: int32 @go(NumberAvailable) @protobuf(7,varint,opt)
// The number of nodes that should be running the
// daemon pod and have none of the daemon pod running and available
// (ready for at least spec.minReadySeconds)
// +optional
numberUnavailable?: int32 @go(NumberUnavailable) @protobuf(8,varint,opt)
// Count of hash collisions for the DaemonSet. The DaemonSet controller
// uses this field as a collision avoidance mechanism when it needs to
// create the name for the newest ControllerRevision.
// +optional
collisionCount?: null | int32 @go(CollisionCount,*int32) @protobuf(9,varint,opt)
// Represents the latest available observations of a DaemonSet's current state.
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
conditions?: [...#DaemonSetCondition] @go(Conditions,[]DaemonSetCondition) @protobuf(10,bytes,rep)
}
#DaemonSetConditionType: string
// DaemonSetCondition describes the state of a DaemonSet at a certain point.
#DaemonSetCondition: {
// Type of DaemonSet condition.
type: #DaemonSetConditionType @go(Type) @protobuf(1,bytes,opt,casttype=DaemonSetConditionType)
// Status of the condition, one of True, False, Unknown.
status: v1.#ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=k8s.io/api/core/v1.ConditionStatus)
// Last time the condition transitioned from one status to another.
// +optional
lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(3,bytes,opt)
// The reason for the condition's last transition.
// +optional
reason?: string @go(Reason) @protobuf(4,bytes,opt)
// A human readable message indicating details about the transition.
// +optional
message?: string @go(Message) @protobuf(5,bytes,opt)
}
// DaemonSet represents the configuration of a daemon set.
#DaemonSet: {
metav1.#TypeMeta
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// The desired behavior of this daemon set.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
spec?: #DaemonSetSpec @go(Spec) @protobuf(2,bytes,opt)
// The current status of this daemon set. This data may be
// out of date by some window of time.
// Populated by the system.
// Read-only.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
status?: #DaemonSetStatus @go(Status) @protobuf(3,bytes,opt)
}
// DefaultDaemonSetUniqueLabelKey is the default label key that is added
// to existing DaemonSet pods to distinguish between old and new
// DaemonSet pods during DaemonSet template updates.
#DefaultDaemonSetUniqueLabelKey: "controller-revision-hash"
// DaemonSetList is a collection of daemon sets.
#DaemonSetList: {
metav1.#TypeMeta
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// A list of daemon sets.
items: [...#DaemonSet] @go(Items,[]DaemonSet) @protobuf(2,bytes,rep)
}
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
#ReplicaSet: {
metav1.#TypeMeta
// If the Labels of a ReplicaSet are empty, they are defaulted to
// be the same as the Pod(s) that the ReplicaSet manages.
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Spec defines the specification of the desired behavior of the ReplicaSet.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
spec?: #ReplicaSetSpec @go(Spec) @protobuf(2,bytes,opt)
// Status is the most recently observed status of the ReplicaSet.
// This data may be out of date by some window of time.
// Populated by the system.
// Read-only.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
status?: #ReplicaSetStatus @go(Status) @protobuf(3,bytes,opt)
}
// ReplicaSetList is a collection of ReplicaSets.
#ReplicaSetList: {
metav1.#TypeMeta
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// List of ReplicaSets.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller
items: [...#ReplicaSet] @go(Items,[]ReplicaSet) @protobuf(2,bytes,rep)
}
// ReplicaSetSpec is the specification of a ReplicaSet.
#ReplicaSetSpec: {
// Replicas is the number of desired replicas.
// This is a pointer to distinguish between explicit zero and unspecified.
// Defaults to 1.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
// +optional
replicas?: null | int32 @go(Replicas,*int32) @protobuf(1,varint,opt)
// Minimum number of seconds for which a newly created pod should be ready
// without any of its container crashing, for it to be considered available.
// Defaults to 0 (pod will be considered available as soon as it is ready)
// +optional
minReadySeconds?: int32 @go(MinReadySeconds) @protobuf(4,varint,opt)
// Selector is a label query over pods that should match the replica count.
// Label keys and values that must match in order to be controlled by this replica set.
// It must match the pod template's labels.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
selector?: null | metav1.#LabelSelector @go(Selector,*metav1.LabelSelector) @protobuf(2,bytes,opt)
// Template is the object that describes the pod that will be created if
// insufficient replicas are detected.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template
// +optional
template?: v1.#PodTemplateSpec @go(Template) @protobuf(3,bytes,opt)
}
// ReplicaSetStatus represents the current status of a ReplicaSet.
#ReplicaSetStatus: {
// Replicas is the most recently observed number of replicas.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
replicas: int32 @go(Replicas) @protobuf(1,varint,opt)
// The number of pods that have labels matching the labels of the pod template of the replicaset.
// +optional
fullyLabeledReplicas?: int32 @go(FullyLabeledReplicas) @protobuf(2,varint,opt)
// readyReplicas is the number of pods targeted by this ReplicaSet with a Ready Condition.
// +optional
readyReplicas?: int32 @go(ReadyReplicas) @protobuf(4,varint,opt)
// The number of available replicas (ready for at least minReadySeconds) for this replica set.
// +optional
availableReplicas?: int32 @go(AvailableReplicas) @protobuf(5,varint,opt)
// ObservedGeneration reflects the generation of the most recently observed ReplicaSet.
// +optional
observedGeneration?: int64 @go(ObservedGeneration) @protobuf(3,varint,opt)
// Represents the latest available observations of a replica set's current state.
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
conditions?: [...#ReplicaSetCondition] @go(Conditions,[]ReplicaSetCondition) @protobuf(6,bytes,rep)
}
#ReplicaSetConditionType: string // #enumReplicaSetConditionType
#enumReplicaSetConditionType:
#ReplicaSetReplicaFailure
// ReplicaSetReplicaFailure is added in a replica set when one of its pods fails to be created
// due to insufficient quota, limit ranges, pod security policy, node selectors, etc. or deleted
// due to kubelet being down or finalizers are failing.
#ReplicaSetReplicaFailure: #ReplicaSetConditionType & "ReplicaFailure"
// ReplicaSetCondition describes the state of a replica set at a certain point.
#ReplicaSetCondition: {
// Type of replica set condition.
type: #ReplicaSetConditionType @go(Type) @protobuf(1,bytes,opt,casttype=ReplicaSetConditionType)
// Status of the condition, one of True, False, Unknown.
status: v1.#ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=k8s.io/api/core/v1.ConditionStatus)
// The last time the condition transitioned from one status to another.
// +optional
lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(3,bytes,opt)
// The reason for the condition's last transition.
// +optional
reason?: string @go(Reason) @protobuf(4,bytes,opt)
// A human readable message indicating details about the transition.
// +optional
message?: string @go(Message) @protobuf(5,bytes,opt)
}
// ControllerRevision implements an immutable snapshot of state data. Clients
// are responsible for serializing and deserializing the objects that contain
// their internal state.
// Once a ControllerRevision has been successfully created, it can not be updated.
// The API Server will fail validation of all requests that attempt to mutate
// the Data field. ControllerRevisions may, however, be deleted. Note that, due to its use by both
// the DaemonSet and StatefulSet controllers for update and rollback, this object is beta. However,
// it may be subject to name and representation changes in future releases, and clients should not
// depend on its stability. It is primarily for internal use by controllers.
#ControllerRevision: {
metav1.#TypeMeta
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Data is the serialized representation of the state.
data?: runtime.#RawExtension @go(Data) @protobuf(2,bytes,opt)
// Revision indicates the revision of the state represented by Data.
revision: int64 @go(Revision) @protobuf(3,varint,opt)
}
// ControllerRevisionList is a resource containing a list of ControllerRevision objects.
#ControllerRevisionList: {
metav1.#TypeMeta
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is the list of ControllerRevisions
items: [...#ControllerRevision] @go(Items,[]ControllerRevision) @protobuf(2,bytes,rep)
}

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/batch/v1
package v1
#GroupName: "batch"

View File

@@ -0,0 +1,713 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/batch/v1
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
)
// All Kubernetes labels need to be prefixed with Kubernetes to distinguish them from end-user labels
// More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#label-selector-and-annotation-conventions
_#labelPrefix: "batch.kubernetes.io/"
// CronJobScheduledTimestampAnnotation is the scheduled timestamp annotation for the Job.
// It records the original/expected scheduled timestamp for the running job, represented in RFC3339.
// The CronJob controller adds this annotation if the CronJobsScheduledAnnotation feature gate (beta in 1.28) is enabled.
#CronJobScheduledTimestampAnnotation: "batch.kubernetes.io/cronjob-scheduled-timestamp"
#JobCompletionIndexAnnotation: "batch.kubernetes.io/job-completion-index"
// JobTrackingFinalizer is a finalizer for Job's pods. It prevents them from
// being deleted before being accounted in the Job status.
//
// Additionally, the apiserver and job controller use this string as a Job
// annotation, to mark Jobs that are being tracked using pod finalizers.
// However, this behavior is deprecated in kubernetes 1.26. This means that, in
// 1.27+, one release after JobTrackingWithFinalizers graduates to GA, the
// apiserver and job controller will ignore this annotation and they will
// always track jobs using finalizers.
#JobTrackingFinalizer: "batch.kubernetes.io/job-tracking"
// The Job labels will use batch.kubernetes.io as a prefix for all labels
// Historically the job controller uses unprefixed labels for job-name and controller-uid and
// Kubernetes continutes to recognize those unprefixed labels for consistency.
#JobNameLabel: "batch.kubernetes.io/job-name"
// ControllerUid is used to programatically get pods corresponding to a Job.
// There is a corresponding label without the batch.kubernetes.io that we support for legacy reasons.
#ControllerUidLabel: "batch.kubernetes.io/controller-uid"
// Annotation indicating the number of failures for the index corresponding
// to the pod, which are counted towards the backoff limit.
#JobIndexFailureCountAnnotation: "batch.kubernetes.io/job-index-failure-count"
// Annotation indicating the number of failures for the index corresponding
// to the pod, which don't count towards the backoff limit, according to the
// pod failure policy. When the annotation is absent zero is implied.
#JobIndexIgnoredFailureCountAnnotation: "batch.kubernetes.io/job-index-ignored-failure-count"
// Job represents the configuration of a single job.
#Job: {
metav1.#TypeMeta
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Specification of the desired behavior of a job.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
spec?: #JobSpec @go(Spec) @protobuf(2,bytes,opt)
// Current status of a job.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
status?: #JobStatus @go(Status) @protobuf(3,bytes,opt)
}
// JobList is a collection of jobs.
#JobList: {
metav1.#TypeMeta
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// items is the list of Jobs.
items: [...#Job] @go(Items,[]Job) @protobuf(2,bytes,rep)
}
// CompletionMode specifies how Pod completions of a Job are tracked.
// +enum
#CompletionMode: string // #enumCompletionMode
#enumCompletionMode:
#NonIndexedCompletion |
#IndexedCompletion
// NonIndexedCompletion is a Job completion mode. In this mode, the Job is
// considered complete when there have been .spec.completions
// successfully completed Pods. Pod completions are homologous to each other.
#NonIndexedCompletion: #CompletionMode & "NonIndexed"
// IndexedCompletion is a Job completion mode. In this mode, the Pods of a
// Job get an associated completion index from 0 to (.spec.completions - 1).
// The Job is considered complete when a Pod completes for each completion
// index.
#IndexedCompletion: #CompletionMode & "Indexed"
// PodFailurePolicyAction specifies how a Pod failure is handled.
// +enum
#PodFailurePolicyAction: string // #enumPodFailurePolicyAction
#enumPodFailurePolicyAction:
#PodFailurePolicyActionFailJob |
#PodFailurePolicyActionFailIndex |
#PodFailurePolicyActionIgnore |
#PodFailurePolicyActionCount
// This is an action which might be taken on a pod failure - mark the
// pod's job as Failed and terminate all running pods.
#PodFailurePolicyActionFailJob: #PodFailurePolicyAction & "FailJob"
// This is an action which might be taken on a pod failure - mark the
// Job's index as failed to avoid restarts within this index. This action
// can only be used when backoffLimitPerIndex is set.
// This value is beta-level.
#PodFailurePolicyActionFailIndex: #PodFailurePolicyAction & "FailIndex"
// This is an action which might be taken on a pod failure - the counter towards
// .backoffLimit, represented by the job's .status.failed field, is not
// incremented and a replacement pod is created.
#PodFailurePolicyActionIgnore: #PodFailurePolicyAction & "Ignore"
// This is an action which might be taken on a pod failure - the pod failure
// is handled in the default way - the counter towards .backoffLimit,
// represented by the job's .status.failed field, is incremented.
#PodFailurePolicyActionCount: #PodFailurePolicyAction & "Count"
// +enum
#PodFailurePolicyOnExitCodesOperator: string // #enumPodFailurePolicyOnExitCodesOperator
#enumPodFailurePolicyOnExitCodesOperator:
#PodFailurePolicyOnExitCodesOpIn |
#PodFailurePolicyOnExitCodesOpNotIn
#PodFailurePolicyOnExitCodesOpIn: #PodFailurePolicyOnExitCodesOperator & "In"
#PodFailurePolicyOnExitCodesOpNotIn: #PodFailurePolicyOnExitCodesOperator & "NotIn"
// PodReplacementPolicy specifies the policy for creating pod replacements.
// +enum
#PodReplacementPolicy: string // #enumPodReplacementPolicy
#enumPodReplacementPolicy:
#TerminatingOrFailed |
#Failed
// TerminatingOrFailed means that we recreate pods
// when they are terminating (has a metadata.deletionTimestamp) or failed.
#TerminatingOrFailed: #PodReplacementPolicy & "TerminatingOrFailed"
// Failed means to wait until a previously created Pod is fully terminated (has phase
// Failed or Succeeded) before creating a replacement Pod.
#Failed: #PodReplacementPolicy & "Failed"
// PodFailurePolicyOnExitCodesRequirement describes the requirement for handling
// a failed pod based on its container exit codes. In particular, it lookups the
// .state.terminated.exitCode for each app container and init container status,
// represented by the .status.containerStatuses and .status.initContainerStatuses
// fields in the Pod status, respectively. Containers completed with success
// (exit code 0) are excluded from the requirement check.
#PodFailurePolicyOnExitCodesRequirement: {
// Restricts the check for exit codes to the container with the
// specified name. When null, the rule applies to all containers.
// When specified, it should match one the container or initContainer
// names in the pod template.
// +optional
containerName?: null | string @go(ContainerName,*string) @protobuf(1,bytes,opt)
// Represents the relationship between the container exit code(s) and the
// specified values. Containers completed with success (exit code 0) are
// excluded from the requirement check. Possible values are:
//
// - In: the requirement is satisfied if at least one container exit code
// (might be multiple if there are multiple containers not restricted
// by the 'containerName' field) is in the set of specified values.
// - NotIn: the requirement is satisfied if at least one container exit code
// (might be multiple if there are multiple containers not restricted
// by the 'containerName' field) is not in the set of specified values.
// Additional values are considered to be added in the future. Clients should
// react to an unknown operator by assuming the requirement is not satisfied.
operator: #PodFailurePolicyOnExitCodesOperator @go(Operator) @protobuf(2,bytes,req)
// Specifies the set of values. Each returned container exit code (might be
// multiple in case of multiple containers) is checked against this set of
// values with respect to the operator. The list of values must be ordered
// and must not contain duplicates. Value '0' cannot be used for the In operator.
// At least one element is required. At most 255 elements are allowed.
// +listType=set
values: [...int32] @go(Values,[]int32) @protobuf(3,varint,rep)
}
// PodFailurePolicyOnPodConditionsPattern describes a pattern for matching
// an actual pod condition type.
#PodFailurePolicyOnPodConditionsPattern: {
// Specifies the required Pod condition type. To match a pod condition
// it is required that specified type equals the pod condition type.
type: corev1.#PodConditionType @go(Type) @protobuf(1,bytes,req)
// Specifies the required Pod condition status. To match a pod condition
// it is required that the specified status equals the pod condition status.
// Defaults to True.
status: corev1.#ConditionStatus @go(Status) @protobuf(2,bytes,req)
}
// PodFailurePolicyRule describes how a pod failure is handled when the requirements are met.
// One of onExitCodes and onPodConditions, but not both, can be used in each rule.
#PodFailurePolicyRule: {
// Specifies the action taken on a pod failure when the requirements are satisfied.
// Possible values are:
//
// - FailJob: indicates that the pod's job is marked as Failed and all
// running pods are terminated.
// - FailIndex: indicates that the pod's index is marked as Failed and will
// not be restarted.
// This value is beta-level. It can be used when the
// `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).
// - Ignore: indicates that the counter towards the .backoffLimit is not
// incremented and a replacement pod is created.
// - Count: indicates that the pod is handled in the default way - the
// counter towards the .backoffLimit is incremented.
// Additional values are considered to be added in the future. Clients should
// react to an unknown action by skipping the rule.
action: #PodFailurePolicyAction @go(Action) @protobuf(1,bytes,req)
// Represents the requirement on the container exit codes.
// +optional
onExitCodes?: null | #PodFailurePolicyOnExitCodesRequirement @go(OnExitCodes,*PodFailurePolicyOnExitCodesRequirement) @protobuf(2,bytes,opt)
// Represents the requirement on the pod conditions. The requirement is represented
// as a list of pod condition patterns. The requirement is satisfied if at
// least one pattern matches an actual pod condition. At most 20 elements are allowed.
// +listType=atomic
// +optional
onPodConditions?: [...#PodFailurePolicyOnPodConditionsPattern] @go(OnPodConditions,[]PodFailurePolicyOnPodConditionsPattern) @protobuf(3,bytes,opt)
}
// PodFailurePolicy describes how failed pods influence the backoffLimit.
#PodFailurePolicy: {
// A list of pod failure policy rules. The rules are evaluated in order.
// Once a rule matches a Pod failure, the remaining of the rules are ignored.
// When no rule matches the Pod failure, the default handling applies - the
// counter of pod failures is incremented and it is checked against
// the backoffLimit. At most 20 elements are allowed.
// +listType=atomic
rules: [...#PodFailurePolicyRule] @go(Rules,[]PodFailurePolicyRule) @protobuf(1,bytes,opt)
}
// JobSpec describes how the job execution will look like.
#JobSpec: {
// Specifies the maximum desired number of pods the job should
// run at any given time. The actual number of pods running in steady state will
// be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism),
// i.e. when the work left to do is less than max parallelism.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
// +optional
parallelism?: null | int32 @go(Parallelism,*int32) @protobuf(1,varint,opt)
// Specifies the desired number of successfully finished pods the
// job should be run with. Setting to null means that the success of any
// pod signals the success of all pods, and allows parallelism to have any positive
// value. Setting to 1 means that parallelism is limited to 1 and the success of that
// pod signals the success of the job.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
// +optional
completions?: null | int32 @go(Completions,*int32) @protobuf(2,varint,opt)
// Specifies the duration in seconds relative to the startTime that the job
// may be continuously active before the system tries to terminate it; value
// must be positive integer. If a Job is suspended (at creation or through an
// update), this timer will effectively be stopped and reset when the Job is
// resumed again.
// +optional
activeDeadlineSeconds?: null | int64 @go(ActiveDeadlineSeconds,*int64) @protobuf(3,varint,opt)
// Specifies the policy of handling failed pods. In particular, it allows to
// specify the set of actions and conditions which need to be
// satisfied to take the associated action.
// If empty, the default behaviour applies - the counter of failed pods,
// represented by the jobs's .status.failed field, is incremented and it is
// checked against the backoffLimit. This field cannot be used in combination
// with restartPolicy=OnFailure.
//
// This field is beta-level. It can be used when the `JobPodFailurePolicy`
// feature gate is enabled (enabled by default).
// +optional
podFailurePolicy?: null | #PodFailurePolicy @go(PodFailurePolicy,*PodFailurePolicy) @protobuf(11,bytes,opt)
// Specifies the number of retries before marking this job failed.
// Defaults to 6
// +optional
backoffLimit?: null | int32 @go(BackoffLimit,*int32) @protobuf(7,varint,opt)
// Specifies the limit for the number of retries within an
// index before marking this index as failed. When enabled the number of
// failures per index is kept in the pod's
// batch.kubernetes.io/job-index-failure-count annotation. It can only
// be set when Job's completionMode=Indexed, and the Pod's restart
// policy is Never. The field is immutable.
// This field is beta-level. It can be used when the `JobBackoffLimitPerIndex`
// feature gate is enabled (enabled by default).
// +optional
backoffLimitPerIndex?: null | int32 @go(BackoffLimitPerIndex,*int32) @protobuf(12,varint,opt)
// Specifies the maximal number of failed indexes before marking the Job as
// failed, when backoffLimitPerIndex is set. Once the number of failed
// indexes exceeds this number the entire Job is marked as Failed and its
// execution is terminated. When left as null the job continues execution of
// all of its indexes and is marked with the `Complete` Job condition.
// It can only be specified when backoffLimitPerIndex is set.
// It can be null or up to completions. It is required and must be
// less than or equal to 10^4 when is completions greater than 10^5.
// This field is beta-level. It can be used when the `JobBackoffLimitPerIndex`
// feature gate is enabled (enabled by default).
// +optional
maxFailedIndexes?: null | int32 @go(MaxFailedIndexes,*int32) @protobuf(13,varint,opt)
// A label query over pods that should match the pod count.
// Normally, the system sets this field for you.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
// +optional
selector?: null | metav1.#LabelSelector @go(Selector,*metav1.LabelSelector) @protobuf(4,bytes,opt)
// manualSelector controls generation of pod labels and pod selectors.
// Leave `manualSelector` unset unless you are certain what you are doing.
// When false or unset, the system pick labels unique to this job
// and appends those labels to the pod template. When true,
// the user is responsible for picking unique labels and specifying
// the selector. Failure to pick a unique label may cause this
// and other jobs to not function correctly. However, You may see
// `manualSelector=true` in jobs that were created with the old `extensions/v1beta1`
// API.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector
// +optional
manualSelector?: null | bool @go(ManualSelector,*bool) @protobuf(5,varint,opt)
// Describes the pod that will be created when executing a job.
// The only allowed template.spec.restartPolicy values are "Never" or "OnFailure".
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
template: corev1.#PodTemplateSpec @go(Template) @protobuf(6,bytes,opt)
// ttlSecondsAfterFinished limits the lifetime of a Job that has finished
// execution (either Complete or Failed). If this field is set,
// ttlSecondsAfterFinished after the Job finishes, it is eligible to be
// automatically deleted. When the Job is being deleted, its lifecycle
// guarantees (e.g. finalizers) will be honored. If this field is unset,
// the Job won't be automatically deleted. If this field is set to zero,
// the Job becomes eligible to be deleted immediately after it finishes.
// +optional
ttlSecondsAfterFinished?: null | int32 @go(TTLSecondsAfterFinished,*int32) @protobuf(8,varint,opt)
// completionMode specifies how Pod completions are tracked. It can be
// `NonIndexed` (default) or `Indexed`.
//
// `NonIndexed` means that the Job is considered complete when there have
// been .spec.completions successfully completed Pods. Each Pod completion is
// homologous to each other.
//
// `Indexed` means that the Pods of a
// Job get an associated completion index from 0 to (.spec.completions - 1),
// available in the annotation batch.kubernetes.io/job-completion-index.
// The Job is considered complete when there is one successfully completed Pod
// for each index.
// When value is `Indexed`, .spec.completions must be specified and
// `.spec.parallelism` must be less than or equal to 10^5.
// In addition, The Pod name takes the form
// `$(job-name)-$(index)-$(random-string)`,
// the Pod hostname takes the form `$(job-name)-$(index)`.
//
// More completion modes can be added in the future.
// If the Job controller observes a mode that it doesn't recognize, which
// is possible during upgrades due to version skew, the controller
// skips updates for the Job.
// +optional
completionMode?: null | #CompletionMode @go(CompletionMode,*CompletionMode) @protobuf(9,bytes,opt,casttype=CompletionMode)
// suspend specifies whether the Job controller should create Pods or not. If
// a Job is created with suspend set to true, no Pods are created by the Job
// controller. If a Job is suspended after creation (i.e. the flag goes from
// false to true), the Job controller will delete all active Pods associated
// with this Job. Users must design their workload to gracefully handle this.
// Suspending a Job will reset the StartTime field of the Job, effectively
// resetting the ActiveDeadlineSeconds timer too. Defaults to false.
//
// +optional
suspend?: null | bool @go(Suspend,*bool) @protobuf(10,varint,opt)
// podReplacementPolicy specifies when to create replacement Pods.
// Possible values are:
// - TerminatingOrFailed means that we recreate pods
// when they are terminating (has a metadata.deletionTimestamp) or failed.
// - Failed means to wait until a previously created Pod is fully terminated (has phase
// Failed or Succeeded) before creating a replacement Pod.
//
// When using podFailurePolicy, Failed is the the only allowed value.
// TerminatingOrFailed and Failed are allowed values when podFailurePolicy is not in use.
// This is an beta field. To use this, enable the JobPodReplacementPolicy feature toggle.
// This is on by default.
// +optional
podReplacementPolicy?: null | #PodReplacementPolicy @go(PodReplacementPolicy,*PodReplacementPolicy) @protobuf(14,bytes,opt,casttype=podReplacementPolicy)
}
// JobStatus represents the current state of a Job.
#JobStatus: {
// The latest available observations of an object's current state. When a Job
// fails, one of the conditions will have type "Failed" and status true. When
// a Job is suspended, one of the conditions will have type "Suspended" and
// status true; when the Job is resumed, the status of this condition will
// become false. When a Job is completed, one of the conditions will have
// type "Complete" and status true.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=atomic
conditions?: [...#JobCondition] @go(Conditions,[]JobCondition) @protobuf(1,bytes,rep)
// Represents time when the job controller started processing a job. When a
// Job is created in the suspended state, this field is not set until the
// first time it is resumed. This field is reset every time a Job is resumed
// from suspension. It is represented in RFC3339 form and is in UTC.
// +optional
startTime?: null | metav1.#Time @go(StartTime,*metav1.Time) @protobuf(2,bytes,opt)
// Represents time when the job was completed. It is not guaranteed to
// be set in happens-before order across separate operations.
// It is represented in RFC3339 form and is in UTC.
// The completion time is only set when the job finishes successfully.
// +optional
completionTime?: null | metav1.#Time @go(CompletionTime,*metav1.Time) @protobuf(3,bytes,opt)
// The number of pending and running pods.
// +optional
active?: int32 @go(Active) @protobuf(4,varint,opt)
// The number of pods which reached phase Succeeded.
// +optional
succeeded?: int32 @go(Succeeded) @protobuf(5,varint,opt)
// The number of pods which reached phase Failed.
// +optional
failed?: int32 @go(Failed) @protobuf(6,varint,opt)
// The number of pods which are terminating (in phase Pending or Running
// and have a deletionTimestamp).
//
// This field is beta-level. The job controller populates the field when
// the feature gate JobPodReplacementPolicy is enabled (enabled by default).
// +optional
terminating?: null | int32 @go(Terminating,*int32) @protobuf(11,varint,opt)
// completedIndexes holds the completed indexes when .spec.completionMode =
// "Indexed" in a text format. The indexes are represented as decimal integers
// separated by commas. The numbers are listed in increasing order. Three or
// more consecutive numbers are compressed and represented by the first and
// last element of the series, separated by a hyphen.
// For example, if the completed indexes are 1, 3, 4, 5 and 7, they are
// represented as "1,3-5,7".
// +optional
completedIndexes?: string @go(CompletedIndexes) @protobuf(7,bytes,opt)
// FailedIndexes holds the failed indexes when backoffLimitPerIndex=true.
// The indexes are represented in the text format analogous as for the
// `completedIndexes` field, ie. they are kept as decimal integers
// separated by commas. The numbers are listed in increasing order. Three or
// more consecutive numbers are compressed and represented by the first and
// last element of the series, separated by a hyphen.
// For example, if the failed indexes are 1, 3, 4, 5 and 7, they are
// represented as "1,3-5,7".
// This field is beta-level. It can be used when the `JobBackoffLimitPerIndex`
// feature gate is enabled (enabled by default).
// +optional
failedIndexes?: null | string @go(FailedIndexes,*string) @protobuf(10,bytes,opt)
// uncountedTerminatedPods holds the UIDs of Pods that have terminated but
// the job controller hasn't yet accounted for in the status counters.
//
// The job controller creates pods with a finalizer. When a pod terminates
// (succeeded or failed), the controller does three steps to account for it
// in the job status:
//
// 1. Add the pod UID to the arrays in this field.
// 2. Remove the pod finalizer.
// 3. Remove the pod UID from the arrays while increasing the corresponding
// counter.
//
// Old jobs might not be tracked using this field, in which case the field
// remains null.
// +optional
uncountedTerminatedPods?: null | #UncountedTerminatedPods @go(UncountedTerminatedPods,*UncountedTerminatedPods) @protobuf(8,bytes,opt)
// The number of pods which have a Ready condition.
// +optional
ready?: null | int32 @go(Ready,*int32) @protobuf(9,varint,opt)
}
// UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't
// been accounted in Job status counters.
#UncountedTerminatedPods: {
// succeeded holds UIDs of succeeded Pods.
// +listType=set
// +optional
succeeded?: [...types.#UID] @go(Succeeded,[]types.UID) @protobuf(1,bytes,rep,casttype=k8s.io/apimachinery/pkg/types.UID)
// failed holds UIDs of failed Pods.
// +listType=set
// +optional
failed?: [...types.#UID] @go(Failed,[]types.UID) @protobuf(2,bytes,rep,casttype=k8s.io/apimachinery/pkg/types.UID)
}
#JobConditionType: string // #enumJobConditionType
#enumJobConditionType:
#JobSuspended |
#JobComplete |
#JobFailed |
#JobFailureTarget
// JobSuspended means the job has been suspended.
#JobSuspended: #JobConditionType & "Suspended"
// JobComplete means the job has completed its execution.
#JobComplete: #JobConditionType & "Complete"
// JobFailed means the job has failed its execution.
#JobFailed: #JobConditionType & "Failed"
// FailureTarget means the job is about to fail its execution.
#JobFailureTarget: #JobConditionType & "FailureTarget"
// JobReasonPodFailurePolicy reason indicates a job failure condition is added due to
// a failed pod matching a pod failure policy rule
// https://kep.k8s.io/3329
// This is currently a beta field.
#JobReasonPodFailurePolicy: "PodFailurePolicy"
// JobReasonBackOffLimitExceeded reason indicates that pods within a job have failed a number of
// times higher than backOffLimit times.
#JobReasonBackoffLimitExceeded: "BackoffLimitExceeded"
// JobReasponDeadlineExceeded means job duration is past ActiveDeadline
#JobReasonDeadlineExceeded: "DeadlineExceeded"
// JobReasonMaxFailedIndexesExceeded indicates that an indexed of a job failed
// This const is used in beta-level feature: https://kep.k8s.io/3850.
#JobReasonMaxFailedIndexesExceeded: "MaxFailedIndexesExceeded"
// JobReasonFailedIndexes means Job has failed indexes.
// This const is used in beta-level feature: https://kep.k8s.io/3850.
#JobReasonFailedIndexes: "FailedIndexes"
// JobCondition describes current state of a job.
#JobCondition: {
// Type of job condition, Complete or Failed.
type: #JobConditionType @go(Type) @protobuf(1,bytes,opt,casttype=JobConditionType)
// Status of the condition, one of True, False, Unknown.
status: corev1.#ConditionStatus @go(Status) @protobuf(2,bytes,opt,casttype=k8s.io/api/core/v1.ConditionStatus)
// Last time the condition was checked.
// +optional
lastProbeTime?: metav1.#Time @go(LastProbeTime) @protobuf(3,bytes,opt)
// Last time the condition transit from one status to another.
// +optional
lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(4,bytes,opt)
// (brief) reason for the condition's last transition.
// +optional
reason?: string @go(Reason) @protobuf(5,bytes,opt)
// Human readable message indicating details about last transition.
// +optional
message?: string @go(Message) @protobuf(6,bytes,opt)
}
// JobTemplateSpec describes the data a Job should have when created from a template
#JobTemplateSpec: {
// Standard object's metadata of the jobs created from this template.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Specification of the desired behavior of the job.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
spec?: #JobSpec @go(Spec) @protobuf(2,bytes,opt)
}
// CronJob represents the configuration of a single cron job.
#CronJob: {
metav1.#TypeMeta
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Specification of the desired behavior of a cron job, including the schedule.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
spec?: #CronJobSpec @go(Spec) @protobuf(2,bytes,opt)
// Current status of a cron job.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
status?: #CronJobStatus @go(Status) @protobuf(3,bytes,opt)
}
// CronJobList is a collection of cron jobs.
#CronJobList: {
metav1.#TypeMeta
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// items is the list of CronJobs.
items: [...#CronJob] @go(Items,[]CronJob) @protobuf(2,bytes,rep)
}
// CronJobSpec describes how the job execution will look like and when it will actually run.
#CronJobSpec: {
// The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
schedule: string @go(Schedule) @protobuf(1,bytes,opt)
// The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
// If not specified, this will default to the time zone of the kube-controller-manager process.
// The set of valid time zone names and the time zone offset is loaded from the system-wide time zone
// database by the API server during CronJob validation and the controller manager during execution.
// If no system-wide time zone database can be found a bundled version of the database is used instead.
// If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host
// configuration, the controller will stop creating new new Jobs and will create a system event with the
// reason UnknownTimeZone.
// More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones
// +optional
timeZone?: null | string @go(TimeZone,*string) @protobuf(8,bytes,opt)
// Optional deadline in seconds for starting the job if it misses scheduled
// time for any reason. Missed jobs executions will be counted as failed ones.
// +optional
startingDeadlineSeconds?: null | int64 @go(StartingDeadlineSeconds,*int64) @protobuf(2,varint,opt)
// Specifies how to treat concurrent executions of a Job.
// Valid values are:
//
// - "Allow" (default): allows CronJobs to run concurrently;
// - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet;
// - "Replace": cancels currently running job and replaces it with a new one
// +optional
concurrencyPolicy?: #ConcurrencyPolicy @go(ConcurrencyPolicy) @protobuf(3,bytes,opt,casttype=ConcurrencyPolicy)
// This flag tells the controller to suspend subsequent executions, it does
// not apply to already started executions. Defaults to false.
// +optional
suspend?: null | bool @go(Suspend,*bool) @protobuf(4,varint,opt)
// Specifies the job that will be created when executing a CronJob.
jobTemplate: #JobTemplateSpec @go(JobTemplate) @protobuf(5,bytes,opt)
// The number of successful finished jobs to retain. Value must be non-negative integer.
// Defaults to 3.
// +optional
successfulJobsHistoryLimit?: null | int32 @go(SuccessfulJobsHistoryLimit,*int32) @protobuf(6,varint,opt)
// The number of failed finished jobs to retain. Value must be non-negative integer.
// Defaults to 1.
// +optional
failedJobsHistoryLimit?: null | int32 @go(FailedJobsHistoryLimit,*int32) @protobuf(7,varint,opt)
}
// ConcurrencyPolicy describes how the job will be handled.
// Only one of the following concurrent policies may be specified.
// If none of the following policies is specified, the default one
// is AllowConcurrent.
// +enum
#ConcurrencyPolicy: string // #enumConcurrencyPolicy
#enumConcurrencyPolicy:
#AllowConcurrent |
#ForbidConcurrent |
#ReplaceConcurrent
// AllowConcurrent allows CronJobs to run concurrently.
#AllowConcurrent: #ConcurrencyPolicy & "Allow"
// ForbidConcurrent forbids concurrent runs, skipping next run if previous
// hasn't finished yet.
#ForbidConcurrent: #ConcurrencyPolicy & "Forbid"
// ReplaceConcurrent cancels currently running job and replaces it with a new one.
#ReplaceConcurrent: #ConcurrencyPolicy & "Replace"
// CronJobStatus represents the current state of a cron job.
#CronJobStatus: {
// A list of pointers to currently running jobs.
// +optional
// +listType=atomic
active?: [...corev1.#ObjectReference] @go(Active,[]corev1.ObjectReference) @protobuf(1,bytes,rep)
// Information when was the last time the job was successfully scheduled.
// +optional
lastScheduleTime?: null | metav1.#Time @go(LastScheduleTime,*metav1.Time) @protobuf(4,bytes,opt)
// Information when was the last time the job successfully completed.
// +optional
lastSuccessfulTime?: null | metav1.#Time @go(LastSuccessfulTime,*metav1.Time) @protobuf(5,bytes,opt)
}

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/rbac/v1
package v1
#GroupName: "rbac.authorization.k8s.io"

View File

@@ -0,0 +1,207 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/rbac/v1
package v1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
#APIGroupAll: "*"
#ResourceAll: "*"
#VerbAll: "*"
#NonResourceAll: "*"
#GroupKind: "Group"
#ServiceAccountKind: "ServiceAccount"
#UserKind: "User"
// AutoUpdateAnnotationKey is the name of an annotation which prevents reconciliation if set to "false"
#AutoUpdateAnnotationKey: "rbac.authorization.kubernetes.io/autoupdate"
// PolicyRule holds information that describes a policy rule, but does not contain information
// about who the rule applies to or which namespace the rule applies to.
#PolicyRule: {
// Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs.
verbs: [...string] @go(Verbs,[]string) @protobuf(1,bytes,rep)
// APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of
// the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups.
// +optional
apiGroups?: [...string] @go(APIGroups,[]string) @protobuf(2,bytes,rep)
// Resources is a list of resources this rule applies to. '*' represents all resources.
// +optional
resources?: [...string] @go(Resources,[]string) @protobuf(3,bytes,rep)
// ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +optional
resourceNames?: [...string] @go(ResourceNames,[]string) @protobuf(4,bytes,rep)
// NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path
// Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
// Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
// +optional
nonResourceURLs?: [...string] @go(NonResourceURLs,[]string) @protobuf(5,bytes,rep)
}
// Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference,
// or a value for non-objects such as user and group names.
// +structType=atomic
#Subject: {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
kind: string @go(Kind) @protobuf(1,bytes,opt)
// APIGroup holds the API group of the referenced subject.
// Defaults to "" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
// +optional
apiGroup?: string @go(APIGroup) @protobuf(2,bytes,opt.name=apiGroup)
// Name of the object being referenced.
name: string @go(Name) @protobuf(3,bytes,opt)
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty
// the Authorizer should report an error.
// +optional
namespace?: string @go(Namespace) @protobuf(4,bytes,opt)
}
// RoleRef contains information that points to the role being used
// +structType=atomic
#RoleRef: {
// APIGroup is the group for the resource being referenced
apiGroup: string @go(APIGroup) @protobuf(1,bytes,opt)
// Kind is the type of resource being referenced
kind: string @go(Kind) @protobuf(2,bytes,opt)
// Name is the name of resource being referenced
name: string @go(Name) @protobuf(3,bytes,opt)
}
// Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.
#Role: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Rules holds all the PolicyRules for this Role
// +optional
rules?: [...#PolicyRule] @go(Rules,[]PolicyRule) @protobuf(2,bytes,rep)
}
// RoleBinding references a role, but does not contain it. It can reference a Role in the same namespace or a ClusterRole in the global namespace.
// It adds who information via Subjects and namespace information by which namespace it exists in. RoleBindings in a given
// namespace only have effect in that namespace.
#RoleBinding: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Subjects holds references to the objects the role applies to.
// +optional
subjects?: [...#Subject] @go(Subjects,[]Subject) @protobuf(2,bytes,rep)
// RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
// This field is immutable.
roleRef: #RoleRef @go(RoleRef) @protobuf(3,bytes,opt)
}
// RoleBindingList is a collection of RoleBindings
#RoleBindingList: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is a list of RoleBindings
items: [...#RoleBinding] @go(Items,[]RoleBinding) @protobuf(2,bytes,rep)
}
// RoleList is a collection of Roles
#RoleList: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is a list of Roles
items: [...#Role] @go(Items,[]Role) @protobuf(2,bytes,rep)
}
// ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding.
#ClusterRole: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Rules holds all the PolicyRules for this ClusterRole
// +optional
rules?: [...#PolicyRule] @go(Rules,[]PolicyRule) @protobuf(2,bytes,rep)
// AggregationRule is an optional field that describes how to build the Rules for this ClusterRole.
// If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be
// stomped by the controller.
// +optional
aggregationRule?: null | #AggregationRule @go(AggregationRule,*AggregationRule) @protobuf(3,bytes,opt)
}
// AggregationRule describes how to locate ClusterRoles to aggregate into the ClusterRole
#AggregationRule: {
// ClusterRoleSelectors holds a list of selectors which will be used to find ClusterRoles and create the rules.
// If any of the selectors match, then the ClusterRole's permissions will be added
// +optional
clusterRoleSelectors?: [...metav1.#LabelSelector] @go(ClusterRoleSelectors,[]metav1.LabelSelector) @protobuf(1,bytes,rep)
}
// ClusterRoleBinding references a ClusterRole, but not contain it. It can reference a ClusterRole in the global namespace,
// and adds who information via Subject.
#ClusterRoleBinding: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Subjects holds references to the objects the role applies to.
// +optional
subjects?: [...#Subject] @go(Subjects,[]Subject) @protobuf(2,bytes,rep)
// RoleRef can only reference a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
// This field is immutable.
roleRef: #RoleRef @go(RoleRef) @protobuf(3,bytes,opt)
}
// ClusterRoleBindingList is a collection of ClusterRoleBindings
#ClusterRoleBindingList: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is a list of ClusterRoleBindings
items: [...#ClusterRoleBinding] @go(Items,[]ClusterRoleBinding) @protobuf(2,bytes,rep)
}
// ClusterRoleList is a collection of ClusterRoles
#ClusterRoleList: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is a list of ClusterRoles
items: [...#ClusterRole] @go(Items,[]ClusterRole) @protobuf(2,bytes,rep)
}

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/rbac/v1beta1
package v1beta1
#GroupName: "rbac.authorization.k8s.io"

View File

@@ -0,0 +1,212 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/rbac/v1beta1
package v1beta1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
#APIGroupAll: "*"
#ResourceAll: "*"
#VerbAll: "*"
#NonResourceAll: "*"
#GroupKind: "Group"
#ServiceAccountKind: "ServiceAccount"
#UserKind: "User"
// AutoUpdateAnnotationKey is the name of an annotation which prevents reconciliation if set to "false"
#AutoUpdateAnnotationKey: "rbac.authorization.kubernetes.io/autoupdate"
// PolicyRule holds information that describes a policy rule, but does not contain information
// about who the rule applies to or which namespace the rule applies to.
#PolicyRule: {
// Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs.
verbs: [...string] @go(Verbs,[]string) @protobuf(1,bytes,rep)
// APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of
// the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups.
// +optional
apiGroups?: [...string] @go(APIGroups,[]string) @protobuf(2,bytes,rep)
// Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups.
// '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups.
// +optional
resources?: [...string] @go(Resources,[]string) @protobuf(3,bytes,rep)
// ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +optional
resourceNames?: [...string] @go(ResourceNames,[]string) @protobuf(4,bytes,rep)
// NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path
// Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
// Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
// +optional
nonResourceURLs?: [...string] @go(NonResourceURLs,[]string) @protobuf(5,bytes,rep)
}
// Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference,
// or a value for non-objects such as user and group names.
#Subject: {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
kind: string @go(Kind) @protobuf(1,bytes,opt)
// APIGroup holds the API group of the referenced subject.
// Defaults to "" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
// +optional
apiGroup?: string @go(APIGroup) @protobuf(2,bytes,opt.name=apiGroup)
// Name of the object being referenced.
name: string @go(Name) @protobuf(3,bytes,opt)
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty
// the Authorizer should report an error.
// +optional
namespace?: string @go(Namespace) @protobuf(4,bytes,opt)
}
// RoleRef contains information that points to the role being used
#RoleRef: {
// APIGroup is the group for the resource being referenced
apiGroup: string @go(APIGroup) @protobuf(1,bytes,opt)
// Kind is the type of resource being referenced
kind: string @go(Kind) @protobuf(2,bytes,opt)
// Name is the name of resource being referenced
name: string @go(Name) @protobuf(3,bytes,opt)
}
// Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.
// Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 Role, and will no longer be served in v1.22.
#Role: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Rules holds all the PolicyRules for this Role
// +optional
rules?: [...#PolicyRule] @go(Rules,[]PolicyRule) @protobuf(2,bytes,rep)
}
// RoleBinding references a role, but does not contain it. It can reference a Role in the same namespace or a ClusterRole in the global namespace.
// It adds who information via Subjects and namespace information by which namespace it exists in. RoleBindings in a given
// namespace only have effect in that namespace.
// Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 RoleBinding, and will no longer be served in v1.22.
#RoleBinding: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Subjects holds references to the objects the role applies to.
// +optional
subjects?: [...#Subject] @go(Subjects,[]Subject) @protobuf(2,bytes,rep)
// RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
roleRef: #RoleRef @go(RoleRef) @protobuf(3,bytes,opt)
}
// RoleBindingList is a collection of RoleBindings
// Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 RoleBindingList, and will no longer be served in v1.22.
#RoleBindingList: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is a list of RoleBindings
items: [...#RoleBinding] @go(Items,[]RoleBinding) @protobuf(2,bytes,rep)
}
// RoleList is a collection of Roles
// Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 RoleList, and will no longer be served in v1.22.
#RoleList: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is a list of Roles
items: [...#Role] @go(Items,[]Role) @protobuf(2,bytes,rep)
}
// ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding.
// Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 ClusterRole, and will no longer be served in v1.22.
#ClusterRole: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Rules holds all the PolicyRules for this ClusterRole
// +optional
rules?: [...#PolicyRule] @go(Rules,[]PolicyRule) @protobuf(2,bytes,rep)
// AggregationRule is an optional field that describes how to build the Rules for this ClusterRole.
// If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be
// stomped by the controller.
// +optional
aggregationRule?: null | #AggregationRule @go(AggregationRule,*AggregationRule) @protobuf(3,bytes,opt)
}
// AggregationRule describes how to locate ClusterRoles to aggregate into the ClusterRole
#AggregationRule: {
// ClusterRoleSelectors holds a list of selectors which will be used to find ClusterRoles and create the rules.
// If any of the selectors match, then the ClusterRole's permissions will be added
// +optional
clusterRoleSelectors?: [...metav1.#LabelSelector] @go(ClusterRoleSelectors,[]metav1.LabelSelector) @protobuf(1,bytes,rep)
}
// ClusterRoleBinding references a ClusterRole, but not contain it. It can reference a ClusterRole in the global namespace,
// and adds who information via Subject.
// Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 ClusterRoleBinding, and will no longer be served in v1.22.
#ClusterRoleBinding: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Subjects holds references to the objects the role applies to.
// +optional
subjects?: [...#Subject] @go(Subjects,[]Subject) @protobuf(2,bytes,rep)
// RoleRef can only reference a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
roleRef: #RoleRef @go(RoleRef) @protobuf(3,bytes,opt)
}
// ClusterRoleBindingList is a collection of ClusterRoleBindings.
// Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 ClusterRoleBindingList, and will no longer be served in v1.22.
#ClusterRoleBindingList: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is a list of ClusterRoleBindings
items: [...#ClusterRoleBinding] @go(Items,[]ClusterRoleBinding) @protobuf(2,bytes,rep)
}
// ClusterRoleList is a collection of ClusterRoles.
// Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 ClusterRoles, and will no longer be served in v1.22.
#ClusterRoleList: {
metav1.#TypeMeta
// Standard object's metadata.
// +optional
metadata?: metav1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// Items is a list of ClusterRoles
items: [...#ClusterRole] @go(Items,[]ClusterRole) @protobuf(2,bytes,rep)
}

View File

@@ -198,7 +198,7 @@ import (
// and services.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
// +optional
labels?: {[string]: string} @go(Labels,map[string]string) @protobuf(12,bytes,rep)
labels?: {[string]: string} @go(Labels,map[string]string) @protobuf(11,bytes,rep)
// Annotations is an unstructured key value map stored with a resource that may be
// set by external tools to store and retrieve arbitrary metadata. They are not

View File

@@ -0,0 +1,213 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws2/components/istio-base/istio-base.gen.yaml
package v1alpha3
import "strings"
#EnvoyFilter: {
// Customizing Envoy configuration generated by Istio. See more
// details at:
// https://istio.io/docs/reference/config/networking/envoy-filter.html
spec!: #EnvoyFilterSpec
apiVersion: "networking.istio.io/v1alpha3"
kind: "EnvoyFilter"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
}
// Customizing Envoy configuration generated by Istio. See more
// details at:
// https://istio.io/docs/reference/config/networking/envoy-filter.html
#EnvoyFilterSpec: {
// One or more patches with match conditions.
configPatches?: [...{
// Specifies where in the Envoy configuration, the patch should be
// applied.
//
// Valid Options: LISTENER, FILTER_CHAIN, NETWORK_FILTER,
// HTTP_FILTER, ROUTE_CONFIGURATION, VIRTUAL_HOST, HTTP_ROUTE,
// CLUSTER, EXTENSION_CONFIG, BOOTSTRAP, LISTENER_FILTER
applyTo?: "INVALID" | "LISTENER" | "FILTER_CHAIN" | "NETWORK_FILTER" | "HTTP_FILTER" | "ROUTE_CONFIGURATION" | "VIRTUAL_HOST" | "HTTP_ROUTE" | "CLUSTER" | "EXTENSION_CONFIG" | "BOOTSTRAP" | "LISTENER_FILTER"
// Match on listener/route configuration/cluster.
match?: ({} | {
listener: _
} | {
routeConfiguration: _
} | {
cluster: _
}) & {
// Match on envoy cluster attributes.
cluster?: {
// The exact name of the cluster to match.
name?: string
// The service port for which this cluster was generated.
portNumber?: uint32
// The fully qualified service name for this cluster.
service?: string
// The subset associated with the service.
subset?: string
}
// The specific config generation context to match on.
//
// Valid Options: ANY, SIDECAR_INBOUND, SIDECAR_OUTBOUND, GATEWAY
context?: "ANY" | "SIDECAR_INBOUND" | "SIDECAR_OUTBOUND" | "GATEWAY"
// Match on envoy listener attributes.
listener?: {
// Match a specific filter chain in a listener.
filterChain?: {
// Applies only to sidecars.
applicationProtocols?: string
// The destination_port value used by a filter chain's match
// condition.
destinationPort?: uint32
// The name of a specific filter to apply the patch to.
filter?: {
// The filter name to match on.
name?: string
subFilter?: {
// The filter name to match on.
name?: string
}
}
// The name assigned to the filter chain.
name?: string
// The SNI value used by a filter chain's match condition.
sni?: string
// Applies only to `SIDECAR_INBOUND` context.
transportProtocol?: string
}
// Match a specific listener filter.
listenerFilter?: string
// Match a specific listener by its name.
name?: string
portName?: string
// The service port/gateway port to which traffic is being
// sent/received.
portNumber?: uint32
}
// Match on properties associated with a proxy.
proxy?: {
// Match on the node metadata supplied by a proxy when connecting
// to Istio Pilot.
metadata?: {
[string]: string
}
// A regular expression in golang regex format (RE2) that can be
// used to select proxies using a specific version of istio
// proxy.
proxyVersion?: string
}
// Match on envoy HTTP route configuration attributes.
routeConfiguration?: {
// The Istio gateway config's namespace/name for which this route
// configuration was generated.
gateway?: string
// Route configuration name to match on.
name?: string
// Applicable only for GATEWAY context.
portName?: string
// The service port number or gateway server port number for which
// this route configuration was generated.
portNumber?: uint32
// Match a specific virtual host in a route configuration and
// apply the patch to the virtual host.
vhost?: {
// The VirtualHosts objects generated by Istio are named as
// host:port, where the host typically corresponds to the
// VirtualService's host field or the hostname of a service in
// the registry.
name?: string
// Match a specific route within the virtual host.
route?: {
// Match a route with specific action type.
//
// Valid Options: ANY, ROUTE, REDIRECT, DIRECT_RESPONSE
action?: "ANY" | "ROUTE" | "REDIRECT" | "DIRECT_RESPONSE"
// The Route objects generated by default are named as default.
name?: string
}
}
}
}
// The patch to apply along with the operation.
patch?: {
// Determines the filter insertion order.
//
// Valid Options: AUTHN, AUTHZ, STATS
filterClass?: "UNSPECIFIED" | "AUTHN" | "AUTHZ" | "STATS"
// Determines how the patch should be applied.
//
// Valid Options: MERGE, ADD, REMOVE, INSERT_BEFORE, INSERT_AFTER,
// INSERT_FIRST, REPLACE
operation?: "INVALID" | "MERGE" | "ADD" | "REMOVE" | "INSERT_BEFORE" | "INSERT_AFTER" | "INSERT_FIRST" | "REPLACE"
// The JSON config of the object being patched.
value?: {}
}
}]
// Priority defines the order in which patch sets are applied
// within a context.
priority?: int
// Optional.
targetRefs?: [...{
// group is the group of the target resource.
group?: string
// kind is kind of the target resource.
kind?: string
// name is the name of the target resource.
name?: string
// namespace is the namespace of the referent.
namespace?: string
}]
workloadSelector?: {
// One or more labels that indicate a specific set of pods/VMs on
// which the configuration should be applied.
labels?: {
[string]: string
}
}
}

View File

@@ -0,0 +1,127 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws2/components/istio-base/istio-base.gen.yaml
package v1
import "strings"
#Gateway: {
// Configuration affecting edge load balancer. See more details
// at:
// https://istio.io/docs/reference/config/networking/gateway.html
spec!: #GatewaySpec
apiVersion: "networking.istio.io/v1"
kind: "Gateway"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
}
// Configuration affecting edge load balancer. See more details
// at:
// https://istio.io/docs/reference/config/networking/gateway.html
#GatewaySpec: {
// One or more labels that indicate a specific set of pods/VMs on
// which this gateway configuration should be applied.
selector?: {
[string]: string
}
// A list of server specifications.
servers?: [...{
// The ip or the Unix domain socket to which the listener should
// be bound to.
bind?: string
defaultEndpoint?: string
// One or more hosts exposed by this gateway.
hosts: [...string]
// An optional name of the server, when set must be unique across
// all servers.
name?: string
// The Port on which the proxy should listen for incoming
// connections.
port: {
// Label assigned to the port.
name: string
// A valid non-negative integer port number.
number: uint32
// The protocol exposed on the port.
protocol: string
targetPort?: uint32
}
// Set of TLS related options that govern the server's behavior.
tls?: {
// REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`.
caCertificates?: string
// OPTIONAL: The path to the file containing the certificate
// revocation list (CRL) to use in verifying a presented client
// side certificate.
caCrl?: string
// Optional: If specified, only support the specified cipher list.
cipherSuites?: [...string]
// For gateways running on Kubernetes, the name of the secret that
// holds the TLS certs including the CA certificates.
credentialName?: string
// If set to true, the load balancer will send a 301 redirect for
// all http connections, asking the clients to use HTTPS.
httpsRedirect?: bool
// Optional: Maximum TLS protocol version.
//
// Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3
maxProtocolVersion?: "TLS_AUTO" | "TLSV1_0" | "TLSV1_1" | "TLSV1_2" | "TLSV1_3"
// Optional: Minimum TLS protocol version.
//
// Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3
minProtocolVersion?: "TLS_AUTO" | "TLSV1_0" | "TLSV1_1" | "TLSV1_2" | "TLSV1_3"
// Optional: Indicates whether connections to this port should be
// secured using TLS.
//
// Valid Options: PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH,
// ISTIO_MUTUAL, OPTIONAL_MUTUAL
mode?: "PASSTHROUGH" | "SIMPLE" | "MUTUAL" | "AUTO_PASSTHROUGH" | "ISTIO_MUTUAL" | "OPTIONAL_MUTUAL"
// REQUIRED if mode is `SIMPLE` or `MUTUAL`.
privateKey?: string
// REQUIRED if mode is `SIMPLE` or `MUTUAL`.
serverCertificate?: string
// A list of alternate names to verify the subject identity in the
// certificate presented by the client.
subjectAltNames?: [...string]
// An optional list of hex-encoded SHA-256 hashes of the
// authorized client certificates.
verifyCertificateHash?: [...string]
// An optional list of base64-encoded SHA-256 hashes of the SPKIs
// of authorized client certificates.
verifyCertificateSpki?: [...string]
}
}]
}

View File

@@ -0,0 +1,127 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f deploy/clusters/aws2/components/istio-base/istio-base.gen.yaml
package v1alpha3
import "strings"
#Gateway: {
// Configuration affecting edge load balancer. See more details
// at:
// https://istio.io/docs/reference/config/networking/gateway.html
spec!: #GatewaySpec
apiVersion: "networking.istio.io/v1alpha3"
kind: "Gateway"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
}
// Configuration affecting edge load balancer. See more details
// at:
// https://istio.io/docs/reference/config/networking/gateway.html
#GatewaySpec: {
// One or more labels that indicate a specific set of pods/VMs on
// which this gateway configuration should be applied.
selector?: {
[string]: string
}
// A list of server specifications.
servers?: [...{
// The ip or the Unix domain socket to which the listener should
// be bound to.
bind?: string
defaultEndpoint?: string
// One or more hosts exposed by this gateway.
hosts: [...string]
// An optional name of the server, when set must be unique across
// all servers.
name?: string
// The Port on which the proxy should listen for incoming
// connections.
port: {
// Label assigned to the port.
name: string
// A valid non-negative integer port number.
number: uint32
// The protocol exposed on the port.
protocol: string
targetPort?: uint32
}
// Set of TLS related options that govern the server's behavior.
tls?: {
// REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`.
caCertificates?: string
// OPTIONAL: The path to the file containing the certificate
// revocation list (CRL) to use in verifying a presented client
// side certificate.
caCrl?: string
// Optional: If specified, only support the specified cipher list.
cipherSuites?: [...string]
// For gateways running on Kubernetes, the name of the secret that
// holds the TLS certs including the CA certificates.
credentialName?: string
// If set to true, the load balancer will send a 301 redirect for
// all http connections, asking the clients to use HTTPS.
httpsRedirect?: bool
// Optional: Maximum TLS protocol version.
//
// Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3
maxProtocolVersion?: "TLS_AUTO" | "TLSV1_0" | "TLSV1_1" | "TLSV1_2" | "TLSV1_3"
// Optional: Minimum TLS protocol version.
//
// Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3
minProtocolVersion?: "TLS_AUTO" | "TLSV1_0" | "TLSV1_1" | "TLSV1_2" | "TLSV1_3"
// Optional: Indicates whether connections to this port should be
// secured using TLS.
//
// Valid Options: PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH,
// ISTIO_MUTUAL, OPTIONAL_MUTUAL
mode?: "PASSTHROUGH" | "SIMPLE" | "MUTUAL" | "AUTO_PASSTHROUGH" | "ISTIO_MUTUAL" | "OPTIONAL_MUTUAL"
// REQUIRED if mode is `SIMPLE` or `MUTUAL`.
privateKey?: string
// REQUIRED if mode is `SIMPLE` or `MUTUAL`.
serverCertificate?: string
// A list of alternate names to verify the subject identity in the
// certificate presented by the client.
subjectAltNames?: [...string]
// An optional list of hex-encoded SHA-256 hashes of the
// authorized client certificates.
verifyCertificateHash?: [...string]
// An optional list of base64-encoded SHA-256 hashes of the SPKIs
// of authorized client certificates.
verifyCertificateSpki?: [...string]
}
}]
}

Some files were not shown because too many files have changed in this diff Show More