Compare commits

...

211 Commits

Author SHA1 Message Date
Jeff McCune
ab5f17c3d2 (#115) Fix goreleaser
Import modules to take the direct dependency and prevent go mod tidy
from modifying go.mod and go.sum which causes goreleaser to fail.
2024-04-10 19:09:30 -07:00
Jeff McCune
a8918c74d4 (#115) Angular spike - fix make frontend
And install frontend deps.
2024-04-09 21:03:26 -07:00
Jeff McCune
ae5738d82d (#115) Angular with SSR
Executed:

    ng new
    ng add @angular/ssr

Name: holos
Style: CSS
SSR and SSG?: No

ssr added using ng add following https://angular.io/guide/prerendering
2024-04-09 20:52:42 -07:00
Jeff McCune
bb99aedffa (#115) Remove frontend
Clean up for ng new in angular spike.
2024-04-09 20:35:43 -07:00
Jeff McCune
d6ee1864c8 (#116) Tilt for development
Add Tilt back from holos server

Note with this patch the ec-creds.yaml file needs to be applied to the
provisioner and an external secret used to sync the image pull creds.

With this patch the dev instance is accessible behind the auth proxy.
pgAdmin also works from the Tilt UI.

https://jeff.holos.dev.k2.ois.run/app/start
2024-04-09 20:26:37 -07:00
Jeff McCune
8a4be66277 (#113) Fix goreleaser try 4
Please check in your pipeline what can be changing the following files:
  M go.sum
2024-04-09 16:48:21 -07:00
Jeff McCune
79ce2f8458 (#113) Fix goreleaser try 3 2024-04-09 16:35:38 -07:00
Jeff McCune
3d4ae44ddd (#113) Fix goreleaser try 2
goreleaser fails with Failure: plugin connect-query: could not find protoc plugin for name connect-query - please make sure protoc-gen-connect-query is installed and present on your $PATH
2024-04-09 16:23:35 -07:00
Jeff McCune
1efb1faa40 (#113) Fix goreleaser
git executable must come before actions checkout
2024-04-09 16:04:42 -07:00
Jeff McCune
bfd6a56397 (#113) Fix actions workflows 2024-04-09 15:57:31 -07:00
Jeff McCune
a788f6d8e8 (#112) Refactor config flag handling
Remove the server.Config struct, not needed.  Remove the app struct and
move the configuration to the main holos.Config.ServerConfig.

Add flags specific to server configuration.

With this patch logging is simplified.  Subcommands have a handle on the
top level holos.Config and can get a fully configured logger from
cfg.Logger() after flag parsing happens.
2024-04-09 11:42:24 -07:00
Jeff McCune
80fa91d74d (#112) Rename wrapper package to errors
The wrapper package name doesn't indicate what it's for.  Rename to
errors and delegate to the standard library.
2024-04-08 20:53:58 -07:00
Jeff McCune
db34562e9a (#112) Get tests passing 2024-04-08 20:53:57 -07:00
Jeff McCune
d6af089ab3 (#112) Rename package core to app
Disambiguate the term `core` which should mean the core domain.  The app
is a supporting domain concerned with logging and configuration
initialization early in the life cycle.
2024-04-08 20:53:57 -07:00
Jeff McCune
b3a70c5911 (#112) Copy holos-server to holos server subcommand
From holos-server commit da35fe966ded2098fe069293ec30864775a6c4f0

Compiles but needs cleanup
2024-04-08 20:53:25 -07:00
Jeff McCune
bf5765c9cb (#110) Update ZITADEL to v2.49.1 from v2.46.0
Attempt to resolve issue where `/oauth/v2/keys` returns `{"keys": []}`
causing id token verification failures.

Closes: #110
2024-04-07 17:20:10 -07:00
Jeff McCune
6c7697648c (#110) Add runbook to take a full database backup
This runbook documents how to write a full database backup to a blank S3
bucket given an existing postgrescluster resource with a live, running
database.

The pgo controller needs to remove and re-create the repo for the backup
to succeed, otherwise it complains about a missing file expected from a
previous backup.
2024-04-07 17:20:07 -07:00
Jeff McCune
04158485c7 (#96) Do not expire ZITADEL signing public key
The public key needs to be configured along with the signing key.
2024-04-05 10:52:36 -07:00
Jeff McCune
cf83c77280 (#96) Do not expire ZITADEL signing private key
Without this patch users encounter an error from istio because it does
not have a valid Jwks from ZITADEL to verify the request when processing
a `RequestAuthentication` policy.

Fixes error `AuthProxy JWKS Error - Jwks doesn't have key to match kid or alg from Jwt`.

Occurs when accessing a protected URL for the first time after tokens have expired.
2024-04-04 15:56:00 -07:00
Jeff McCune
6e545b13dd (#104) Deploy crunchy monitoring stack for ZITADEL
Not exposed via the ingress gateway, but accessible via

    kubectl port-forward svc/crunchy-grafana 3000

Refer to [day two monitoring][1].  This is pretty much a straight copy
of the upstream kustomize configs at [2].

[1]: https://access.crunchydata.com/documentation/postgres-operator/5.5/tutorials/day-two/monitoring
[2]: https://github.com/CrunchyData/postgres-operator-examples/tree/main/kustomize/monitoring
2024-04-04 15:40:07 -07:00
Jeff McCune
bf258a1f41 (#104) Enable monitoring for ZITADEL postgres
This patch enables the monitoring configuration for the ZITADEL postgres
cluster.

Refer to: https://access.crunchydata.com/documentation/postgres-operator/5.5/tutorials/day-two/monitoring

Integrating with:
https://github.com/CrunchyData/postgres-operator-examples/tree/main/kustomize/monitoring
which will become a separate holos component instance.
2024-04-03 22:26:38 -07:00
Jeff McCune
6f06c73d6f (#85) Initial addition of kube-prometheus-stack
Grafana does not yet have the istio sidecar.  Prometheus is accessible
through the auth proxy.  Cert manager is added to the workload clusters
so tls certs can be issued for webhooks, the kube-prom-stack helm chart
uses cert manager for this purpose.

With this patch Grafana is integrated with OIDC and I'm able to log in
as an Administrator.
2024-04-03 21:29:26 -07:00
Jeff McCune
a689c53a9c (#47) v0.62.1 - Projects v1alpha1 milestone complete 2024-04-03 15:32:34 -07:00
Jeff McCune
58cdda1d35 Merge pull request #100 from holos-run/jeff/47-iam-v2
(#47) Remove the prod-iam-zitadel namespace
2024-04-03 15:23:48 -07:00
Jeff McCune
bcb02b5c5c (#47) Remove the prod-iam-zitadel namespace
No longer needed, cluster has moved to prod-iam namespace.
2024-04-03 15:10:30 -07:00
Jeff McCune
0736c7de1a (#47) Bind ALL VirtualServices to the default gateway
Problem:
The VirtualService that catches auth routes for paths, e.g.
`/holos/authproxy/istio-ingress` is bound to the default gateway which
no longer exists because it has no hosts.

Solution:
It's unnecessary and complicated to create a Gateway for every project.
Instead, put all server entries into one `default` gateway and
consolidate the list using CUE.

Result:
It's easier to reason about this system.  There is only one ingress
gateway, `default` and everything gets added to it.  VirtualServices
need only bind to this gateway, which has a hosts entry appropriately
namespaced for the project.
2024-04-03 14:56:40 -07:00
Jeff McCune
28be9f9fbb (#47) Use the project specific Gateway
The login service is unavailable because the wrong gateway is used.
When using projects the VS needs to attach to the correct Gateway.
2024-04-03 12:59:48 -07:00
Jeff McCune
647681de38 (#99) Restore backups from prod-iam namespace
This patch configures the standby cluster to restore backups from the
prod-iam namespace instead of the prod-iam-zitadel namespace.
2024-04-03 12:30:12 -07:00
Jeff McCune
81beb5c539 (#47) Restore ZITADEL from existing backups
Problem:
The ZITADEL database isn't restoring into the prod-iam namespace after
moving from prod-iam-zitadel because no backup exists at the bucket
path.

Solution:
Hard-code the path to the old namespace to restore the database.  We'll
figure out how to move the backups to the new location in a follow up
change.
2024-04-03 11:44:16 -07:00
Jeff McCune
5c1e0a29c8 (#47) Have Ceph depend on secret stores
Another kustomization reconciling too early.
2024-04-03 11:22:15 -07:00
Jeff McCune
01ac5276a9 (#47) Have Gateway depend on secret stores
The `prod-platform-gateway` kustomization is reconciling early:

ExternalSecret/istio-ingress/argocd.ois.run dry-run failed: failed to
get API group resources: unable to retrieve the complete list of server
APIs: external-secrets.io/v1beta1: the server could not find the
requested resource
2024-04-03 11:20:15 -07:00
Jeff McCune
e40594ad8e (#47) Move ZITADEL to prod-iam project namespace
This patch moves ZITADEL from the prod-iam-zitadel namespace to the
projects managed prod-iam namespace, which is the prod environment of
the prod stage of the iam project.
2024-04-03 11:06:55 -07:00
Jeff McCune
bc9c6a622a (#97) Increase ZITADEL pgdata volume to 20Gi
Problem:

```
❯ k exec zitadel-pgha1-4npq-0 -it -- bash
Defaulted container "database" out of: database, replication-cert-copy, pgbackrest, pgbackrest-config, postgres-startup (init), nss-wrapper-init (init)
bash-4.4$ df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay         119G   51G   68G  43% /
tmpfs            64M     0   64M   0% /dev
/dev/rbd3       9.8G  9.8G     0 100% /pgdata
/dev/sda6       119G   51G   68G  43% /tmp
tmpfs            16G   24K   16G   1% /pgconf/tls
tmpfs            16G   24K   16G   1% /etc/database-containerinfo
tmpfs            16G   16K   16G   1% /etc/patroni
tmpfs            16G     0   16G   0% /dev/shm
tmpfs            16G   28K   16G   1% /etc/pgbackrest/conf.d
tmpfs            16G   12K   16G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs           7.9G     0  7.9G   0% /proc/acpi
tmpfs           7.9G     0  7.9G   0% /proc/scsi
tmpfs           7.9G     0  7.9G   0% /sys/firmware
```
2024-04-03 10:09:49 -07:00
Jeff McCune
17f22199b7 (#86) ArgoCD - Disable Dex
Not needed
2024-04-02 15:47:22 -07:00
Jeff McCune
7e93fe4535 (#86) ArgoCD
Using the Helm chart so we can inject the istio sidecar with a kustomize
patch and tweak the configs for OIDC integration.

Login works, istio sidecar is injected.  ArgoCD can only be configured
with one domain unfortunately, it's not accessible at argocd.ois.run,
only argocd.k2.ois.run (or whatever cluster it's installed into).

Ideally it would use the Host header but it does not.

RBAC is not implemented but the User Info endpoint does have group
membership so this shouldn't be a problem to implement.
2024-04-02 15:33:47 -07:00
Jeff McCune
2e98df3572 (#86) ArgoCD in prod-platform project namespace
Deploys using the official release yaml.
2024-04-02 13:34:03 -07:00
Jeff McCune
3b561de413 (#93) Custom AuthPolicy rules for vault
This patch defines a #AuthPolicyRules struct which excludes hosts from
the blanket auth policy and includes them in specialized auth policies.
The purpose is to handle special cases like vault requests which have an
`X-Vault-Token` and `X-Vault-Request` header.

Vault does not use jwts so we cannot verify them in the mesh, have to
pass them along to the backend.

Closes: #93
2024-04-02 12:54:31 -07:00
Jeff McCune
0d0dae8742 (#89) Disable project auth proxies by default
Focus on the ingress gateway auth proxy for now and see how far it gets
us.
2024-04-01 21:48:08 -07:00
Jeff McCune
61b4b5bd17 (#89) Refactor auth proxy callbacks
The ingress gateway auth proxy callback conflicts with the project stage
auth proxy callback for the same backend Host: header value.

This patch disambiguates them by the namespace the auth proxy resides
in.
2024-04-01 21:37:52 -07:00
Jeff McCune
0060740b76 (#82) ingress gateway AuthorizationPolicy
This patch adds a `RequestAuthentication` and `AuthorizationPolicy` rule
to protect all requests flowing through the default ingress gateway.

Consider a browser request for httpbin.k2.example.com representing any
arbitrary host with a valid destination inside the service mesh.  The
default ingress gateway will check if there is already an
x-oidc-id-token header, and if so validate the token is issued by
ZITADEL and the aud value contains the ZITADEL project number.

If the header is not present, the request is forwarded to oauth2-proxy
in the istio-ingress namespace.  This auth proxy is configured to start
the oidc auth flow with a redirect back to /holos/oidc/callback of the
Host: value originally provided in the browser request.

Closes: #82
2024-04-01 20:37:34 -07:00
Jeff McCune
bf8a4af579 (#82) ingressgateway ExtAuthzHttp provider
This patch adds an ingress gateway extauthz provider.  Because ZITADEL
returns all applications associated with a ZITADEL project in the aud
claim, it makes sense to have one ingress auth proxy at the initial
ingress gateway so we can get the ID token in the request header for
backend namespaces to match using `RequestAuthentication` and
`AuthorizationPolicy`.

This change likely makes the additional per-stage auth proxies
unnecessary and over-engineered.  Backend namespaces will have access to
the ID token.
2024-04-01 16:53:11 -07:00
Jeff McCune
dc057fe39d (#89) Add platform project hosts for argocd, grafana, and prometheus
Certificates are issued by the provisioner and synced to the workload
clusters.
2024-04-01 13:09:46 -07:00
Jeff McCune
9877ab131a (#89) Platform Project
This patch manages a platform project to host platform level services
like ArgoCD, Kube Prom Stack, Kiali, etc...
2024-04-01 11:46:02 -07:00
Jeff McCune
13aba64cb7 (#66) Move CUSTOM AuthorizationPolicy to env namespace
It doesn't make sense to link the stage ext authz provider to the
ingress gateway because there can be only one provider per workload.

Link it instead to the backend environment and use the
`security.holos.run/authproxy` label to match the workload.
2024-03-31 18:56:14 -07:00
Jeff McCune
fe9bc2dbfc (#81) Istio 1.21.0 2024-03-31 12:51:56 -07:00
Jeff McCune
c53b682852 (#66) Use x-oidc-id-token instead of authorization header
Problem:
Backend services and web apps expect to place their own credentials into
the Authorization header.  oauth2-proxy writes over the authorization
header creating a conflict.

Solution:
Use the alpha configuration to place the id token into the
x-oidc-id-token header and configure the service mesh to authenticate
requests that have this header in place.

Note: ZITADEL does not use a JWT for an access token, unlike Keycloak
and Dex.  The access token is not compatible with a
RequestAuthentication jwt rule so we must use the id token.
2024-03-31 11:41:23 -07:00
Jeff McCune
3aca6a9e4c (#66) configure auth proxies to set Authorization: Bearer header
Without this patch the istio RequestAuthentication resources fail to
match because the access token from ZITADEL returned by oauth2-proxy in
the x-auth-request-access-token header is not a proper jwt.

The error is:

```
Jwt is not in the form of Header.Payload.Signature with two dots and 3 sections
```

This patch works around the problem by configuring oauth2-proxy to set
the ID token, which is guaranteed to be a proper JWT in the
authorization response headers.

Unfortunately, oauth2-proxy will only place the ID token in the
Authorization header response, which will write over any header set by a
client application.  This is likely to cause problems with single page
apps.

We'll probably need to work around this issue by using the alpha
configuration to set the id token in some out-of-the-way header.  We've
done this before, it'll just take some work to setup the ConfigMap and
translate the config again.
2024-03-30 16:15:27 -07:00
Jeff McCune
40fdfc0317 (#66) Fix auth proxy provider name, stage is always first
dev-holos-authproxy not authproxy-dev-holos
2024-03-30 14:05:50 -07:00
Jeff McCune
25d9415b0a (#66) Fix redis not able to write to /data
Without this patch redis cannot write to the /data directory, which
causes oauth2-proxy to fail with a 500 server error.
2024-03-30 13:40:34 -07:00
Jeff McCune
43c8702398 (#66) Configure an ExtAuthzProxy provider for each project stage
This patch configures an istio envoyExtAuthzHttp provider for each stage
in each project.  An example provider for the dev stage of the holos
project is `authproxy-dev-holos`
2024-03-30 11:28:23 -07:00
Jeff McCune
ce94776dbb (#66) Add ZITADEL project and client ids for iam project
core1 and core2 don't render without these resource identifiers in
place.
2024-03-30 09:18:54 -07:00
Jeff McCune
78ab6cd848 (#66) Match /holos/oidc for all hosts in the project stage
This has the same effect and makes the VirtualService much more
manageable, particularly when calling `kubectl get vs -A`.
2024-03-29 22:50:17 -07:00
Jeff McCune
0a7001f868 (#66) Configure the primary domain for zitadel
This bypasses the account selection screen and automatically redirects
back to the application without user interaction.
2024-03-29 22:44:52 -07:00
Jeff McCune
2db7be671b (#66) Route prefix /holos/oidc to authproxy
This patch configures the service mesh to route all requests with a uri
path prefix of `/holos/oidc` to the auth proxy associated with the
project stage.

Consider a request to https://jeff.holos.dev.k2.ois.run/holos/oidc/sign_in

This request is usually routed to the backend app, but
VirtualService/authproxy in the dev-holos-system namespace matches the
request and routes it to the auth proxy instead.

The auth proxy matches the request Host: header against the whitelist
and cookiedomain setting, which matches the suffix
`.holos.dev.k2.ois.run`.  The auth proxy redirects to the oidc issuer
with a callback url of the request Host for a url of
`https://jeff.holos.dev.k2.ois.run/holos/oidc/callback`.

ZITADEL matches the callback against those registered with the app and
the app client id.  A code is then sent back to the auth proxy.

The auth proxy sets a cookie named `__Secure-authproxy-dev-holos` with a
domain of `.holos.dev.k2.ois.run` from the suffix match of the
`--cookiedomain` flag.

Because this all works using paths, the `auth` prefix domains have been
removed.  They're unnecessary, oauth2-proxy is available for any host
routed to the project stage at path prefix `/holos/oidc`.

Refer to https://oauth2-proxy.github.io/oauth2-proxy/features/endpoints/
for good endpoints for debuggin, replacing `/oauth2` with `/holos/oidc`
2024-03-29 21:56:46 -07:00
Jeff McCune
b51870f7bf (#66) Deploy oauth2-proxy and redis to stage namespaces
This patch deploys oauth2-proxy and redis to the system namespace of
each stage in each project.  The plan is to redirect unauthenticated
requests to the request host at the /holos/oidc/callback endpoint.

This patch removes the --redirect-uri flag, which makes the auth domain
prefix moot, so a future patch should remove those if they really are
unnecessary.

The reason to remove the --redirect-uri flag is to make sure we set the
cookie to a domain suffix of the request Host: header.
2024-03-29 20:56:26 -07:00
Jeff McCune
0227dfa7e5 (#66) Add Gateway entries for oauth2-proxy
This patch adds entries to the project stage Gateway for oauth2-proxy.
Three entries for each stage are added, one for the global endpoint plus
one for each cluster.
2024-03-29 15:30:02 -07:00
Jeff McCune
05b59d9af0 (#66) Refactor project hosts for auth proxy cookies
Without this patch the auth proxy cookie domain is difficult to manage.
This patch refactors the hosts managed for each environment in a project
to better align with security domains and auth proxy session cookies.

The convention is: `<env?>.<host>.<stage?>.<cluster?>.<domain>` where
`host` can be 0..N entries with a default value of `[projectName]`.

env may be omitted for prod or the dev env of the dev stage.  stage may
be omitted for prod.  cluster may be omitted for the global endpoint.

For a project named `holos`:

| Project | Stage | Env  | Cluster | Host                      |
| ------- | ----- | ---  | ------- | ------                    |
| holos   | dev   | jeff | k2      | jeff.holos.dev.k2.ois.run |
| holos   | dev   | jeff | global  | jeff.holos.dev.ois.run    |
| holos   | dev   | -    | k2      | holos.dev.k2.ois.run      |
| holos   | dev   | -    | global  | holos.dev.ois.run         |
| holos   | prod  | -    | k2      | holos.k2.ois.run          |
| holos   | prod  | -    | global  | holos.ois.run             |

Auth proxy:

| Project | Stage | Auth Proxy Host           | Auth Cookie Domain   |
| ------- | ----- | ------                    | ------------------   |
| holos   | dev   | auth.holos.dev.ois.run    | holos.dev.ois.run    |
| holos   | dev   | auth.holos.dev.k1.ois.run | holos.dev.k1.ois.run |
| holos   | dev   | auth.holos.dev.k2.ois.run | holos.dev.k2.ois.run |
| holos   | prod  | auth.holos.ois.run        | holos.ois.run        |
| holos   | prod  | auth.holos.k1.ois.run     | holos.k1.ois.run     |
| holos   | prod  | auth.holos.k2.ois.run     | holos.k2.ois.run     |
2024-03-29 15:30:01 -07:00
Jeff McCune
04f9f3b3a8 Merge pull request #79 from holos-run/nate/makefile_version
Show the holos version in 'make install|build'
2024-03-29 15:04:48 -07:00
Nate McCurdy
b58be8b38c Show the holos version in 'make install|build'
Prior to this, when running the 'install' or 'build' Makefile target,
the version of holos being built was not shown even though the 'build'
target attempted to show the version.

```
.PHONY: build
build: generate ## Build holos executable.
	@echo "building ${BIN_NAME} ${VERSION}"
```

For example:
```
> make install
go generate ./...
building holos
...
```

Holo's version is stored in pkg/version/embedded/{major,minor,patch},
not the `Version` const. So the fix is to change the value of `VERSION`
so that it comes from those embedded files.

Now the version of holos is shown:

```
> make install
go generate ./...
building holos 0.61.1
...
```

This also adds a new Makefile target called `show-version` which shows
the full version string (i.e. the value of `$VERSION`).
2024-03-29 15:01:33 -07:00
Jeff McCune
10493d754a (#66) Add httpbin to each project environment
The goal of this patch is to verify each project environment is wired up
to the ingress Gateway for the project stage.

This is a necessary step to eventually configure the VirtualService and
AuthorizationPolicy to only match on the `/dump/request` path of each
endpoint for troubleshooting.
2024-03-28 21:51:34 -07:00
Jeff McCune
cf28516b8b (#66) Project managed namespaces
This patch uses the existing #ManagedNamespaces definition to create and
manage namespaces on the provisioner and workload clusters so that
SecretStore and eso-creds-refresher resources are managed in the project
environment namespaces and the project stage system namespace.
2024-03-28 15:09:57 -07:00
Jeff McCune
d81e25c4e4 (#66) Project Certificates
Provisioner cluster:

This patch creates a Certificate resource in the provisioner for each
host associated with the project.  By default, one host is created for
each stage with the short hostname set to the project name.

A namespace is also created for each project for eso creds refresher to
manage service accounts for SecretStore resources in the workload
clusters.

Workload cluster:

For each env, plus one system namespace per stage:

 - Namespace per env
 - SecretStore per env
 - ExternalSecret per host in the env

Common names for the holos project, prod stage:

- holos.k1.ois.run
- holos.k2.ois.run
- holos.ois.run

Common names for the holos project, dev stage:

- holos.dev.k1.ois.run
- holos.dev.k2.ois.run
- holos.dev.ois.run
- holos.gary.k1.ois.run
- holos.gary.k2.ois.run
- holos.gary.ois.run
- holos.jeff.k1.ois.run
- holos.jeff.k2.ois.run
- holos.jeff.ois.run
- holos.nate.k1.ois.run
- holos.nate.k2.ois.run
- holos.nate.ois.run

Usage:

    holos render --cluster-name=provisioner \
      ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/provisioner/projects/...
    holos render --cluster-name=k1 \
      ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/workload/projects/...
    holos render --cluster-name=k2 \
      ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/workload/projects/...
2024-03-27 20:54:51 -07:00
Jeff McCune
c4612ff5d2 (#64) Manage one system namespace per project
This patch introduces a new BuildPlan spec.components.resources
collection, which is a map version of
spec.components.kubernetesObjectsList.  The map version is much easier
to work with and produce in CUE than the list version.

The list version should be deprecated and removed prior to public
release.

The projects holos instance renders multiple holos components, each
containing kubernetes api objects defined directly in CUE.

<project>-system is intended for the ext auth proxy providers for all
stages.

<project>-namespaces is intended to create a namespace for each
environment in the project.

The intent is to expand the platform level definition of a project to
include the per-stage auth proxy and per-env role bindings.  Secret
Store and ESO creds refresher resources will also be defined by the
platform level definition of a project.
2024-03-26 12:23:01 -07:00
Jeff McCune
d70acbb47e ignore .vscode 2024-03-22 21:22:06 -07:00
Jeff McCune
3c977d22fe (#71) Final refactoring of example code to use BuildPlan
Need to test it on all the clusters now.  Will follow up with any
necessary fixes.
2024-03-22 16:58:52 -07:00
Jeff McCune
e34db2b583 (#71) Refactor provisioner to produce a BuildPlan 2024-03-22 16:42:57 -07:00
Jeff McCune
71de57ac88 (#71) Refactor optional vault service to BuildPlan 2024-03-22 15:54:52 -07:00
Jeff McCune
c7cc661018 (#71) Refactor Zitadel components for BuildPlan
❯ holos render --cluster-name k2  ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/accounts/iam/zitadel/...
3:04PM INF render.go:43 rendered prod-iam-postgres version=0.60.2 status=ok action=rendered name=prod-iam-postgres
3:04PM INF render.go:43 rendered prod-iam-postgres-certs version=0.60.2 status=ok action=rendered name=prod-iam-postgres-certs
3:04PM INF render.go:43 rendered prod-iam-zitadel version=0.60.2 status=ok action=rendered name=prod-iam-zitadel
2024-03-22 15:04:43 -07:00
Jeff McCune
09f39c02fe (#71) Refactor foundation/cloud/secrets components to BuildPlan 2024-03-22 13:50:34 -07:00
Jeff McCune
23c76a73e0 (#71) Refactor pgo components to BuildPlan 2024-03-22 13:29:38 -07:00
Jeff McCune
1cafe08237 (#71) Refactor prod-metal-ceph to use BuildPlan 2024-03-22 12:44:20 -07:00
Jeff McCune
45b07964ef (#71) Refactor the mesh collection to use BuildPlan
This patch refactors the example reference platform to use the new
BuildPlan API.

```
❯ holos render --cluster-name=k2 /home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/mesh/...
12:19PM INF render.go:43 rendered prod-mesh-cni version=0.60.2 status=ok action=rendered name=prod-mesh-cni
12:19PM INF render.go:43 rendered prod-mesh-gateway version=0.60.2 status=ok action=rendered name=prod-mesh-gateway
12:19PM INF render.go:43 rendered prod-mesh-httpbin version=0.60.2 status=ok action=rendered name=prod-mesh-httpbin
12:19PM INF render.go:43 rendered prod-mesh-ingress version=0.60.2 status=ok action=rendered name=prod-mesh-ingress
12:19PM INF render.go:43 rendered prod-mesh-istiod version=0.60.2 status=ok action=rendered name=prod-mesh-istiod
12:19PM INF render.go:43 rendered prod-mesh-istio-base version=0.60.2 status=ok action=rendered name=prod-mesh-istio-base
```
2024-03-22 12:44:20 -07:00
Jeff McCune
6cc4a57b62 (#72) BuildPlan DisallowUnknownFields
This patch disallows unknown fields from CUE.  The purpose is to fail
early if there is a typo in a nested field name and to speed up
refactoring the reference platform.

With this patch, refactoring the type definition of the Holos/CUE API is
a faster process:

 1. Change api/vX/*.go
 2. make gencue
 3. Render the reference platform
 4. Fix error with unknown fields
 5. Verify rendered output is the same as before

Closes: #72
2024-03-22 12:44:11 -07:00
Jeff McCune
31280acbae (#71) Add HelmChart BuildPlan support
This patch refactors the #HelmChart definition to a BuildPlan.HelmCharts,
which executes a collection of HelmCharts.  The same behavior is
preserved, helm template executes then a kustomize post processor
executes.

```
❯ holos render --cluster-name=k2 ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/... --log-level=debug
9:53PM DBG config.go:150 finalized config from flags version=0.60.1 state=finalized
9:53PM DBG builder.go:108 cue: building instances version=0.60.1
9:53PM DBG builder.go:95 cue: equivalent command: cue export --out yaml -t cluster=k2 ./platforms/reference/clusters/foundation/cloud/github/arc/... version=0.60.1
9:53PM DBG builder.go:100 cue: tags [cluster=k2] version=0.60.1
9:53PM DBG builder.go:122 cue: building instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc
9:53PM DBG builder.go:127 cue: validating instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc
9:53PM DBG builder.go:131 cue: decoding holos build plan version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc
9:53PM DBG builder.go:122 cue: building instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/runner
9:53PM DBG builder.go:127 cue: validating instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/runner
9:53PM DBG builder.go:131 cue: decoding holos build plan version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/runner
9:53PM DBG result.go:61 ExternalSecret/controller-manager version=0.60.1 kind=ExternalSecret name=controller-manager
9:53PM DBG builder.go:122 cue: building instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/system
9:53PM DBG builder.go:127 cue: validating instance version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/system
9:53PM DBG builder.go:131 cue: decoding holos build plan version=0.60.1 dir=/home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/system
9:53PM DBG helm.go:95 helm: wrote values version=0.60.1 chart=oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller path=/tmp/holos1163326896/values.yaml bytes=653
9:53PM DBG run.go:40 running: helm version=0.60.1 name=helm args="[template --no-hooks --include-crds --values /tmp/holos1163326896/values.yaml --namespace arc-system --kubeconfig /dev/null --version 0.8.3 gha-rs-controller /home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/github/arc/system/vendor/gha-runner-scale-set-controller]"
9:53PM DBG remove.go:15 tmp: removed version=0.60.1 path=/tmp/holos1163326896
9:53PM DBG result.go:95 wrote: /tmp/holos.kustomize3569816247/resources.yaml version=0.60.1 op=write path=/tmp/holos.kustomize3569816247/resources.yaml bytes=2019229
9:53PM DBG result.go:108 wrote: /tmp/holos.kustomize3569816247/kustomization.yaml version=0.60.1 op=write path=/tmp/holos.kustomize3569816247/kustomization.yaml bytes=94
9:53PM DBG run.go:40 running: kubectl version=0.60.1 name=kubectl args="[kustomize /tmp/holos.kustomize3569816247]"
9:53PM DBG remove.go:15 tmp: removed version=0.60.1 path=/tmp/holos.kustomize3569816247
9:53PM DBG result.go:135 out: wrote deploy/clusters/k2/components/prod-github-arc-runner/prod-github-arc-runner.gen.yaml version=0.60.1 action=write path=deploy/clusters/k2/components/prod-github-arc-runner/prod-github-arc-runner.gen.yaml status=ok
9:53PM DBG result.go:135 out: wrote deploy/clusters/k2/holos/components/prod-github-arc-runner-kustomization.gen.yaml version=0.60.1 action=write path=deploy/clusters/k2/holos/components/prod-github-arc-runner-kustomization.gen.yaml status=ok
9:53PM INF render.go:43 rendered prod-github-arc-runner version=0.60.1 status=ok action=rendered name=prod-github-arc-runner
9:53PM DBG result.go:135 out: wrote deploy/clusters/k2/components/prod-github-arc-system/prod-github-arc-system.gen.yaml version=0.60.1 action=write path=deploy/clusters/k2/components/prod-github-arc-system/prod-github-arc-system.gen.yaml status=ok
9:53PM DBG result.go:135 out: wrote deploy/clusters/k2/holos/components/prod-github-arc-system-kustomization.gen.yaml version=0.60.1 action=write path=deploy/clusters/k2/holos/components/prod-github-arc-system-kustomization.gen.yaml status=ok
9:53PM INF render.go:43 rendered prod-github-arc-system version=0.60.1 status=ok action=rendered name=prod-github-arc-system
```
2024-03-22 10:14:04 -07:00
Jeff McCune
6f0928b12c (#71) Add go BuildPlan type as the CUE<->Holos API
This patch establishes the BuildPlan struct as the single API contract
between CUE and Holos.  A BuildPlan spec contains a list of each of the
support holos component types.

The purpose of this data structure is to support the use case of one CUE
instance generating 1 build plan that contains 0..N of each type of
holos component.

The need for multiple components per one CUE instance is to support the
generation of a collection of N~4 flux kustomization resources per
project and P~6 projects built from one CUE instance.

Tested with:

    holos render --cluster-name=k2 ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/foundation/cloud/init/namespaces/...

Common labels are removed because they're too tightly coupled to the
model of one component per one cue instance.
2024-03-21 16:13:36 -07:00
Jeff McCune
c6e9250d60 (#69) Refactor clean up go types
Separate out the Kustomization and Kustomize types commonly used in
holos components.  Embed HolosComponent into Result.
2024-03-21 08:57:02 -07:00
Jeff McCune
104bda459f (#69) Go Types for CUE/Holos API contract
This patch refactors the go structs used to decode cue output for
processing by the holos cli.  For context, the purpose of the structs
are to inform holos how the data from cue should be modeled and
processed as a rendering pipeline that provides rendered yaml to
configure kubernetes api objects.

The structs share common fields in the form of the HolosComponent
embedded struct.  The three main holos component kinds today are:

 1. KubernetesObjects - CUE outputs a nested map where each value is a
    single rendered api object (resource).
 2. HelmChart - CUE outputs the chart name and values.  Holos calls helm
    template to render the chart.  Additional api objects may be
    overlaid into the rendered output.  Kustomize may also optionally be
    called at the end of the render pipeline.
 3. KustomizeBuild - CUE outputs data to construct a kustomize
    kustomization build.  The holos component contains raw yaml files to
    use as kustomization resources.  CUE optionally defines additional
    patches, common labels, etc.

With the Go structs, cue may directly import the definitions to more
easily keep the CUE definitions in sync with what the holos cli expects
to receive.

The holos component types may be imported into cue using:

    cue get go github.com/holos-run/holos/api/v1alpha1/...
2024-03-20 17:21:10 -07:00
Jeff McCune
bd2effa183 (#61) Improve ks prod-iam-zitadel robustness with flux health checks
Without this patch ks/prod-iam-zitadel often gets blocked waiting for
jobs that will never complete.  In addition, flux should not manage the
zitadel-test-connection Pod which is an unnecessary artifact of the
upstream helm chart.

We'd disable helm hooks, but they're necessary to create the init and
setup jobs.

This patch also changes the default behavior of Kustomizations from
wait: true to wait: false.  Waiting is expensive for the api server and
slows down the reconciliation process considerably.

Component authors should use ks.spec.healthChecks to target specific
important resources to watch and wait for.
2024-03-15 15:56:43 -07:00
Jeff McCune
562412fbe7 (#57) Run gha-rs scale set only on the primary cluster
This patch fixes the problem of the actions runner scale set listener
pod failing every 3 seconds.  See
https://github.com/actions/actions-runner-controller/issues/3351

The solution is not ideal, if the primary cluster is down workflows will
not execute.  The primary cluster shouldn't go down though so this is
the trade off.  Lower log spam and resource usage by eliminating the
failing pods on other clusters for lower availability if the primary
cluster is not available.

We could let the pods loop and if the primary is unavailable another
would quickly pick up the role, but it doesn't seem worth it.
2024-03-15 13:13:25 -07:00
Jeff McCune
fd6fbe5598 (#57) Allow gha-rs scale set to fail on all but one clusters
The effect of this patch is limited to refreshing credentials only for
namespaces that exist in the local cluster.  There is structure in place
in the CUE code to allow for namespaces bound to specific clusters, but
this is used only by the optional Vault component.

This patch was an attempt to work around
https://github.com/actions/actions-runner-controller/issues/3351 by
deploying the runner scale sets into unique namespaces.

This effort was a waste of time, only one listener pod successfully
registered for a given scale set name / group combination.

Because we have only one group named Default we can only have one
listener pod globally for a given scale set name.

Because we want our workflows to execute regardless of the availability
of a single cluster, we're going to let this fail for now.  The pod
retries every 3 seconds.  When a cluster is destroyed, another cluster
will quickly register.

A follow up patch will look to expand this retry behavior.
2024-03-15 12:53:16 -07:00
Jeff McCune
67472e1e1c (#60) Disable flux reconciliation of deployment/zitadel on standby clusters 2024-03-14 21:58:32 -07:00
Jeff McCune
d64c3e8c66 (#58) Zitadel Failover RunBook 2024-03-14 15:25:38 -07:00
Jeff McCune
f344f97374 (#58) Restore last zitadel database backup
When the cluster is provisioned, restore the most recent backup instead
of a fixed point in time.
2024-03-14 11:40:17 -07:00
Jeff McCune
770088b912 (#53) Clean up nested if statements with && 2024-03-13 10:35:20 -07:00
Jeff McCune
cb9b39c3ca (#53) Add Vault as an optional service on the core clusters
This patch migrates the vault component from [holos-infra][1] to a cue
based component.  Vault is optional in the reference platform, so this
patch also defines an `#OptionalServices` struct to conditionally manage
a service across multiple clusters in the platform.

The primary use case for optional services is managing a namespace to
provision and provide secrets across clusters.

[1]: https://github.com/holos-run/holos-infra/tree/v0.5.0/components/core/core/vault
2024-03-12 17:18:38 -07:00
Jeff McCune
0f34b20546 (#54) Disable helm hooks when rendering components
Pods are unnecessarily created when deploying helm based holos
components and often fail.  Prevent these test pods by disabling helm
hooks with the `--no-hooks` flag.

Closes: #54
2024-03-12 14:14:20 -07:00
Jeff McCune
0d7bbbb659 (#48) Disable pg spec.dataSource for standby cluster
Problem:
The standby cluster on k2 fails to start.  A pgbackrest pod first
restores the database from S3, then the pgha nodes try to replay the WAL
as part of the standby initialization process.  This fails because the
PGDATA directory is not empty.

Solution:
Specify the spec.dataSource field only when the cluster is configured as
a primary cluster.

Result:
Non-primary clusters are standby, they skip the pgbackrest job to
restore from S3 and move straight to patroni replaying the WAL from S3
as part of the pgha pods.

One of the two pgha pods becomes the "standby leader" and restores the
WAL from S3.  The other is a cascading standby and then restores the
same WAL from the standby leader.

After 8 minutes both pods are ready.

```
❯ k get pods
NAME                               READY   STATUS    RESTARTS   AGE
zitadel-pgbouncer-d9f8cffc-j469g   2/2     Running   0          11m
zitadel-pgbouncer-d9f8cffc-xq29g   2/2     Running   0          11m
zitadel-pgha1-27w7-0               4/4     Running   0          11m
zitadel-pgha1-c5qj-0               4/4     Running   0          11m
zitadel-repo-host-0                2/2     Running   0          11m
```
2024-03-11 17:56:47 -07:00
Jeff McCune
3f3e36bbe9 (#48) Split workload into foundation and accounts
Problem:
The k3 and k4 clusters are getting the Zitadel components which are
really only intended for the core cluster pair.

Solution:
Split the workload subtree into two, named foundation and accounts.  The
core cluster pair gets foundation+accounts while the kX clusters get
just the foundation subtree.

Result:
prod-zitadel-iam is no longer managed on k3 and k4
2024-03-11 15:20:35 -07:00
Jeff McCune
9f41478d33 (#48) Restore from Monday morning after Gary and Nate registered
Set the restore point to time="2024-03-11T17:08:58Z" level=info
msg="crunchy-pgbackrest ends" which is just after Gary and Nate
registered and were granted the cluster-admin role.
2024-03-11 10:18:45 -07:00
Jeff McCune
b86fee04fc (#48) v0.55.4 to rebuild k3, k4, k5 2024-03-11 08:48:07 -07:00
Jeff McCune
c78da6949f Merge pull request #51 from holos-run/jeff/48-zitadel-backups
(#48) Custom PGO Certs for Zitadel
2024-03-10 23:08:29 -07:00
Jeff McCune
7b215bb8f1 (#48) Custom PGO Certs for Zitadel
The [Streaming Standby][standby] architecture requires custom tls certs
for two clusters in two regions to connect to each other.

This patch manages the custom certs following the configuration
described in the article [Using Cert Manager to Deploy TLS for Postgres
on Kubernetes][article].

NOTE: One thing not mentioned anywhere in the crunchy documentation is
how custom tls certs work with pgbouncer.  The pgbouncer service uses a
tls certificate issued by the pgo root cert, not by the custom
certificate authority.

For this reason, we use kustomize to patch the zitadel Deployment and
the zitadel-init and zitadel-setup Jobs.  The patch projects the ca
bundle from the `zitadel-pgbouncer` secret into the zitadel pods at
/pgbouncer/ca.crt

[standby]: https://access.crunchydata.com/documentation/postgres-operator/latest/architecture/disaster-recovery#streaming-standby-with-an-external-repo
[article]: https://www.crunchydata.com/blog/using-cert-manager-to-deploy-tls-for-postgres-on-kubernetes
2024-03-10 22:54:06 -07:00
Jeff McCune
78cec76a96 (#48) Restore ZITADEL from point in time full backup
A full backup was taken using:

```
kubectl annotate postgrescluster zitadel postgres-operator.crunchydata.com/pgbackrest-backup="$(date)"
```

And completed with:

```
❯ k logs -f zitadel-backup-5r6v-v5jnm
time="2024-03-10T21:52:15Z" level=info msg="crunchy-pgbackrest starts"
time="2024-03-10T21:52:15Z" level=info msg="debug flag set to false"
time="2024-03-10T21:52:15Z" level=info msg="backrest backup command requested"
time="2024-03-10T21:52:15Z" level=info msg="command to execute is [pgbackrest backup --stanza=db --repo=2 --type=full]"
time="2024-03-10T21:55:18Z" level=info msg="crunchy-pgbackrest ends"
```

This patch verifies the point in time backup is robust in the face of
the following operations:

1. pg cluster zitadel was deleted (whole namespace emptied)
2. pg cluster zitadel was re-created _without_ a `dataSource`
3. pgo initailized a new database and backed up the blank database to
   S3.
4. pg cluster zitadel was deleted again.
5. pg cluster zitadel was re-created with `dataSource` `options: ["--type=time", "--target=\"2024-03-10 21:56:00+00\""]` (Just after the full backup completed)
6. Restore completed successfully.
7. Applied the holos zitadel component.
8. Zitadel came up successfully and user login worked as expected.

- [x] Perform an in place [restore][restore] from [s3][bucket].
- [x] Set repo1-retention-full to clear warning

[restore]: https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/backups-disaster-recovery/disaster-recovery#restore-properties
[bucket]: https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/backups-disaster-recovery/disaster-recovery#cloud-based-data-source
2024-03-10 17:42:54 -07:00
Jeff McCune
0e98ad2ecb (#48) Zitadel Backups
This patch configures backups suitable to support the [Streaming Standby
with an External Repo][0] architecture.

- [x] PGO [Multiple Backup Repositories][1] to k8s pv and s3.
- [x] [Encryption][2] of backups to S3.
- [x] [Remove SUPERUSER][3] role from zitadel-admin pg user to work with pgbouncer.  Resolves zitadel-init job failure.
- [x] Take a [Manual Backup][5]

[0]: https://access.crunchydata.com/documentation/postgres-operator/latest/architecture/disaster-recovery#streaming-standby-with-an-external-repo
[1]: https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/backups-disaster-recovery/backups#set-up-multiple-backup-repositories
[2]: https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/backups-disaster-recovery/backups#encryption
[3]: https://github.com/CrunchyData/postgres-operator/issues/3095#issuecomment-1904712211
[4]: https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/backups-disaster-recovery/disaster-recovery#streaming-standby-with-an-external-repo
[5]: https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/backups-disaster-recovery/backup-management#taking-a-one-off-backup
2024-03-10 16:38:56 -07:00
Jeff McCune
30bb3f183a (#50) Describe type as strings to match others 2024-03-10 11:29:19 -07:00
Jeff McCune
1369338f3c (#50) Add -n shorthand for --namespace for secrets
It's annoying holos get secret -n foo doesn't work like kubectl get
secret -n foo works.

Closes: #50
2024-03-10 10:45:49 -07:00
Jeff McCune
ac03f64724 (#45) Configure ZITADEL to use pgbouncer 2024-03-09 09:44:33 -08:00
Jeff McCune
bea4468972 (#42) Remove cert manager db ca components
Simpler to let postgres manage the certs.  TLS is in verify-full mode
with the pgo configured certs.
2024-03-08 21:34:26 -08:00
Jeff McCune
224adffa15 (#42) Add holos components for zitadel with postgres
To establish the canonical https://login.ois.run identity issuer on the
core cluster pair.

Custom resources for PGO have been imported with:

    timoni mod vendor crds -f deploy/clusters/core2/components/prod-pgo-crds/prod-pgo-crds.gen.yaml

Note, the zitadel tls connection took some considerable effort to get
working.  We intentionally use pgo issued certs to reduce the toil of
managing certs issued by cert manager.

The default tls configuration of pgo is pretty good with verify full
enabled.
2024-03-08 21:29:25 -08:00
Jeff McCune
b4d34ffdbc (#42) Fix incorrect ceph pool for core2 cluster
The core2 cluster cannot provision pvcs because it's using the k8s-dev
pool when it has credentials valid only for the k8s-prod pool.

This patch adds an entry to the platform cluster map to configure the
pool for each cluster, with a default of k8s-dev.
2024-03-08 13:14:27 -08:00
Jeff McCune
a85db9cf5e (#42) Add KustomizeBuild holos component type to install pgo
PGO uses plain yaml and kustomize as the recommended installation
method.  Holos supports upstream by adding a new PlainFiles component
kind, which simply copies files into place and lets kustomize handle the
generation of the api objects.

Cue is responsible for very little in this kind of component, basically
allowing overlay resources if needed and deferring everything else to
the holos cli.

The holos cli in turn is responsible for executing kubectl kustomize
build on the input directory to produce the rendered output, then writes
the rendered output into place.
2024-03-08 11:27:42 -08:00
Jeff McCune
990c82432c (#40) Fix go releaser with standard arc runners
Standard arc runner image is missing gpg and git.
2024-03-07 22:59:15 -08:00
Jeff McCune
e3673b594c Merge pull request #41 from holos-run/jeff/40-actions-runners
(#40) Actions Runner Controller (Runner Scale Sets)
2024-03-07 22:43:16 -08:00
Jeff McCune
f8cf278a24 (#40) bump to v0.54.0 2024-03-07 22:37:51 -08:00
Jeff McCune
b0bc596a49 (#40) Update workflow to run on arc runner set
Matches the value of the github/arc/runner component helm release, which
is the installation name.
2024-03-07 22:37:51 -08:00
Jeff McCune
4501ceec05 (#40) Use baseline security context for GitHub arc
Without this patch the arc controller fails to create a listener.  The
template for the listener doesn't appear to be configurable from the
chart.

Could patch the listener pod template with kustomize, do this as a
follow up feature.

With this patch we get the expected two pods in the runner system
namespace:

```
❯ k get pods
NAME                                 READY   STATUS    RESTARTS   AGE
gha-rs-7db9c9f7-listener             1/1     Running   0          43s
gha-rs-controller-56bb9c77d9-6tjch   1/1     Running   0          8s
```
2024-03-07 22:37:50 -08:00
Jeff McCune
4183fdfd42 (#40) Note the helm release name is the installation name
Which is the value of the `runs-on` field in workflows.
2024-03-07 22:37:50 -08:00
Jeff McCune
2595793019 (#40) Do not force the namespace with kustomize
To avoid confining the custom resource definitions to a namespace.
2024-03-07 22:37:50 -08:00
Jeff McCune
aa3d1914b1 (#40) Manage the actions runner scale sets 2024-03-07 22:37:49 -08:00
Jeff McCune
679ddbb6bf (#40) Use Restricted pod security for arc runners
Might as well put the restriction in place before deploying the runners
to see what breaks.
2024-03-07 22:37:49 -08:00
Jeff McCune
b1d7d07a04 (#40) Add field for helm chart release name
The resource names for the arc controller are too long:

❯ k get pods -n arc-systems
NAME                                                              READY   STATUS    RESTARTS   AGE
gha-runner-scale-set-controller-gha-rs-controller-6bdf45bd6jx5n   1/1     Running   0          59m

Solve the problem by allowing components to set the release name to
`gha-rs-controller` which requires an additional field from the cue code
to differentiate from the chart name.
2024-03-07 20:40:31 -08:00
Jeff McCune
5f58263232 (#40) Create arc namespaces
Named after the upstream install guide, though arc-systems makes me
twitch for arc-system.
2024-03-07 20:37:35 -08:00
Jeff McCune
b6bdd072f7 (#40) Include crds when running helm template
Might need to make this a configurable option, but for now just always
do it.
2024-03-07 20:37:35 -08:00
Jeff McCune
509f2141ac (#40) Actions Runner Controller
This patch adds support for helm oci images which are used by the
gha-runner-scale-set-controller.

For example, arc is installed normally with:

```
NAMESPACE="arc-systems"
helm install arc \
    --namespace "${NAMESPACE}" \
    --create-namespace \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
```

This patch caches the oci image in the same way as the repository based
method.

Refer to: https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners-with-actions-runner-controller/quickstart-for-actions-runner-controller
2024-03-07 20:37:35 -08:00
Jeff McCune
4c2bc34d58 (#32) SecretStore Component
Separate the SecretStore resources from the namespaces component because
it creates a deadlock.  The secretstore crds don't get applied until the
eso component is managed.

The namespaces component should have nothing but core api objects, no
custom resources.
2024-03-07 16:01:22 -08:00
Jeff McCune
d831070f53 Trim trailing newlines from files when creating secrets
Without this patch, the pattern of echoing data (without -n) or editing
files in a directory to represent the keys of a secret results in a
trailing newline in the kubernetes Secret.

This patch trims off the trailing newline by default, with the option to
preserve it with the --trim-trailing-newlines=false flag.
2024-03-06 11:21:32 -08:00
Jeff McCune
340715f76c (#36) Provide certs to Cockroach DB and Zitadel with ExternalSecrets
This patch switches CockroachDB to use certs provided by ExternalSecrets
instead of managing Certificate resources in-cluster from the upstream
helm chart.

This paves the way for multi-cluster replication by moving certificates
outside of the lifecycle of the workload cluster cockroach db operates
within.

Closes: #36
2024-03-06 10:38:47 -08:00
Jeff McCune
64ffacfc7a (#36) Add Cockroach Issuer for Zitadel to provisioner cluster
Issuing mtls certs for cockroach db moves to the provisioner cluster so
we can more easily support cross cluster replication in the future.
crdb certs will be synced same as public tls certs, using ExternalSecret
resources.
2024-03-06 09:36:20 -08:00
Nate McCurdy
54acea42cb Merge pull request #37 from holos-run/nate/preflight
Add 'holos preflight' command, check for GitHub CLI
2024-03-06 09:32:54 -08:00
Nate McCurdy
5ef8e75194 Fix Actions warning during Lint by updating golangci-lint-action
Warning:
> Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: golangci/golangci-lint-action@v3. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/.
2024-03-05 17:42:30 -08:00
Nate McCurdy
cb2b5c0f49 Add the 'preflight' subcommand; check for GitHub access
This adds a new holos subcommand: preflight

Initially, this just checks that the GitHub CLI is installed and
authenticated.

The preflight command will be used to validate that the user has the
neccessary CLI tools, access, and authorization to start using Holos and
setup a Holos cluster.
2024-03-05 17:40:08 -08:00
Jeff McCune
fd5a2fdbc1 (#36) Sync certs as ExternalSecrets from workload clusters
This patch replaces the httpbin and login cert on the workload clusters
with an ExternalSecret to sync the tls cert from the provisioner
cluster.
2024-03-05 17:05:10 -08:00
Jeff McCune
eb3e272612 (#36) Dynamically generate cluster certs from Platform spec
Each cluster should be more or less identical, configure certs from the
dynamic list of platform clusters.
2024-03-05 16:44:35 -08:00
Nate McCurdy
9f2a51bde8 Move the RunCmd function to the util package
More than one Holos package needs to execute commands, so pull out the
runCmd from builder and move it to the util package.

This commits adds the following to the util package:
* util.RunCmd func
* util.runResult struct
2024-03-05 15:12:14 -08:00
Jeff McCune
2b3b5a4887 (#36) Issue login and httpbin certs
This patch uses cert manager in the provisioner cluster to provision tls
certs for https://login.example.com and https://httpbin.k2.example.com

The certs are not yet synced to the clusters.  Next step is to replace
the Certificate resources with ExternalSecret resources, then remove
cert manager from the workload clusters.
2024-03-05 14:27:37 -08:00
Jeff McCune
7426e8f867 (#36) Move cert-manager to the provisioner cluster
This patch moves certificate management to the provisioner cluster to
centralize all secrets into the highly secured cluster.  This change
also simplifies the architecture in a number of ways:

1. Certificate lives are now completely independent of cluster
   lifecycle.
2. Remove the need for bi-directional sync to save cert secrets.
3. Workload clusters no longer need access to DNS.
2024-03-05 12:51:58 -08:00
Jeff McCune
cf0c455aa2 (#34) Add test for print secret data 2024-03-05 11:14:37 -08:00
Jeff McCune
752a3f912d (#34) Remove debug info logs 2024-03-05 11:05:51 -08:00
Jeff McCune
7d5852d675 (#34) Print secret data as json
Closes: #34
2024-03-05 11:03:47 -08:00
Jeff McCune
66b4ca0e6c (#31) Fix helm missing in actions workflow
Causing test failures that should pass.
2024-03-05 10:11:43 -08:00
Jeff McCune
b3f682453d (#31) Inject istio sidecar into Deployment zitadel using Kustomize
Multiple holos components rely on kustomize to modify the output of the
upstream helm chart, for example patching a Deployment to inject the
istio sidecar.

The new holos cue based component system did not support running
kustomize after helm template.  This patch adds the kustomize execution
if two fields are defined in the helm chart kind of cue output.

The API spec is pretty loose in this patch but I'm proceeding for
expedience and to inform the final API with more use cases as more
components are migrated to cue.
2024-03-05 09:56:39 -08:00
Jeff McCune
0c3181ae05 (#31) Add VirtualService for Zitadel
Also import the Kustomize types using:

    cue get go sigs.k8s.io/kustomize/api/types/...
2024-03-04 17:18:46 -08:00
Jeff McCune
18cbff0c13 (#31) Add tls cert for zitadel to connect to cockroach db
Cockroach DB uses tls certs for client authentication.  Issue one for
Zitadel.

With this patch Zitadel starts up bit is not yet exposted with a
VirtualService.

Refer to https://zitadel.com/docs/self-hosting/manage/configure
2024-03-04 14:46:49 -08:00
Jeff McCune
b4fca0929c (#31) ExternalSecret for zitadel-masterkey 2024-03-04 14:31:27 -08:00
Jeff McCune
911d65bdc6 (#31) Setup login.ois.run with basic istio default Gateway
The istio default Gateway is the basis for what will become a dynamic
set of server entries specified from cue project data integrated with
extauthz.

For now we simply need to get the identity provider up and running as
the first step toward identity and access management.
2024-03-04 13:59:17 -08:00
Jeff McCune
2a5eccf0c1 (#33) Helm stderr logging
Log error messages from helm when building and rendering holos
components.

Closes: #33
2024-03-04 13:16:51 -08:00
Jeff McCune
9db4873205 (#31) Add Cockroach DB for Zitadel
Following https://github.com/zitadel/zitadel-charts/blob/main/examples/4-cockroach-secure/README.md
2024-03-04 10:31:39 -08:00
Jeff McCune
f90e83e142 (#30) Add httpbin Gateway and VirtualService
There isn't a default Gateway yet, so use a specific `httpbin` gateway
to test istio instead.
2024-03-02 21:12:03 -08:00
Jeff McCune
bdd2964edb (#30) Add httpbin Service for ns istio-ingress 2024-03-02 20:39:55 -08:00
Jeff McCune
56375b82d8 (#30) Fix httpbin Deployment selector match labels
Without this patch the deployment fails with:

```
Deployment/istio-ingress/httpbin dry-run failed, reason: Invalid:
Deployment.apps "httpbin" is invalid: spec.template.metadata.labels:
Invalid value:
map[string]string{"app.kubernetes.io/component":"httpbin",
"app.kubernetes.io/instance":"prod-mesh-httpbin",
"app.kubernetes.io/name":"mesh", "app .kubernetes.io/part-of":"prod",
"holos.run/component.name":"httpbin", "holos.run/project.name":"mesh",
"holos.run/stage.name":"prod", "sidecar.istio.io/inject":"true"}:
`selector` does not match template `labels`
```
2024-03-02 20:23:23 -08:00
Jeff McCune
dc27489249 (#30) Add httpbin Deployment in istio-ingress namespace
This patch gets the Deployment running with a restricted seccomp
profile.
2024-03-02 20:17:16 -08:00
Jeff McCune
7d8a618e25 (#30) Add httpbin Certificate to verify the mesh
Also fix certmanager which was not installing role bindings correctly
because the flux kustomization was writing over the metadata namespace
field.
2024-03-02 17:16:42 -08:00
Jeff McCune
646f6fcdb0 (#30) Add https redirect overlay resources
This patch migrates the https redirect and the
istio-ingressgateway-loopback Service from
`holos-infra/components/core/istio/ingress/templates/deployment`
2024-03-02 15:01:58 -08:00
Jeff McCune
4ce39db745 (#30) Enforce restricted pod security profile on istio-ingress namespace
This patch enforces the restricted pod security profile on the istio
ingress namespace. The istio cni to move the traffic redirection from
the init container to a cni daemon set pod.

Refer to:

 - https://istio.io/latest/docs/setup/additional-setup/pod-security-admission/
 - https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted
2024-03-02 11:16:55 -08:00
Jeff McCune
eba58d1639 (#30) Add ingress component and istio-ingressgateway Deployment
Migrated from holos-infra/components/core/istio/ingress
2024-03-02 10:22:21 -08:00
Jeff McCune
765832d90d (#30) Trim istiod 2024-03-01 16:27:49 -08:00
Jeff McCune
d1163d689a (#30) Add istiod istio controller and meshconfig
This patch adds the standard istiod controller, which depends on
istio-base.

The holos reference platform heavily customizes the meshconfig, so the
upstream istio ConfigMap is disabled in the helm chart values.  The mesh
config is generated from cue data defined in the controller holos
component.

Note: This patch adds a static configuration for the istio meshconfig in
the meshconfig.cue file.  The extauthz providers are a core piece of
functionality in the holos reference platform and a key motivation of
moving to CUE from Helm is the need to dynamically generate the
meshconfig from a platform scoped set of projects and services across
multiple clusters.

For expedience this dynamic generation is not part of this patch but is
expected to replace the static meshconfig once the cluster is more fully
configured with the new cue based holos command line interface.
2024-03-01 16:13:19 -08:00
Jeff McCune
63009ba419 (#30) Fix cue formatting 2024-03-01 10:35:32 -08:00
Jeff McCune
9c42cf9109 (#30) Import istio crds into cue definitions
❯ timoni mod vendor crds -f ~/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-mesh-istio-base/prod-mesh-istio-base.gen.yaml
10:30AM INF schemas vendored: extensions.istio.io/wasmplugin/v1alpha1
10:30AM INF schemas vendored: install.istio.io/istiooperator/v1alpha1
10:30AM INF schemas vendored: networking.istio.io/destinationrule/v1alpha3
10:30AM INF schemas vendored: networking.istio.io/destinationrule/v1beta1
10:30AM INF schemas vendored: networking.istio.io/envoyfilter/v1alpha3
10:30AM INF schemas vendored: networking.istio.io/gateway/v1alpha3
10:30AM INF schemas vendored: networking.istio.io/gateway/v1beta1
10:30AM INF schemas vendored: networking.istio.io/proxyconfig/v1beta1
10:30AM INF schemas vendored: networking.istio.io/serviceentry/v1alpha3
10:30AM INF schemas vendored: networking.istio.io/serviceentry/v1beta1
10:30AM INF schemas vendored: networking.istio.io/sidecar/v1alpha3
10:30AM INF schemas vendored: networking.istio.io/sidecar/v1beta1
10:30AM INF schemas vendored: networking.istio.io/virtualservice/v1alpha3
10:30AM INF schemas vendored: networking.istio.io/virtualservice/v1beta1
10:30AM INF schemas vendored: networking.istio.io/workloadentry/v1alpha3
10:30AM INF schemas vendored: networking.istio.io/workloadentry/v1beta1
10:30AM INF schemas vendored: networking.istio.io/workloadgroup/v1alpha3
10:30AM INF schemas vendored: networking.istio.io/workloadgroup/v1beta1
10:30AM INF schemas vendored: security.istio.io/authorizationpolicy/v1
10:30AM INF schemas vendored: security.istio.io/authorizationpolicy/v1beta1
10:30AM INF schemas vendored: security.istio.io/peerauthentication/v1beta1
10:30AM INF schemas vendored: security.istio.io/requestauthentication/v1
10:30AM INF schemas vendored: security.istio.io/requestauthentication/v1beta1
10:30AM INF schemas vendored: telemetry.istio.io/telemetry/v1alpha1
2024-03-01 10:31:52 -08:00
Jeff McCune
3fce5188a2 (#30) Add holos cue instance prod-mesh-istio-base
This patch installs the istio base helm chart from upstream which
includes the custom resource definitions.
2024-03-01 10:28:54 -08:00
Jeff McCune
fde88ad5eb (#30) Add #DependsOn struct to unify dependencies
Using a list to merge dependencies through the tree from root to leaf is
challenging.  This patch uses a #DependsOn struct instead then builds
the list of dependencies for flux from the struct field values.
2024-03-01 10:13:55 -08:00
Jeff McCune
7a8d30f833 (#30) Mesh istio-system istio-ingress namespaces
Need to be in place with privileged pod security policies.
2024-03-01 09:35:57 -08:00
Jeff McCune
8987442b91 (#27) Add cert-manager ExternalSecret cloudflare-api-token-secret
This enables the dns01 letsencrypt acme solver and is heavily used in
the reference platform.

Secret migrated from Vault using:

```bash
vault kv get -format=json -field data kv/k8s/ns/cert-manager/cloudflare-api-token-secret \
  | holos create secret --namespace cert-manager cloudflare-api-token-secret --data-stdin --append-hash=false
```
2024-03-01 08:44:06 -08:00
Jeff McCune
a6af3a46cf (#27) Manage SecretStore with platform namespaces
It makes sense to manage the SecretStore along with the Namespace in the
platform namespaces holos component.  Otherwise, the first component
that needs an ExternalSecret also needs to manage a SecretStore, which
creates an artificial dependency for subesequent components that also
need a SecretStore in the same namespace.

Best to just have all components depend on the namespaces component.
2024-03-01 08:05:00 -08:00
Jeff McCune
71d545a883 (#27) Add cert-manager LetsEncrypt issuers
This patch partially adds the Let's Encrypt issuers.  The platform data
expands to take a contact email and a cloudflare login email.

The external secret needs to be added next.
2024-02-29 21:40:55 -08:00
Jeff McCune
044d3082d9 (#27) Add cert-manager custom resource definitions
Without this patch the cert-manager component is missing the custom
resource definitions.

This patch adds them using the helm installCRDs value.
2024-02-29 20:46:42 -08:00
Jeff McCune
c2d5c4ad36 (#27) Add cert-manager to the mesh collection
Straight-forward helm install with no customization.

This patch also adds a "Skip" output kind which allows intermediate cue
files in the tree to signal holos to skip over the instance.  This
enables constraints to be added at intermediate layers without build
errors.
2024-02-29 16:50:27 -08:00
Jeff McCune
ab03ef1052 (#27) Refactor top level schema
Remove content and contentType top level keys, deprecated in favor of
apiObjects.

Clarify toward the use of #CollectionName instead of project name.
2024-02-29 15:48:54 -08:00
Jeff McCune
8c76061b0d (#27) Add recommended labels and sort output
Add the recommended labels mapping to holos stage, project, and
component names.  Project will eventually be renamed to "collection" or
something.

Example:

    app.kubernetes.io/part-of: prod
    app.kubernetes.io/name: secrets
    app.kubernetes.io/component: validate
    app.kubernetes.io/instance: prod-secrets-validate

Also sort the api objects produced from cue so the output of the `holos
render` command is stable for git commits.
2024-02-29 15:12:19 -08:00
Jeff McCune
f60db8fa1f (#25) Show name of api object in errors
This patch changes the interface between CUE and Holos to remove the
content field and replace it with an api object map.  The map is a
`map[string]map[string]string` with the rendered yaml as the value of a
kind/name nesting.

This structure enables better error messages, cue disjunction errors
indicate the type and the name of the resource instead of just the list
index number.
2024-02-29 11:23:49 -08:00
Jeff McCune
eefc092ea9 (#22) Copy external secret data files one for one
Without this patch the secret data was nested under a key with the same
name as the secret name.  This caused the ceph controller to not find
the values.

This patch changes the golden path for #ExternalSecret to copy all data
keys 1:1 from the external to the target in the cluster.
2024-02-28 16:51:26 -08:00
Jeff McCune
0860ac3409 (#22) Rename ceph secret to include ClusterName
Without this patch all clusters would use the same ceph secret from the
provisioner cluster.  This is a problem because ceph credentials are
unique per cluster.

This patch renames the ceph secret to have a cluster name prefix.

The secret is created with:

```bash
vault kv get -format=json -field data kv/k2/kube-namespace/ceph-csi-rbd/csi-rbd-secret \
  | holos create secret --namespace ceph-system k2-ceph-csi-rbd --cluster-name=k2 --data-stdin --append-hash=false
```
2024-02-28 16:14:22 -08:00
Jeff McCune
6b156e9883 (#22) Label ns ceph-system with pod-security enforce: privileged
This patch adds the `pod-security.kubernetes.io/enforce: privileged`
label to the ceph-system namespace.

The Namespace resources are managed all over the map, it would be a good
idea to consolidate the PlatformNamespaces data into one well known
place for the entire platform.  Eschewing for now.
2024-02-28 15:57:01 -08:00
Jeff McCune
4de9f77fbf (#22) Add holos create secret --data-stdin flag
This patch enables quickly copying secrets from vault to the provisioner
cluster.  For example:

    vault kv get -format=json -field data kv/k2/kube-namespace/ceph-csi-rbd/csi-rbd-secret \
      | holos create secret --namespace ceph-system csi-rbd-secret --data-stdin --append-hash=false
2024-02-28 15:29:32 -08:00
Jeff McCune
4c5429b64a (#22) Ceph CSI for Metal clusters
This patch adds the ceph-csi-rbd helm chart component to the metal
cluster type.  The purpose is to enable PersistentVolumeClaims on ois
metal clusters.

Cloud clusters like GKE and EKS are expected to skip rendering the metal
type.

Helm values are handled with CUE.  The ceph secret is managed as an
ExternalSecret resource, appended to the rendered output by cue and the
holos cli.

Use:

    ❯ holos render --cluster-name=k2 ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/metal/...
    2:45PM INF render.go:40 rendered prod-metal-ceph version=0.47.0 status=ok action=rendered name=prod-metal-ceph
2024-02-28 14:46:03 -08:00
Jeff McCune
ac5bff4b32 (#20) Error if secret is not found
Without this patch scripts incorrectly proceeded without detecting a
secret was not fetched.

    holos get secret notfound

    8:34AM ERR could not execute version=0.46.3 err="not found: notfound" loc=get.go:66
2024-02-28 08:33:55 -08:00
Jeff McCune
6090ab224e (#14) Validate secrets fetched from provisioner cluster
This patch validates secrets are synced from the provisioner cluster to
a workload cluster.  This verifies the eso-creds-refresher job, external
secrets operator, etc...

Refer to
0ae58858f5
for the corresponding commit on the k2 cluster.
2024-02-27 15:55:17 -08:00
Jeff McCune
10e140258d (#15) Report multiple cue errors
This patch prints out the cue file and line numbers when a cue error
contains multiple go errors to unwrap.

For example:

```
❯ holos render --cluster-name=k2 ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/workload/...
3:31PM ERR could not execute version=0.46.0 err="could not decode: content: error in call to encoding/yaml.MarshalStream: incomplete value string (and 1 more errors)" loc=builder.go:212
content: error in call to encoding/yaml.MarshalStream: incomplete value string:
    /home/jeff/workspace/holos-run/holos/docs/examples/schema.cue:199:11
    /home/jeff/workspace/holos-run/holos/docs/examples/cue.mod/gen/external-secrets.io/externalsecret/v1beta1/types_gen.cue:83:14
```
2024-02-27 15:32:11 -08:00
Jeff McCune
40ac705f0d (#16) Add create secret --append-hash=false
So we can easily create secrets for use with ExternalSecret resources.
2024-02-27 12:04:00 -08:00
Jeff McCune
b4ad6425e5 (#14) Validate SecretStore works
This patch validates a SecretStore in the holos-system namespace works
after provisioner credentials are refreshed.
2024-02-27 11:25:00 -08:00
Jeff McCune
3343d226e5 (#14) Fix namespaces "external-secrets" not found
Needed for the `prod-secrets-eso` component to reconcile with flux.

NAME                                    REVISION                SUSPENDED       READY   MESSAGE
flux-system                             main@sha1:28b9ab6b      False           True    Applied revision: main@sha1:28b9ab6b
prod-secrets-eso                        main@sha1:28b9ab6b      False           True    Applied revision: main@sha1:28b9ab6b
prod-secrets-eso-creds-refresher        main@sha1:28b9ab6b      False           True    Applied revision: main@sha1:28b9ab6b
prod-secrets-namespaces                 main@sha1:28b9ab6b      False           True    Applied revision: main@sha1:28b9ab6b
2024-02-26 20:53:43 -08:00
Jeff McCune
f3a9b7cfbc (#10) Additional test coverage for secrets
Also fix a bug, secrets were created with keys that have a sub-directory
which is not a valid kubernetes secret.
2024-02-26 16:58:38 -08:00
Jeff McCune
53b7246d5e (#10) Add tests for holos get secrets command
This patch adds basic test data to run integration level tests on the
holos cli command.  Tests are structured similar to how the go and cue
maintainers test their own cli tools using the testscripts package.

Fixture data is loaded into a fake kubernetes.Clientset.

The holos root command is executed without using a full sub-process so
the fake kubernetes interface persists across multiple holos commands in
the same test case.

The fake kubernetes interface is reset after the testcase script
concludes and a new one starts.

Take care to read and write absolute paths from the test scripts, the
current working directory of the test runner is not set to $WORK when
executing the custom holos command.
2024-02-26 16:16:27 -08:00
Jeff McCune
c20872c92f v0.45.1 2024-02-24 11:37:03 -08:00
Jeff McCune
ecce1f797e (#8) Get secret subcommand
This patch adds a get secret subcommand.  With no args, lists holos
secrets.  With args, gets each argument.

The use cases are:

 1. Extract specified keys to files with --to-file
 2. Extract all keys to files with --extract-all
 3. Print one key to stdout with --print-key

If no key is specified, the key is implicitly set to the holos secret
name.  This behavior should be preserved as part of the api.
2024-02-24 11:32:48 -08:00
Jeff McCune
0d7033d063 (#8) Create secret subcommand
This patch adds a holos create secret command that behaves like kubectl
create secret, but for the specific use case of provisioning holos
clusters.

```
❯ holos create secret k2-talos --cluster-name=k2 --from-file=secrets.yaml
4:48PM INF secret.go:104 created: k2-talos-49546d9fd7 version=0.45.0 secret=k2-talos-49546d9fd7 name=k2-talos namespace=secrets
```

Once the corresponding `holos get secret` subcommands are implemented
the kv subcommand may be removed.
2024-02-23 16:49:13 -08:00
Jeff McCune
84bf0c8945 (#6) Holos kv put command to create secrets
A "holos secret" is a Secret in the secrets namespace of the provisioner
cluster.  The put command creates a unique secret from files and
directories listed as arguments, or from a txtar archive provided on
standard input.

Secret data may come from any or all of the following sources:

1. Create a secret from raw data on standard input.  --name and --file
   must be specified.
2. Create a secret from txtar data on standard input.  The secret name
   is taken from the --name flag if provided, otherwise is taken from
   the first line of the txtar comment.
3. Create a secret from files and directories specified as arguments.
   The secret name is the base name of the first argument unless it is
   overridden by the --name flag.

This is likely doing too much, really all we care about is this use
case:

holos kv put talosconfig

holos kv get talosconfig | holos txtar

Additionally, I want to get get one command without writing a file:

DATA="$(holos kv get talosconfig --file talosconfig)
2024-02-23 12:03:47 -08:00
Jeff McCune
466b48966a (#3) holos kv list command
Simple list command that finds the unique holos.run/secret.name label
values and prints them out.

    holos kv list
    k2-flux-system
    k2-talos
    test
2024-02-22 22:06:23 -08:00
Jeff McCune
84bcf4b2d0 Handle write errors when creating an archive 2024-02-22 21:46:41 -08:00
Jeff McCune
bdd76c78a7 Refactor txtar package for readability 2024-02-22 21:42:07 -08:00
Jeff McCune
95e0dfa44a Refactor render cli to a package
Tidy up the structure of the cli package, keep subcommand related
functions grouped together in a package.
2024-02-22 21:20:51 -08:00
Jeff McCune
90d70a6afa Refactor build cli to a package
Tidy up the structure of the cli package, keep subcommand related
functions grouped together in a package.
2024-02-22 21:20:45 -08:00
Jeff McCune
d0c2d85246 (#3) Refactor txtar cli to a package
Tidy up the structure of the cli package, keep txtar related functions
grouped together in a package.
2024-02-22 21:13:40 -08:00
Jeff McCune
7e637b4647 (#3) Refactor kv command to kv package
The structure of the cli package was getting to be a bit of a mess, time
to clean it up.  The structure is much easier to read with each command
in a separate package of related functionality.
2024-02-22 21:09:45 -08:00
Jeff McCune
9bc96d0783 (#3) holos txtar command for provisioner secrets
This patch makes it easy to fetch one or multiple files from a Secret in
the provisioner cluster to address two primary use cases:

 1. Extract files into a temporary directory to provide to other tools.
 2. Print one file to stdout.

For example, the secrets.yaml file necessary to reset a talos cluster is
printed to stdout in txtar format with one command:

    holos kv get k2-talos

The output has the secret name as the comment, then the value of each key of the data
field is printed as the txtar name and data.

    k2-talos-49546d9fd7
    -- secrets.yaml --
    ...

Extracting all of the files in the secret is also simple:

    holos kv get k2-talos | holos txtar
    8:34PM INF txtar.go:94 writing: secrets.yaml version=0.43.0 header=k2-talos-49546d9fd7 path=secrets.yaml bytes=4841

Extracting one file to stdout is also simple:

    holos kv get k2-talos | holos txtar --index=1
2024-02-22 20:38:44 -08:00
Jeff McCune
ac72ac5ace (#3) holos kv get command
This patch adds a command to get a secret and output the keys and values
in txtar format.  The goal is to easily save files to temporary
directories for scripts.

```
❯ holos kv get test
test-95m5dh57b9
-- other --
other:j1mGVxKhSD4gAVaaY1IHsDZbXt5vaGEg
-- random --
jeff:3l6QlDmr3aoAyxqDyh7t469n2D23EFHd
```
2024-02-22 15:13:29 -08:00
Jeff McCune
51f22443f3 Move secrets project components to the workload cluster
Goal is to render all of the flux kustomization components with:

```
❯ holos render --cluster-name=k2 ~/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/workload/...
4:47PM INF render.go:39 rendered prod-secrets-eso version=0.42.1 status=ok action=rendered name=prod-secrets-eso
4:47PM INF render.go:39 rendered prod-secrets-eso-creds-refresher version=0.42.1 status=ok action=rendered name=prod-secrets-eso-creds-refresher
4:47PM INF render.go:39 rendered prod-secrets-namespaces version=0.42.1 status=ok action=rendered name=prod-secrets-namespaces
```
2024-02-21 16:45:48 -08:00
Jeff McCune
e98ee28f74 Add eso-creds-refresher CronJob
This patch adds the `eso-creds-refresher` CronJob which executes every 8
hours in the holos-system namespace of each workload cluster.  The job
creates Secrets with a `token` field representing the id token
credential for a SecretStore to use when synchronizing secrets to and
from the provisioner cluster.

Service accounts in the provisioner cluster are selected with
selector=holos.run/job.name=eso-creds-refresher.

Each selected service account has a token issued with a 12 hour
expiration ttl and is stored in a Secret matching the service account
name in the same namespace in the workload cluster.

The job takes about 25 seconds to run once the image is cached on the
node.
2024-02-21 15:09:26 -08:00
Jeff McCune
b16d3459f7 Allow eso-creds-refresher iam service account to list ksas
Without this patch the Job on a workload cluster fails with:

```
+ kubectl get serviceaccount -A --selector=holos.run/job.name=eso-creds-refresher --output=json
Error from server (Forbidden): serviceaccounts is forbidden: User
"eso-creds-refresher@holos-run.iam.gserviceaccount.com" cannot list
resource "serviceaccounts" in API group "" at the cluster scope:
requires one of ["container.serviceAccounts.list"] permission(s).
```
2024-02-21 11:13:04 -08:00
Jeff McCune
f41b883dce Add holos.run/job.name=eso-creds-refresher label to ksa
This label is intended for the Job to select which service accounts to
issue tokens for.  For example:

  kubectl get serviceaccount -A --selector=holos.run/job.name=eso-creds-refresher --output=json
2024-02-21 11:03:33 -08:00
Jeff McCune
572281914c Remove view role from eso-creds-refresher
Listing namespaces is sufficient, viewing all resources isn't necessary.
2024-02-21 10:32:41 -08:00
Jeff McCune
4cdf9d2dae Refactor eso-reader and eso-writer provisioner service accounts
Without this patch it is difficult to navigate the structure of the
configuration of the api objects because they're positional elements in
a list.

This patch extracts the configuration of the eso-reader and eso-writer
ServiceAccount, Role, and RoleBinding structs into a definition that
behaves like a function.  The individual objects are fields of the
struct instead of positional elements in a list.
2024-02-21 10:08:39 -08:00
Jeff McCune
29a4fae059 Merge pull request #1 from holos-run/jeff/provisioner
Provisioner Cluster to host secrets for workload clusters
2024-02-20 17:47:27 -08:00
Jeff McCune
fd306aae76 Pod eso-creds-refresher authenticates to provisioner
This patch adds a ConfigMap and Pod to the eso-creds-refresher
component.  The Pod executes the gcloud container, impersonates the
eso-creds-refresher iam service account using workload identity, then
authenticates to the remote provisioner cluster.

This is the foundation for a script to automatically create Secret API
objects in a workload cluster which have a kubernetes service account
token ESO SecretStore resources can use to fetch secrets from the
provisioner cluster.

Once we have that script in place we can turn this Pod into a Job and
replace Vault.
2024-02-20 17:45:43 -08:00
Jeff McCune
e4875fe3a6 Do not release on pull requests 2024-02-20 17:45:43 -08:00
Jeff McCune
5bf2b85036 Refactor namespaces separate from eso-creds-refresher
Manage namespaces in a separate component so we can easily run the
eso-creds-refresher component through kubectl delete -f- without
deleting the namespace.

For the k2 cluster:

```
❯ holos build ./platforms/reference/clusters/workload/... | k apply --server-side=true -f-
serviceaccount/eso-creds-refresher serverside-applied
clusterrole.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
namespace/holos-system serverside-applied
namespace/flux-system serverside-applied
namespace/ceph-system serverside-applied
namespace/istio-system serverside-applied
namespace/istio-ingress serverside-applied
namespace/cert-manager serverside-applied
namespace/argocd serverside-applied
```

For the provisioner cluster:

```
❯ holos build ./platforms/reference/clusters/provisioner/... | k apply --server-side=true -f-
clusterrolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
role.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
serviceaccount/eso-reader serverside-applied
role.rbac.authorization.k8s.io/eso-reader serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-reader serverside-applied
serviceaccount/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
serviceaccount/eso-reader serverside-applied
role.rbac.authorization.k8s.io/eso-reader serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-reader serverside-applied
serviceaccount/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
serviceaccount/eso-reader serverside-applied
role.rbac.authorization.k8s.io/eso-reader serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-reader serverside-applied
serviceaccount/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
serviceaccount/eso-reader serverside-applied
role.rbac.authorization.k8s.io/eso-reader serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-reader serverside-applied
serviceaccount/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
serviceaccount/eso-reader serverside-applied
role.rbac.authorization.k8s.io/eso-reader serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-reader serverside-applied
serviceaccount/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
serviceaccount/eso-reader serverside-applied
role.rbac.authorization.k8s.io/eso-reader serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-reader serverside-applied
serviceaccount/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-creds-refresher serverside-applied
serviceaccount/eso-reader serverside-applied
role.rbac.authorization.k8s.io/eso-reader serverside-applied
rolebinding.rbac.authorization.k8s.io/eso-reader serverside-applied
serviceaccount/eso-writer serverside-applied
role.rbac.authorization.k8s.io/eso-writer serverside-applied
namespace/holos-system serverside-applied
namespace/flux-system serverside-applied
namespace/ceph-system serverside-applied
namespace/istio-system serverside-applied
namespace/istio-ingress serverside-applied
namespace/cert-manager serverside-applied
namespace/argocd serverside-applied
```
2024-02-20 15:40:32 -08:00
Jeff McCune
0771bd6b6c Configure namespaces in the provisioner cluster
The provisioner cluster is a worker-less autopilot cluster that provides
secrets to other clusters in the platform.  The `eso-creds-refresher`
Job in the holos-system namespace of each other cluster refreshes
service account tokens for SecretStores.

This patch adds the IAM structure for the Job implemented by Namespace,
ServiceAccount, Role, and RoleBinding api objects.
2024-02-19 21:37:13 -08:00
Jeff McCune
f647a4a76c Fix secret validation path 2024-02-13 17:58:21 -08:00
Jeff McCune
37d5eac841 Add dependency from prod-secrets-validate to prod-secrets-eso 2024-02-13 17:44:21 -08:00
Jeff McCune
3e991d9026 Add holos build --cluster-name flag
Without this patch the build command doesn't fill in the cue cluster
name tag, resulting in incorrect output compared to the render command.

With this patch the correct output is generated.  Note the `mountPath`
field is correct:

```
❯ holos build ~/workspace/holos-run/holos/docs/examples/platforms/reference/projects/secrets/components/validate
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: default
  namespace: default
spec:
  provider:
    vault:
      auth:
        kubernetes:
          mountPath: k2
          role: default
          serviceAccountRef:
            name: default
      path: kv/k8s
      server: https://vault.core.ois.run
      version: v2
```
2024-02-13 17:26:14 -08:00
Jeff McCune
a6dab235f5 Add SecretStore and ExternalSecret validation component
This patch adds a holos component to deploy a SecretStore and
ExternalSecret in the default namespace to validate authentication with
Vault is configured correctly.

The default ksa is used to authenticate to vault.
2024-02-13 17:21:14 -08:00
Jeff McCune
f4c85736a2 Move instances to leaf nodes for cue
This patch makes it possible to build all components for a platform with
a single command:

  ❯ holos render ~/workspace/holos-run/holos/docs/examples/platforms/reference/...
  2:51PM INF render.go:39 rendered prod-secrets-eso version=0.42.0 status=ok action=rendered name=prod-secrets-eso
  2:51PM INF render.go:39 rendered prod-secrets-namespaces version=0.42.0 status=ok action=rendered name=prod-secrets-namespaces

Note the `reference/...` path base name.  Without this patch cue tried
to build an intermediate directory instance.
2024-02-13 14:51:01 -08:00
Jeff McCune
f9fef06c55 Cache helm charts
This patch speeds up rendering by storing a copy of helm charts in the
holos component directory.
2024-02-13 14:24:45 -08:00
Jeff McCune
039fb056c0 Have prod-secrets-eso depend on prod-secrets-namespaces
This patch is an example of using CUE to add the dependsOn field to the
generated kustomization.yaml.

```
❯ holos render ~/workspace/holos-run/holos/docs/examples/platforms/reference/projects/secrets/components/...
11:51AM INF render.go:39 rendered prod-secrets-eso version=0.41.0 status=ok action=rendered name=prod-secrets-eso
11:51AM INF render.go:39 rendered prod-secrets-namespaces version=0.41.0 status=ok action=rendered name=prod-secrets-namespaces

❯ git add -p
diff --git a/deploy/clusters/k2/holos/components/prod-secrets-eso-kustomization.gen.yaml b/deploy/clusters/k2/holos/components/prod-secrets-eso-kustomization.gen.yaml
index 74c626d0..2dedf991 100644
--- a/deploy/clusters/k2/holos/components/prod-secrets-eso-kustomization.gen.yaml
+++ b/deploy/clusters/k2/holos/components/prod-secrets-eso-kustomization.gen.yaml
@@ -4,6 +4,8 @@ metadata:
   name: prod-secrets-eso
   namespace: flux-system
 spec:
+  dependsOn:
+    - name: prod-secrets-namespaces
   interval: 30m0s
   path: deploy/clusters/k2/components/prod-secrets-eso
   prune: true
```
2024-02-13 11:51:55 -08:00
Jeff McCune
cde4380049 Add holos component HelmChart type
This patch implements rendering a holos component from an upstream helm
chart using a values.yaml file generated by CUE.  The resulting
kubernetes api objects are saved to the deploy directory in the same way
the KubernetesObject holos component type.

```
❯ holos render --cluster-name=core2 ./docs/examples/platforms/reference/projects/secrets/components/...
3:55PM INF render.go:39 rendered prod-secrets-eso version=0.41.0 status=ok action=rendered name=prod-secrets-eso
3:55PM INF render.go:39 rendered prod-secrets-namespaces version=0.41.0 status=ok action=rendered name=prod-secrets-namespaces
```

```
❯ tree deploy
deploy
└── clusters
    └── core2
        ├── components
        │   ├── prod-secrets-eso
        │   │   └── prod-secrets-eso.gen.yaml
        │   └── prod-secrets-namespaces
        │       └── prod-secrets-namespaces.gen.yaml
        └── holos
            └── components
                ├── prod-secrets-eso-kustomization.gen.yaml
                └── prod-secrets-namespaces-kustomization.gen.yaml

7 directories, 4 files
```
2024-02-12 15:56:06 -08:00
Jeff McCune
0d4f36333f Add platform and instance values to helm values 2024-02-12 10:16:40 -08:00
Jeff McCune
69916a13ab Decode cue values for use as helm values
In helm mode, cue is responsible for producing the values.yaml file.
Holos is responsible for taking the values produced by cue and providing
them to helm to produce rendered kubernetes api objects.

This patch adds intermediate data structures to hold the output from
cue: the helm values, the flux kustomization, and the helm charts to
provide the helm values to.

Holos takes this information and orchestrates running helm template to
render the api objects and write them to the file system for git ops.
2024-02-12 09:53:47 -08:00
Jeff McCune
9739fc6471 Initial structure for helm support
Stopping here to look into generating go types from the cue output type
definitions.
2024-02-10 17:14:42 -08:00
Jeff McCune
1d3b9340ab Fix log message 2024-02-09 15:54:02 -08:00
Jeff McCune
bb06fa742a Render flux Kustomization along with api objects
This patch writes a Flux Kustomization to apply the api objects rendered
by a component instance.

    ❯ holos render --log-format=json --log-level=debug --cluster-name core2 ./docs/examples/platforms/reference/projects/secrets/components/namespaces/ 2> >(./scripts/msgs)
    config.go:91    finalized config from flags
    builder.go:129  cue export --out yaml -t cluster=core2 ./platforms/reference/projects/secrets/components/namespaces
    builder.go:134  configured cue tags: [cluster=core2]
    builder.go:94   wrote deploy/clusters/core2/components/prod-secrets-namespaces/prod-secrets-namespaces.gen.yaml
    builder.go:94   wrote deploy/clusters/core2/holos/components/prod-secrets-namespaces-kustomization.gen.yaml
    render.go:39    rendered prod-secrets-namespaces

```yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: prod-secrets-namespaces
  namespace: flux-system
spec:
  interval: 30m0s
  path: deploy/clusters/core2/components/prod-secrets-namespaces
  prune: true
  retryInterval: 2m0s
  sourceRef:
    kind: GitRepository
    name: flux-system
  timeout: 3m0s
  wait: true
```
2024-02-09 15:42:50 -08:00
Jeff McCune
7dce445c1a Import flux v2.2.3 crds into cue schemas
timoni mod vendor crds -f https://github.com/fluxcd/flux2/releases/download/v2.2.3/install.yaml
2024-02-09 13:45:57 -08:00
599 changed files with 174177 additions and 532 deletions

View File

@@ -1,6 +1,7 @@
---
# https://github.com/golangci/golangci-lint-action?tab=readme-ov-file#how-to-use
name: Lint
on:
"on":
push:
branches:
- main
@@ -14,14 +15,33 @@ permissions:
jobs:
golangci:
name: lint
runs-on: [self-hosted, k8s]
runs-on: gha-rs
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
cache: false
- name: Install tools
run: sudo apt update && sudo apt -qq -y install curl zip unzip tar bzip2 make
- name: Install Deps
run: |
make go-deps
go generate ./...
make frontend-deps
make frontend
go mod tidy
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v4
with:
version: latest

View File

@@ -1,34 +1,58 @@
name: Release
on:
pull_request:
push:
# Run only against tags
tags:
- '*'
branches:
- release
permissions:
contents: write
jobs:
goreleaser:
runs-on: [self-hosted, k8s]
runs-on: gha-rs
steps:
# Must come before Checkout, otherwise goreleaser fails
- name: Provide GPG and Git
run: sudo apt update && sudo apt -qq -y install gnupg git curl zip unzip tar bzip2 make
# Must come after git executable is provided
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
# Necessary to run these outside of goreleaser, otherwise
# /home/runner/_work/holos/holos/internal/frontend/node_modules/.bin/protoc-gen-connect-query is not in PATH
- name: Install Deps
run: |
make go-deps
go generate ./...
make frontend-deps
make frontend
go mod tidy
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_CODE_SIGNING_SECRETKEY }}
passphrase: ${{ secrets.GPG_CODE_SIGNING_PASSPHRASE }}
- name: List keys
run: gpg -K
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:

View File

@@ -13,15 +13,37 @@ permissions:
jobs:
test:
runs-on: [self-hosted, k8s]
runs-on: gha-rs
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
- name: Install tools
run: sudo apt update && sudo apt -qq -y install curl zip unzip tar bzip2 make
- name: Set up Helm
uses: azure/setup-helm@v4
- name: Set up Kubectl
uses: azure/setup-kubectl@v3
- name: Install Deps
run: |
make go-deps
go generate ./...
make frontend-deps
make frontend
go mod tidy
- name: Test
run: ./scripts/test

3
.gitignore vendored
View File

@@ -2,6 +2,7 @@ bin/
vendor/
.idea/
coverage.out
dist/
/dist/
*.hold/
/deploy/
.vscode/

2
.golangci.yaml Normal file
View File

@@ -0,0 +1,2 @@
run:
timeout: 5m

View File

@@ -10,10 +10,8 @@ version: 1
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
- go mod tidy
builds:
- main: ./cmd/holos
@@ -23,6 +21,9 @@ builds:
- linux
- windows
- darwin
goarch:
- amd64
- arm64
signs:
- artifacts: checksum

View File

@@ -4,7 +4,7 @@ PROJ=holos
ORG_PATH=github.com/holos-run
REPO_PATH=$(ORG_PATH)/$(PROJ)
VERSION := $(shell grep "const Version " pkg/version/version.go | sed -E 's/.*"(.+)"$$/\1/')
VERSION := $(shell cat pkg/version/embedded/major pkg/version/embedded/minor pkg/version/embedded/patch | xargs printf "%s.%s.%s")
BIN_NAME := holos
DOCKER_REPO=quay.io/openinfrastructure/holos
@@ -12,6 +12,9 @@ IMAGE_NAME=$(DOCKER_REPO)
$( shell mkdir -p bin)
# For buf plugin protoc-gen-connect-es
export PATH := $(PWD)/internal/frontend/holos/node_modules/.bin:$(PATH)
GIT_COMMIT=$(shell git rev-parse HEAD)
GIT_TREE_STATE=$(shell test -n "`git status --porcelain`" && echo "dirty" || echo "clean")
BUILD_DATE=$(shell date -Iseconds)
@@ -39,18 +42,27 @@ bumpmajor: ## Bump the major version.
scripts/bump minor 0
scripts/bump patch 0
.PHONY: show-version
show-version: ## Print the full version.
@echo $(VERSION)
.PHONY: tidy
tidy: ## Tidy go module.
go mod tidy
.PHONY: fmt
fmt: ## Format Go code.
fmt: ## Format code.
cd docs/examples && cue fmt ./...
go fmt ./...
.PHONY: vet
vet: ## Vet Go code.
go vet ./...
.PHONY: gencue
gencue: ## Generate CUE definitions
cd docs/examples && cue get go github.com/holos-run/holos/api/...
.PHONY: generate
generate: ## Generate code.
go generate ./...
@@ -85,6 +97,37 @@ coverage: test ## Test coverage profile.
snapshot: ## Go release snapshot
goreleaser release --snapshot --clean
.PHONY: buf
buf: ## buf generate
cd service && buf mod update
buf generate
.PHONY: go-deps
go-deps: ## install go executables
go install github.com/bufbuild/buf/cmd/buf@v1
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@v1
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1
go install connectrpc.com/connect/cmd/protoc-gen-connect-go@v1
go install honnef.co/go/tools/cmd/staticcheck@latest
# curl https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash
.PHONY: frontend-deps
frontend-deps: ## Setup npm and vite
cd internal/frontend/holos && npm install
cd internal/frontend/holos && npm install --save-dev @bufbuild/buf @connectrpc/protoc-gen-connect-es
cd internal/frontend/holos && npm install @connectrpc/connect @connectrpc/connect-web @bufbuild/protobuf
# https://github.com/connectrpc/connect-query-es/blob/1350b6f07b6aead81793917954bdb1cc3ce09df9/packages/protoc-gen-connect-query/README.md?plain=1#L23
cd internal/frontend/holos && npm install --save-dev @connectrpc/protoc-gen-connect-query @bufbuild/protoc-gen-es
cd internal/frontend/holos && npm install @connectrpc/connect-query @bufbuild/protobuf
.PHONY: frontend
frontend: buf
mkdir -p internal/frontend/holos/dist
cd internal/frontend/holos/dist && rm -rf app
cd internal/frontend/holos && ng build
touch internal/frontend/frontend.go
.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)

315
Tiltfile Normal file
View File

@@ -0,0 +1,315 @@
# -*- mode: Python -*-
# This Tiltfile manages a Go project with live leload in Kubernetes
listen_port = 3000
metrics_port = 9090
# Use our wrapper to set the kube namespace
if os.getenv('TILT_WRAPPER') != '1':
fail("could not run, ./hack/tilt/bin/tilt was not used to start tilt")
# AWS Account to work in
aws_account = '271053619184'
aws_region = 'us-east-2'
# Resource ids
holos_backend = 'Holos Backend'
pg_admin = 'pgAdmin'
pg_cluster = 'PostgresCluster'
pg_svc = 'Database Pod'
compile_id = 'Go Build'
auth_id = 'Auth Policy'
lint_id = 'Run Linters'
tests_id = 'Run Tests'
# PostgresCluster resource name in k8s
pg_cluster_name = 'holos'
# Database name inside the PostgresCluster
pg_database_name = 'holos'
# PGAdmin name
pg_admin_name = 'pgadmin'
# Default Registry.
# See: https://github.com/tilt-dev/tilt.build/blob/master/docs/choosing_clusters.md#manual-configuration
# Note, Tilt will append the image name to the registry uri path
default_registry('{account}.dkr.ecr.{region}.amazonaws.com/holos-run/holos-server'.format(account=aws_account, region=aws_region))
# Set a name prefix specific to the user. Multiple developers share the tilt-holos namespace.
developer = os.getenv('USER')
holos_server = 'holos'
# See ./hack/tilt/bin/tilt
namespace = os.getenv('NAMESPACE')
# We always develop against the k1 cluster.
os.putenv('KUBECONFIG', os.path.abspath('./hack/tilt/kubeconfig'))
# The context defined in ./hack/tilt/kubeconfig
allow_k8s_contexts('sso@k1')
allow_k8s_contexts('sso@k2')
allow_k8s_contexts('sso@k3')
allow_k8s_contexts('sso@k4')
allow_k8s_contexts('sso@k5')
# PG db connection for localhost -> k8s port-forward
os.putenv('PGHOST', 'localhost')
os.putenv('PGPORT', '15432')
# We always develop in the dev aws account.
os.putenv('AWS_CONFIG_FILE', os.path.abspath('./hack/tilt/aws.config'))
os.putenv('AWS_ACCOUNT', aws_account)
os.putenv('AWS_DEFAULT_REGION', aws_region)
os.putenv('AWS_PROFILE', 'dev-holos')
os.putenv('AWS_SDK_LOAD_CONFIG', '1')
# Authenticate to AWS ECR when tilt up is run by the developer
local_resource('AWS Credentials', './hack/tilt/aws-login.sh', auto_init=True)
# Extensions are open-source, pre-packaged functions that extend Tilt
#
# More info: https://github.com/tilt-dev/tilt-extensions
# More info: https://docs.tilt.dev/extensions.html
load('ext://restart_process', 'docker_build_with_restart')
load('ext://k8s_attach', 'k8s_attach')
load('ext://git_resource', 'git_checkout')
load('ext://uibutton', 'cmd_button')
# Paths edited by the developer Tilt watches to trigger compilation.
# Generated files should be excluded to avoid an infinite build loop.
developer_paths = [
'./cmd',
'./internal/server',
'./internal/ent/schema',
'./frontend/package-lock.json',
'./frontend/src',
'./go.mod',
'./pkg',
'./service/holos',
]
# Builds the holos-server executable
local_resource(compile_id, 'make build', deps=developer_paths)
# Build Docker image
# Tilt will automatically associate image builds with the resource(s)
# that reference them (e.g. via Kubernetes or Docker Compose YAML).
#
# More info: https://docs.tilt.dev/api.html#api.docker_build
#
docker_build_with_restart(
'holos',
context='.',
entrypoint=[
'/app/bin/holos',
'server',
'--listen-port={}'.format(listen_port),
'--oidc-issuer=https://login.ois.run',
'--oidc-audience=262096764402729854@holos_platform',
'--metrics-port={}'.format(metrics_port),
],
dockerfile='./hack/tilt/Dockerfile',
only=['./bin'],
# (Recommended) Updating a running container in-place
# https://docs.tilt.dev/live_update_reference.html
live_update=[
# Sync files from host to container
sync('./bin', '/app/bin'),
# Wait for aws-login https://github.com/tilt-dev/tilt/issues/3048
sync('./tilt/aws-login.last', '/dev/null'),
# Execute commands in the container when paths change
# run('/app/hack/codegen.sh', trigger=['./app/api'])
],
)
# Run local commands
# Local commands can be helpful for one-time tasks like installing
# project prerequisites. They can also manage long-lived processes
# for non-containerized services or dependencies.
#
# More info: https://docs.tilt.dev/local_resource.html
#
# local_resource('install-helm',
# cmd='which helm > /dev/null || brew install helm',
# # `cmd_bat`, when present, is used instead of `cmd` on Windows.
# cmd_bat=[
# 'powershell.exe',
# '-Noninteractive',
# '-Command',
# '& {if (!(Get-Command helm -ErrorAction SilentlyContinue)) {scoop install helm}}'
# ]
# )
# Teach tilt about our custom resources (Note, this may be intended for workloads)
# k8s_kind('authorizationpolicy')
# k8s_kind('requestauthentication')
# k8s_kind('virtualservice')
k8s_kind('pgadmin')
# Troubleshooting
def resource_name(id):
print('resource: {}'.format(id))
return id.name
workload_to_resource_function(resource_name)
# Apply Kubernetes manifests
# Tilt will build & push any necessary images, re-deploying your
# resources as they change.
#
# More info: https://docs.tilt.dev/api.html#api.k8s_yaml
#
def holos_yaml():
"""Return a k8s Deployment personalized for the developer."""
k8s_yaml_template = str(read_file('./hack/tilt/k8s.yaml'))
return k8s_yaml_template.format(
name=holos_server,
developer=developer,
namespace=namespace,
listen_port=listen_port,
metrics_port=metrics_port,
tz=os.getenv('TZ'),
)
# Customize a Kubernetes resource
# By default, Kubernetes resource names are automatically assigned
# based on objects in the YAML manifests, e.g. Deployment name.
#
# Tilt strives for sane defaults, so calling k8s_resource is
# optional, and you only need to pass the arguments you want to
# override.
#
# More info: https://docs.tilt.dev/api.html#api.k8s_resource
#
k8s_yaml(blob(holos_yaml()))
# Backend server process
k8s_resource(
workload=holos_server,
new_name=holos_backend,
objects=[
'{}:serviceaccount'.format(holos_server),
'{}:servicemonitor'.format(holos_server),
],
resource_deps=[compile_id],
links=[
link('https://{}.holos.dev.k2.ois.run/app/'.format(developer), "Holos Web UI")
],
)
# AuthorizationPolicy - Beyond Corp functionality
k8s_resource(
new_name=auth_id,
objects=[
'{}:virtualservice'.format(holos_server),
'{}-allow-groups:authorizationpolicy'.format(holos_server),
'{}-allow-nothing:authorizationpolicy'.format(holos_server),
'{}-allow-well-known-paths:authorizationpolicy'.format(holos_server),
'{}-auth:authorizationpolicy'.format(holos_server),
'{}:requestauthentication'.format(holos_server),
],
)
# Database
# Note: Tilt confuses the backup pods with the database server pods, so this code is careful to tease the pods
# apart so logs are streamed correctly.
# See: https://github.com/tilt-dev/tilt.specs/blob/master/resource_assembly.md
# pgAdmin Web UI
k8s_resource(
workload=pg_admin_name,
new_name=pg_admin,
port_forwards=[
port_forward(15050, 5050, pg_admin),
],
)
# Disabled because these don't group resources nicely
# k8s_kind('postgrescluster')
# Postgres database in-cluster
k8s_resource(
new_name=pg_cluster,
objects=['holos:postgrescluster'],
)
# Needed to select the database by label
# https://docs.tilt.dev/api.html#api.k8s_custom_deploy
k8s_custom_deploy(
pg_svc,
apply_cmd=['./hack/tilt/k8s-get-db-sts', pg_cluster_name],
delete_cmd=['echo', 'Skipping delete. Object managed by custom resource.'],
deps=[],
)
k8s_resource(
pg_svc,
port_forwards=[
port_forward(15432, 5432, 'psql'),
],
resource_deps=[pg_cluster]
)
# Run tests
local_resource(
tests_id,
'make test',
allow_parallel=True,
auto_init=False,
deps=developer_paths,
)
# Run linter
local_resource(
lint_id,
'make lint',
allow_parallel=True,
auto_init=False,
deps=developer_paths,
)
# UI Buttons for helpful things.
# Icons: https://fonts.google.com/icons
os.putenv("GH_FORCE_TTY", "80%")
cmd_button(
'{}:go-test-failfast'.format(tests_id),
argv=['./hack/tilt/go-test-failfast'],
resource=tests_id,
icon_name='quiz',
text='Fail Fast',
)
cmd_button(
'{}:issues'.format(holos_server),
argv=['./hack/tilt/gh-issues'],
resource=holos_backend,
icon_name='folder_data',
text='Issues',
)
cmd_button(
'{}:gh-issue-view'.format(holos_server),
argv=['./hack/tilt/gh-issue-view'],
resource=holos_backend,
icon_name='task',
text='View Issue',
)
cmd_button(
'{}:get-pgdb-creds'.format(holos_server),
argv=['./hack/tilt/get-pgdb-creds', pg_cluster_name, pg_database_name],
resource=pg_svc,
icon_name='lock_open_right',
text='DB Creds',
)
cmd_button(
'{}:get-pgdb-creds'.format(pg_admin_name),
argv=['./hack/tilt/get-pgdb-creds', pg_cluster_name, pg_database_name],
resource=pg_admin,
icon_name='lock_open_right',
text='DB Creds',
)
cmd_button(
'{}:get-pgadmin-creds'.format(pg_admin_name),
argv=['./hack/tilt/get-pgadmin-creds', pg_admin_name],
resource=pg_admin,
icon_name='lock_open_right',
text='pgAdmin Login',
)
print("✨ Tiltfile evaluated")

40
api/v1alpha1/buildplan.go Normal file
View File

@@ -0,0 +1,40 @@
package v1alpha1
import (
"fmt"
"strings"
)
// BuildPlan is the primary interface between CUE and the Holos cli.
type BuildPlan struct {
TypeMeta `json:",inline" yaml:",inline"`
// Metadata represents the holos component name
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
Spec BuildPlanSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
}
type BuildPlanSpec struct {
Disabled bool `json:"disabled,omitempty" yaml:"disabled,omitempty"`
Components BuildPlanComponents `json:"components,omitempty" yaml:"components,omitempty"`
}
type BuildPlanComponents struct {
HelmChartList []HelmChart `json:"helmChartList,omitempty" yaml:"helmChartList,omitempty"`
KubernetesObjectsList []KubernetesObjects `json:"kubernetesObjectsList,omitempty" yaml:"kubernetesObjectsList,omitempty"`
KustomizeBuildList []KustomizeBuild `json:"kustomizeBuildList,omitempty" yaml:"kustomizeBuildList,omitempty"`
Resources map[string]KubernetesObjects `json:"resources,omitempty" yaml:"resources,omitempty"`
}
func (bp *BuildPlan) Validate() error {
errs := make([]string, 0, 2)
if bp.Kind != BuildPlanKind {
errs = append(errs, fmt.Sprintf("kind invalid: want: %s have: %s", BuildPlanKind, bp.Kind))
}
if bp.APIVersion != APIVersion {
errs = append(errs, fmt.Sprintf("apiVersion invalid: want: %s have: %s", APIVersion, bp.APIVersion))
}
if len(errs) > 0 {
return fmt.Errorf("invalid BuildPlan: " + strings.Join(errs, ", "))
}
return nil
}

22
api/v1alpha1/component.go Normal file
View File

@@ -0,0 +1,22 @@
package v1alpha1
// HolosComponent defines the fields common to all holos component kinds including the Render Result.
type HolosComponent struct {
TypeMeta `json:",inline" yaml:",inline"`
// Metadata represents the holos component name
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
// APIObjectMap holds the marshalled representation of api objects. Think of
// these as resources overlaid at the back of the render pipeline.
APIObjectMap APIObjectMap `json:"apiObjectMap,omitempty" yaml:"apiObjectMap,omitempty"`
// Kustomization holds the marshalled representation of the flux kustomization
// which reconciles resources in git with the api server.
Kustomization `json:",inline" yaml:",inline"`
// Kustomize represents a kubectl kustomize build post-processing step.
Kustomize `json:",inline" yaml:",inline"`
// Skip causes holos to take no action regarding the component.
Skip bool
}
func (hc *HolosComponent) NewResult() *Result {
return &Result{HolosComponent: *hc}
}

11
api/v1alpha1/constants.go Normal file
View File

@@ -0,0 +1,11 @@
package v1alpha1
const (
APIVersion = "holos.run/v1alpha1"
BuildPlanKind = "BuildPlan"
HelmChartKind = "HelmChart"
// ChartDir is the directory name created in the holos component directory to cache a chart.
ChartDir = "vendor"
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
ResourcesFile = "resources.yaml"
)

2
api/v1alpha1/doc.go Normal file
View File

@@ -0,0 +1,2 @@
// Package v1alpha1 defines the api boundary between CUE and Holos.
package v1alpha1

154
api/v1alpha1/helm.go Normal file
View File

@@ -0,0 +1,154 @@
package v1alpha1
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/holos-run/holos"
"github.com/holos-run/holos/pkg/errors"
"github.com/holos-run/holos/pkg/logger"
"github.com/holos-run/holos/pkg/util"
)
// A HelmChart represents a helm command to provide chart values in order to render kubernetes api objects.
type HelmChart struct {
HolosComponent `json:",inline" yaml:",inline"`
// Namespace is the namespace to install into. TODO: Use metadata.namespace instead.
Namespace string `json:"namespace"`
Chart Chart `json:"chart"`
ValuesContent string `json:"valuesContent"`
EnableHooks bool `json:"enableHooks"`
}
type Chart struct {
Name string `json:"name"`
Version string `json:"version"`
Release string `json:"release"`
Repository Repository `json:"repository,omitempty"`
}
type Repository struct {
Name string `json:"name"`
URL string `json:"url"`
}
func (hc *HelmChart) Render(ctx context.Context, path holos.InstancePath) (*Result, error) {
result := Result{HolosComponent: hc.HolosComponent}
if err := hc.helm(ctx, &result, path); err != nil {
return nil, err
}
result.addObjectMap(ctx, hc.APIObjectMap)
if err := result.kustomize(ctx); err != nil {
return nil, errors.Wrap(fmt.Errorf("could not kustomize: %w", err))
}
return &result, nil
}
// runHelm provides the values produced by CUE to helm template and returns
// the rendered kubernetes api objects in the result.
func (hc *HelmChart) helm(ctx context.Context, r *Result, path holos.InstancePath) error {
log := logger.FromContext(ctx).With("chart", hc.Chart.Name)
if hc.Chart.Name == "" {
log.WarnContext(ctx, "skipping helm: no chart name specified, use a different component type")
return nil
}
cachedChartPath := filepath.Join(string(path), ChartDir, filepath.Base(hc.Chart.Name))
if isNotExist(cachedChartPath) {
// Add repositories
repo := hc.Chart.Repository
if repo.URL != "" {
out, err := util.RunCmd(ctx, "helm", "repo", "add", repo.Name, repo.URL)
if err != nil {
log.ErrorContext(ctx, "could not run helm", "stderr", out.Stderr.String(), "stdout", out.Stdout.String())
return errors.Wrap(fmt.Errorf("could not run helm repo add: %w", err))
}
// Update repository
out, err = util.RunCmd(ctx, "helm", "repo", "update", repo.Name)
if err != nil {
log.ErrorContext(ctx, "could not run helm", "stderr", out.Stderr.String(), "stdout", out.Stdout.String())
return errors.Wrap(fmt.Errorf("could not run helm repo update: %w", err))
}
} else {
log.DebugContext(ctx, "no chart repository url proceeding assuming oci chart")
}
// Cache the chart
if err := cacheChart(ctx, path, ChartDir, hc.Chart); err != nil {
return fmt.Errorf("could not cache chart: %w", err)
}
}
// Write values file
tempDir, err := os.MkdirTemp("", "holos")
if err != nil {
return errors.Wrap(fmt.Errorf("could not make temp dir: %w", err))
}
defer util.Remove(ctx, tempDir)
valuesPath := filepath.Join(tempDir, "values.yaml")
if err := os.WriteFile(valuesPath, []byte(hc.ValuesContent), 0644); err != nil {
return errors.Wrap(fmt.Errorf("could not write values: %w", err))
}
log.DebugContext(ctx, "helm: wrote values", "path", valuesPath, "bytes", len(hc.ValuesContent))
// Run charts
chart := hc.Chart
args := []string{"template"}
if !hc.EnableHooks {
args = append(args, "--no-hooks")
}
namespace := hc.Namespace
args = append(args, "--include-crds", "--values", valuesPath, "--namespace", namespace, "--kubeconfig", "/dev/null", "--version", chart.Version, chart.Release, cachedChartPath)
helmOut, err := util.RunCmd(ctx, "helm", args...)
if err != nil {
stderr := helmOut.Stderr.String()
lines := strings.Split(stderr, "\n")
for _, line := range lines {
if strings.HasPrefix(line, "Error:") {
err = fmt.Errorf("%s: %w", line, err)
}
}
return errors.Wrap(fmt.Errorf("could not run helm template: %w", err))
}
r.accumulatedOutput = helmOut.Stdout.String()
return nil
}
// cacheChart stores a cached copy of Chart in the chart subdirectory of path.
func cacheChart(ctx context.Context, path holos.InstancePath, chartDir string, chart Chart) error {
log := logger.FromContext(ctx)
cacheTemp, err := os.MkdirTemp(string(path), chartDir)
if err != nil {
return errors.Wrap(fmt.Errorf("could not make temp dir: %w", err))
}
defer util.Remove(ctx, cacheTemp)
chartName := chart.Name
if chart.Repository.Name != "" {
chartName = fmt.Sprintf("%s/%s", chart.Repository.Name, chart.Name)
}
helmOut, err := util.RunCmd(ctx, "helm", "pull", "--destination", cacheTemp, "--untar=true", "--version", chart.Version, chartName)
if err != nil {
return errors.Wrap(fmt.Errorf("could not run helm pull: %w", err))
}
log.Debug("helm pull", "stdout", helmOut.Stdout, "stderr", helmOut.Stderr)
cachePath := filepath.Join(string(path), chartDir)
if err := os.Rename(cacheTemp, cachePath); err != nil {
return errors.Wrap(fmt.Errorf("could not rename: %w", err))
}
log.InfoContext(ctx, "cached", "chart", chart.Name, "version", chart.Version, "path", cachePath)
return nil
}
func isNotExist(path string) bool {
_, err := os.Stat(path)
return os.IsNotExist(err)
}

View File

@@ -0,0 +1,21 @@
package v1alpha1
import (
"context"
"github.com/holos-run/holos"
)
const KubernetesObjectsKind = "KubernetesObjects"
// KubernetesObjects represents CUE output which directly provides Kubernetes api objects to holos.
type KubernetesObjects struct {
HolosComponent `json:",inline" yaml:",inline"`
}
// Render produces kubernetes api objects from the APIObjectMap
func (o *KubernetesObjects) Render(ctx context.Context, path holos.InstancePath) (*Result, error) {
result := Result{HolosComponent: o.HolosComponent}
result.addObjectMap(ctx, o.APIObjectMap)
return &result, nil
}

View File

@@ -0,0 +1,7 @@
package v1alpha1
// Kustomization holds the rendered flux kustomization api object content for git ops.
type Kustomization struct {
// KsContent is the yaml representation of the flux kustomization for gitops.
KsContent string `json:"ksContent,omitempty" yaml:"ksContent,omitempty"`
}

47
api/v1alpha1/kustomize.go Normal file
View File

@@ -0,0 +1,47 @@
package v1alpha1
import (
"context"
"github.com/holos-run/holos"
"github.com/holos-run/holos/pkg/errors"
"github.com/holos-run/holos/pkg/logger"
"github.com/holos-run/holos/pkg/util"
)
const KustomizeBuildKind = "KustomizeBuild"
// Kustomize represents resources necessary to execute a kustomize build.
// Intended for at least two use cases:
//
// 1. Process raw yaml file resources in a holos component directory.
// 2. Post process a HelmChart to inject istio, add custom labels, etc...
type Kustomize struct {
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
KustomizeFiles FileContentMap `json:"kustomizeFiles,omitempty" yaml:"kustomizeFiles,omitempty"`
// ResourcesFile is the file name used for api objects in kustomization.yaml
ResourcesFile string `json:"resourcesFile,omitempty" yaml:"resourcesFile,omitempty"`
}
// KustomizeBuild renders plain yaml files in the holos component directory using kubectl kustomize build.
type KustomizeBuild struct {
HolosComponent `json:",inline" yaml:",inline"`
}
// Render produces a Result by executing kubectl kustomize on the holos
// component path. Useful for processing raw yaml files.
func (kb *KustomizeBuild) Render(ctx context.Context, path holos.InstancePath) (*Result, error) {
log := logger.FromContext(ctx)
result := Result{HolosComponent: kb.HolosComponent}
// Run kustomize.
kOut, err := util.RunCmd(ctx, "kubectl", "kustomize", string(path))
if err != nil {
log.ErrorContext(ctx, kOut.Stderr.String())
return nil, errors.Wrap(err)
}
// Replace the accumulated output
result.accumulatedOutput = kOut.Stdout.String()
// Add CUE based api objects.
result.addObjectMap(ctx, kb.APIObjectMap)
return &result, nil
}

14
api/v1alpha1/objectmap.go Normal file
View File

@@ -0,0 +1,14 @@
package v1alpha1
// Label is an arbitrary unique identifier. Defined as a type for clarity and type checking.
type Label string
// Kind is a kubernetes api object kind. Defined as a type for clarity and type checking.
type Kind string
// APIObjectMap is the shape of marshalled api objects returned from cue to the
// holos cli. A map is used to improve the clarity of error messages from cue.
type APIObjectMap map[Kind]map[Label]string
// FileContentMap is a map of file names to file contents.
type FileContentMap map[string]string

View File

@@ -0,0 +1,15 @@
package v1alpha1
// ObjectMeta represents metadata of a holos component object. The fields are a
// copy of upstream kubernetes api machinery but are by holos objects distinct
// from kubernetes api objects.
type ObjectMeta struct {
// Name uniquely identifies the holos component instance and must be suitable as a file name.
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// Namespace confines a holos component to a single namespace via kustomize if set.
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
// Labels are not used but are copied from api machinery ObjectMeta for completeness.
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
// Annotations are not used but are copied from api machinery ObjectMeta for completeness.
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
}

22
api/v1alpha1/render.go Normal file
View File

@@ -0,0 +1,22 @@
package v1alpha1
import (
"context"
"github.com/holos-run/holos"
)
type Renderer interface {
GetKind() string
Render(ctx context.Context, path holos.InstancePath) (*Result, error)
}
// Render produces a Result representing the kubernetes api objects to
// configure. Each of the various holos component types, e.g. Helm, Kustomize,
// et al, should implement the Renderer interface. This process is best
// conceptualized as a data pipeline, for example a component may render a
// result by first calling helm template, then passing the result through
// kustomize, then mixing in overlay api objects.
func Render(ctx context.Context, r Renderer, path holos.InstancePath) (*Result, error) {
return r.Render(ctx, path)
}

138
api/v1alpha1/result.go Normal file
View File

@@ -0,0 +1,138 @@
package v1alpha1
import (
"context"
"fmt"
"os"
"path/filepath"
"slices"
"github.com/holos-run/holos/pkg/errors"
"github.com/holos-run/holos/pkg/logger"
"github.com/holos-run/holos/pkg/util"
)
// Result is the build result for display or writing. Holos components Render the Result as a data pipeline.
type Result struct {
HolosComponent
// accumulatedOutput accumulates rendered api objects.
accumulatedOutput string
}
func (r *Result) Name() string {
return r.Metadata.Name
}
func (r *Result) Filename(writeTo string, cluster string) string {
name := r.Metadata.Name
return filepath.Join(writeTo, "clusters", cluster, "components", name, name+".gen.yaml")
}
func (r *Result) KustomizationFilename(writeTo string, cluster string) string {
return filepath.Join(writeTo, "clusters", cluster, "holos", "components", r.Metadata.Name+"-kustomization.gen.yaml")
}
// AccumulatedOutput returns the accumulated rendered output.
func (r *Result) AccumulatedOutput() string {
return r.accumulatedOutput
}
// addObjectMap renders the provided APIObjectMap into the accumulated output.
func (r *Result) addObjectMap(ctx context.Context, objectMap APIObjectMap) {
log := logger.FromContext(ctx)
b := []byte(r.AccumulatedOutput())
kinds := make([]Kind, 0, len(objectMap))
// Sort the keys
for kind := range objectMap {
kinds = append(kinds, kind)
}
slices.Sort(kinds)
for _, kind := range kinds {
v := objectMap[kind]
// Sort the keys
names := make([]Label, 0, len(v))
for name := range v {
names = append(names, name)
}
slices.Sort(names)
for _, name := range names {
yamlString := v[name]
log.Debug(fmt.Sprintf("%s/%s", kind, name), "kind", kind, "name", name)
b = util.EnsureNewline(b)
header := fmt.Sprintf("---\n# Source: CUE apiObjects.%s.%s\n", kind, name)
b = append(b, []byte(header+yamlString)...)
b = util.EnsureNewline(b)
}
}
r.accumulatedOutput = string(b)
}
// kustomize replaces the accumulated output with the output of kustomize build
func (r *Result) kustomize(ctx context.Context) error {
log := logger.FromContext(ctx)
if r.ResourcesFile == "" {
log.DebugContext(ctx, "skipping kustomize: no resourcesFile")
return nil
}
if len(r.KustomizeFiles) < 1 {
log.DebugContext(ctx, "skipping kustomize: no kustomizeFiles")
return nil
}
tempDir, err := os.MkdirTemp("", "holos.kustomize")
if err != nil {
return errors.Wrap(err)
}
defer util.Remove(ctx, tempDir)
// Write the main api object resources file for kustomize.
target := filepath.Join(tempDir, r.ResourcesFile)
b := []byte(r.AccumulatedOutput())
b = util.EnsureNewline(b)
if err := os.WriteFile(target, b, 0644); err != nil {
return errors.Wrap(fmt.Errorf("could not write resources: %w", err))
}
log.DebugContext(ctx, "wrote: "+target, "op", "write", "path", target, "bytes", len(b))
// Write the kustomization tree, kustomization.yaml must be in this map for kustomize to work.
for file, content := range r.KustomizeFiles {
target := filepath.Join(tempDir, file)
if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil {
return errors.Wrap(err)
}
b := []byte(content)
b = util.EnsureNewline(b)
if err := os.WriteFile(target, b, 0644); err != nil {
return errors.Wrap(fmt.Errorf("could not write: %w", err))
}
log.DebugContext(ctx, "wrote: "+target, "op", "write", "path", target, "bytes", len(b))
}
// Run kustomize.
kOut, err := util.RunCmd(ctx, "kubectl", "kustomize", tempDir)
if err != nil {
log.ErrorContext(ctx, kOut.Stderr.String())
return errors.Wrap(err)
}
// Replace the accumulated output
r.accumulatedOutput = kOut.Stdout.String()
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)
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, os.FileMode(0775)); err != nil {
log.WarnContext(ctx, "could not mkdir", "path", dir, "err", err)
return errors.Wrap(err)
}
// Write the kube api objects
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)
}
log.DebugContext(ctx, "out: wrote "+path, "action", "write", "path", path, "status", "ok")
return nil
}

10
api/v1alpha1/typemeta.go Normal file
View File

@@ -0,0 +1,10 @@
package v1alpha1
type TypeMeta struct {
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
}
func (tm *TypeMeta) GetKind() string {
return tm.Kind
}

24
buf.gen.yaml Normal file
View File

@@ -0,0 +1,24 @@
# Generates gRPC and ConnectRPC bindings for Go and TypeScript
#
# Note: protoc-gen-connect-query is the primary method of wiring up the React
# frontend.
version: v1
plugins:
- plugin: go
out: service/gen
opt: paths=source_relative
- plugin: connect-go
out: service/gen
opt: paths=source_relative
- plugin: es
out: internal/frontend/holos/gen
opt:
- target=ts
- plugin: connect-es
out: internal/frontend/holos/gen
opt:
- target=ts
- plugin: connect-query
out: internal/frontend/holos/gen
opt:
- target=ts

8
buf.lock Normal file
View File

@@ -0,0 +1,8 @@
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: bufbuild
repository: protovalidate
commit: b983156c5e994cc9892e0ce3e64e17e0
digest: shake256:fb47a62989d38c2529bcc5cd86ded43d800eb84cee82b42b9e8a9e815d4ee8134a0fb9d0ce8299b27c2d2bbb7d6ade0c4ad5a8a4d467e1e2c7ca619ae9f634e2

3
buf.work.yaml Normal file
View File

@@ -0,0 +1,3 @@
version: v1
directories:
- service

View File

@@ -1,28 +1,10 @@
package main
import (
"context"
"errors"
"github.com/holos-run/holos/pkg/cli"
"github.com/holos-run/holos/pkg/config"
"github.com/holos-run/holos/pkg/wrapper"
"log/slog"
"os"
)
func main() {
cfg := config.New()
slog.SetDefault(cfg.Logger())
ctx := context.Background()
if err := cli.New(cfg).ExecuteContext(ctx); err != nil {
log := cfg.NewTopLevelLogger()
var errAt *wrapper.ErrorAt
const msg = "could not execute"
if ok := errors.As(err, &errAt); ok {
log.ErrorContext(ctx, msg, "err", errAt.Unwrap(), "loc", errAt.Source.Loc())
} else {
log.ErrorContext(ctx, msg, "err", err)
}
os.Exit(1)
}
os.Exit(cli.MakeMain()())
}

20
cmd/holos/main_test.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"github.com/holos-run/holos/pkg/cli"
"github.com/rogpeppe/go-internal/testscript"
"os"
"testing"
)
func TestMain(m *testing.M) {
os.Exit(testscript.RunMain(m, map[string]func() int{
"holos": cli.MakeMain(),
}))
}
func TestGetSecrets(t *testing.T) {
testscript.Run(t, testscript.Params{
Dir: "testdata",
})
}

31
cmd/holos/testdata/constraints.txt vendored Normal file
View File

@@ -0,0 +1,31 @@
# Want support for intermediary constraints
exec holos build ./foo/... --log-level debug
stdout '^bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b$'
-- cue.mod --
package holos
-- foo/constraints.cue --
package holos
metadata: name: "jeff"
-- foo/bar/bar.cue --
package holos
spec: components: KubernetesObjectsList: [
#KubernetesObjects & {
apiObjectMap: foo: bar: "bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b"
}
]
-- schema.cue --
package holos
_cluster: string @tag(cluster, string)
#KubernetesObjects: {
apiVersion: "holos.run/v1alpha1"
kind: "KubernetesObjects"
apiObjectMap: {...}
}
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"

View File

@@ -0,0 +1,17 @@
# Want cue errors to show files and lines
! exec holos build .
stderr 'apiObjectMap.foo.bar: cannot convert incomplete value'
stderr '/component.cue:\d+:\d+$'
-- cue.mod --
package holos
-- component.cue --
package holos
_cluster: string @tag(cluster, string)
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"
spec: components: KubernetesObjectsList: [{apiObjectMap: foo: bar: _baz}]
_baz: string

View File

@@ -0,0 +1,58 @@
# Want kube api objects in the apiObjects output.
exec holos build .
stdout '^kind: SecretStore$'
stdout '# Source: CUE apiObjects.SecretStore.default'
-- cue.mod --
package holos
-- component.cue --
package holos
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"
spec: components: KubernetesObjectsList: [{apiObjectMap: #APIObjects.apiObjectMap}]
_cluster: string @tag(cluster, string)
#SecretStore: {
kind: string
metadata: name: string
}
#APIObjects: {
apiObjects: {
SecretStore: {
default: #SecretStore & { metadata: name: "default" }
}
}
}
-- schema.cue --
package holos
// #APIObjects is the output type for api objects produced by cue. A map is used to aid debugging and clarity.
import "encoding/yaml"
#APIObjects: {
// apiObjects holds each the api objects produced by cue.
apiObjects: {
[Kind=_]: {
[Name=_]: {
kind: Kind
metadata: name: Name
}
}
}
// apiObjectsContent holds the marshalled representation of apiObjects
apiObjectMap: {
for kind, v in apiObjects {
"\(kind)": {
for name, obj in v {
"\(name)": yaml.Marshal(obj)
}
}
}
}
}

View File

@@ -0,0 +1,59 @@
# Want kube api objects in the apiObjects output.
exec holos build .
stdout '^kind: SecretStore$'
stdout '# Source: CUE apiObjects.SecretStore.default'
stderr 'skipping helm: no chart name specified'
-- cue.mod --
package holos
-- component.cue --
package holos
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"
spec: components: HelmChartList: [{apiObjectMap: #APIObjects.apiObjectMap}]
_cluster: string @tag(cluster, string)
#SecretStore: {
kind: string
metadata: name: string
}
#APIObjects: {
apiObjects: {
SecretStore: {
default: #SecretStore & { metadata: name: "default" }
}
}
}
-- schema.cue --
package holos
// #APIObjects is the output type for api objects produced by cue. A map is used to aid debugging and clarity.
import "encoding/yaml"
#APIObjects: {
// apiObjects holds each the api objects produced by cue.
apiObjects: {
[Kind=_]: {
[Name=_]: {
kind: Kind
metadata: name: Name
}
}
}
// apiObjectsContent holds the marshalled representation of apiObjects
apiObjectMap: {
for kind, v in apiObjects {
"\(kind)": {
for name, obj in v {
"\(name)": yaml.Marshal(obj)
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
# Want api object kind and name in errors
! exec holos build .
stderr 'apiObjects.secretstore.default.foo: field not allowed'
-- cue.mod --
package holos
-- component.cue --
package holos
apiVersion: "holos.run/v1alpha1"
kind: "KubernetesObjects"
cluster: string @tag(cluster, string)
#SecretStore: {
metadata: name: string
}
apiObjects: {
secretstore: {
default: #SecretStore & { foo: "not allowed" }
}
}

View File

@@ -0,0 +1,286 @@
# Want helm errors to show up
! exec holos build .
stderr 'Error: execution error at \(zitadel/templates/secret_zitadel-masterkey.yaml:2:4\): Either set .Values.zitadel.masterkey xor .Values.zitadel.masterkeySecretName'
-- cue.mod --
package holos
-- zitadel.cue --
package holos
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"
spec: components: HelmChartList: [_HelmChart]
_cluster: string @tag(cluster, string)
_HelmChart: {
apiVersion: "holos.run/v1alpha1"
kind: "HelmChart"
metadata: name: "zitadel"
namespace: "zitadel"
chart: {
name: "zitadel"
version: "7.9.0"
release: name
repository: {
name: "zitadel"
url: "https://charts.zitadel.com"
}
}
}
-- vendor/zitadel/templates/secret_zitadel-masterkey.yaml --
{{- if (or (and .Values.zitadel.masterkey .Values.zitadel.masterkeySecretName) (and (not .Values.zitadel.masterkey) (not .Values.zitadel.masterkeySecretName)) ) }}
{{- fail "Either set .Values.zitadel.masterkey xor .Values.zitadel.masterkeySecretName" }}
{{- end }}
{{- if .Values.zitadel.masterkey -}}
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: zitadel-masterkey
{{- with .Values.zitadel.masterkeyAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "zitadel.labels" . | nindent 4 }}
stringData:
masterkey: {{ .Values.zitadel.masterkey }}
{{- end -}}
-- vendor/zitadel/Chart.yaml --
apiVersion: v2
appVersion: v2.46.0
description: A Helm chart for ZITADEL
icon: https://zitadel.com/zitadel-logo-dark.svg
kubeVersion: '>= 1.21.0-0'
maintainers:
- email: support@zitadel.com
name: zitadel
url: https://zitadel.com
name: zitadel
type: application
version: 7.9.0
-- vendor/zitadel/values.yaml --
# Default values for zitadel.
zitadel:
# The ZITADEL config under configmapConfig is written to a Kubernetes ConfigMap
# See all defaults here:
# https://github.com/zitadel/zitadel/blob/main/cmd/defaults.yaml
configmapConfig:
ExternalSecure: true
Machine:
Identification:
Hostname:
Enabled: true
Webhook:
Enabled: false
# The ZITADEL config under secretConfig is written to a Kubernetes Secret
# See all defaults here:
# https://github.com/zitadel/zitadel/blob/main/cmd/defaults.yaml
secretConfig:
# Annotations set on secretConfig secret
secretConfigAnnotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation
helm.sh/hook-weight: "0"
# Reference the name of a secret that contains ZITADEL configuration.
configSecretName:
# The key under which the ZITADEL configuration is located in the secret.
configSecretKey: config-yaml
# ZITADEL uses the masterkey for symmetric encryption.
# You can generate it for example with tr -dc A-Za-z0-9 </dev/urandom | head -c 32
masterkey: ""
# Reference the name of the secret that contains the masterkey. The key should be named "masterkey".
# Note: Either zitadel.masterkey or zitadel.masterkeySecretName must be set
masterkeySecretName: ""
# Annotations set on masterkey secret
masterkeyAnnotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation
helm.sh/hook-weight: "0"
# The CA Certificate needed for establishing secure database connections
dbSslCaCrt: ""
# The Secret containing the CA certificate at key ca.crt needed for establishing secure database connections
dbSslCaCrtSecret: ""
# The db admins secret containing the client certificate and key at tls.crt and tls.key needed for establishing secure database connections
dbSslAdminCrtSecret: ""
# The db users secret containing the client certificate and key at tls.crt and tls.key needed for establishing secure database connections
dbSslUserCrtSecret: ""
# Generate a self-signed certificate using an init container
# This will also mount the generated files to /etc/tls/ so that you can reference them in the pod.
# E.G. KeyPath: /etc/tls/tls.key CertPath: /etc/tls/tls.crt
# By default, the SAN DNS names include, localhost, the POD IP address and the POD name. You may include one more by using additionalDnsName like "my.zitadel.fqdn".
selfSignedCert:
enabled: false
additionalDnsName:
replicaCount: 3
image:
repository: ghcr.io/zitadel/zitadel
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
chownImage:
repository: alpine
pullPolicy: IfNotPresent
tag: "3.19"
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
# Annotations to add to the deployment
annotations: {}
# Annotations to add to the configMap
configMap:
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation
helm.sh/hook-weight: "0"
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation
helm.sh/hook-weight: "0"
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podAdditionalLabels: {}
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
securityContext: {}
# Additional environment variables
env:
[]
# - name: ZITADEL_DATABASE_POSTGRES_HOST
# valueFrom:
# secretKeyRef:
# name: postgres-pguser-postgres
# key: host
service:
type: ClusterIP
# If service type is "ClusterIP", this can optionally be set to a fixed IP address.
clusterIP: ""
port: 8080
protocol: http2
annotations: {}
scheme: HTTP
ingress:
enabled: false
className: ""
annotations: {}
hosts:
- host: localhost
paths:
- path: /
pathType: Prefix
tls: []
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
topologySpreadConstraints: []
initJob:
# Once ZITADEL is installed, the initJob can be disabled.
enabled: true
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation
helm.sh/hook-weight: "1"
resources: {}
backoffLimit: 5
activeDeadlineSeconds: 300
extraContainers: []
podAnnotations: {}
# Available init commands :
# "": initialize ZITADEL instance (without skip anything)
# database: initialize only the database
# grant: set ALL grant to user
# user: initialize only the database user
# zitadel: initialize ZITADEL internals (skip "create user" and "create database")
command: ""
setupJob:
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation
helm.sh/hook-weight: "2"
resources: {}
activeDeadlineSeconds: 300
extraContainers: []
podAnnotations: {}
additionalArgs:
- "--init-projections=true"
machinekeyWriter:
image:
repository: bitnami/kubectl
tag: ""
resources: {}
readinessProbe:
enabled: true
initialDelaySeconds: 0
periodSeconds: 5
failureThreshold: 3
livenessProbe:
enabled: true
initialDelaySeconds: 0
periodSeconds: 5
failureThreshold: 3
startupProbe:
enabled: true
periodSeconds: 1
failureThreshold: 30
metrics:
enabled: false
serviceMonitor:
# If true, the chart creates a ServiceMonitor that is compatible with Prometheus Operator
# https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.ServiceMonitor.
# The Prometheus community Helm chart installs this operator
# https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack#kube-prometheus-stack
enabled: false
honorLabels: false
honorTimestamps: true
pdb:
enabled: false
# these values are used for the PDB and are mutally exclusive
minAvailable: 1
# maxUnavailable: 1
annotations: {}

View File

@@ -0,0 +1,36 @@
# Kustomize is a supported holos component kind
exec holos render --cluster-name=mycluster . --log-level=debug
# Want generated output
cmp want.yaml deploy/clusters/mycluster/components/kstest/kstest.gen.yaml
-- cue.mod --
package holos
-- component.cue --
package holos
_cluster: string @tag(cluster, string)
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"
spec: components: KustomizeBuildList: [{metadata: name: "kstest"}]
-- kustomization.yaml --
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mynamespace
resources:
- serviceaccount.yaml
-- serviceaccount.yaml --
apiVersion: v1
kind: ServiceAccount
metadata:
name: test
-- want.yaml --
apiVersion: v1
kind: ServiceAccount
metadata:
name: test
namespace: mynamespace

View File

@@ -0,0 +1,14 @@
# https://github.com/holos-run/holos/issues/72
# Want holos to fail on unknown fields to catch typos and aid refactors
! exec holos build .
stderr 'unknown field \\"TypoKubernetesObjectsList\\"'
-- cue.mod --
package holos
-- component.cue --
package holos
_cluster: string @tag(cluster, string)
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"
spec: components: TypoKubernetesObjectsList: []

5
cmd/holos/testdata/version.txt vendored Normal file
View File

@@ -0,0 +1,5 @@
exec holos --version
# want version with no v on stdout
stdout -count=1 '^\d+\.\d+\.\d+$'
# want nothing on stderr
! stderr .

View File

@@ -0,0 +1,37 @@
package holos
import ap "security.istio.io/authorizationpolicy/v1"
// #AuthPolicyRules represents AuthorizationPolicy rules for hosts that need specialized treatment. Entries in this struct are exclused from the blank ingressauth AuthorizationPolicy governing the ingressgateway and included in a spcialized policy
#AuthPolicyRules: {
// AuthProxySpec represents the identity provider configuration
AuthProxySpec: #AuthProxySpec & #Platform.authproxy
// Hosts are hosts that need specialized treatment
hosts: {
[Name=_]: {
// name is the fully qualifed hostname, a Host: header value.
name: Name
// slug is the resource name prefix
slug: string
// Refer to https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule
spec: ap.#AuthorizationPolicySpec & {
action: "CUSTOM"
provider: name: AuthProxySpec.provider
selector: matchLabels: istio: "ingressgateway"
}
}
}
objects: #APIObjects & {
for Host in hosts {
apiObjects: {
AuthorizationPolicy: "\(Host.slug)-custom": {
metadata: namespace: "istio-ingress"
metadata: name: "\(Host.slug)-custom"
spec: Host.spec
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
// 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"
// Order is a type to represent an Order with an ACME server
#Order: {
// 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: "acme.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: "Order"
metadata: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
spec!: #OrderSpec
}
#OrderSpec: {
// CommonName is the common name as specified on the DER encoded
// CSR. If specified, this value must also be present in
// `dnsNames` or `ipAddresses`. This field must match the
// corresponding field on the DER encoded CSR.
commonName?: string
// DNSNames is a list of DNS names that should be included as part
// of the Order validation process. This field must match the
// corresponding field on the DER encoded CSR.
dnsNames?: [...string]
// Duration is the duration for the not after date for the
// requested certificate. this is set on order creation as pe the
// ACME spec.
duration?: string
// IPAddresses is a list of IP addresses that should be included
// as part of the Order validation process. This field must match
// the corresponding field on the DER encoded CSR.
ipAddresses?: [...string]
// IssuerRef references a properly configured ACME-type Issuer
// which should be used to create this Order. If the Issuer does
// not exist, processing will be retried. If the Issuer is not an
// 'ACME' Issuer, an error will be returned and the Order will be
// marked as failed.
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
}
// Certificate signing request bytes in DER encoding. This will be
// used when finalizing the order. This field must be set on the
// order.
request: string
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,189 @@
// 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-platform-argocd/prod-platform-argocd.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,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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,123 @@
// 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-istio-base/prod-mesh-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.
failStrategy?: "FAIL_CLOSE" | "FAIL_OPEN"
// The pull behaviour to be applied when fetching Wasm module by
// either OCI image or http/https.
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.
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.
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}$)"
// Optional.
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
}
// Specifies the type of Wasm Extension to be used.
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.
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
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,167 @@
// 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"
// ACRAccessToken returns a Azure Container Registry token
// that can be used for pushing/pulling images.
// Note: by default it will return an ACR Refresh Token with full
// access
// (depending on the identity).
// This can be scoped down to the repository level using
// .spec.scope.
// In case scope is defined it will return an ACR Access Token.
//
//
// See docs:
// https://github.com/Azure/acr/blob/main/docs/AAD-OAuth.md
#ACRAccessToken: {
// 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: "generators.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: "ACRAccessToken"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ACRAccessTokenSpec defines how to generate the access token
// e.g. how to authenticate and which registry to use.
// see:
// https://github.com/Azure/acr/blob/main/docs/AAD-OAuth.md#overview
spec!: #ACRAccessTokenSpec
}
// ACRAccessTokenSpec defines how to generate the access token
// e.g. how to authenticate and which registry to use.
// see:
// https://github.com/Azure/acr/blob/main/docs/AAD-OAuth.md#overview
#ACRAccessTokenSpec: {
auth: {
managedIdentity?: {
// If multiple Managed Identity is assigned to the pod, you can
// select the one to be used
identityId?: string
}
servicePrincipal?: {
// Configuration used to authenticate with Azure using static
// credentials stored in a Kind=Secret.
secretRef: {
// The Azure clientId of the service principle used for
// authentication.
clientId?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// The Azure ClientSecret of the service principle used for
// authentication.
clientSecret?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
}
workloadIdentity?: {
// ServiceAccountRef specified the service account
// that should be used when authenticating with WorkloadIdentity.
serviceAccountRef?: {
// Audience specifies the `aud` claim for the service account
// token
// If the service account uses a well-known annotation for e.g.
// IRSA or GCP Workload Identity
// then this audiences will be appended to the list
audiences?: [...string]
// The name of the ServiceAccount resource being referred to.
name: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
}
// EnvironmentType specifies the Azure cloud environment endpoints
// to use for
// connecting and authenticating with Azure. By default it points
// to the public cloud AAD endpoint.
// The following endpoints are available, also see here:
// https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152
// PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
environmentType?: "PublicCloud" | "USGovernmentCloud" | "ChinaCloud" | "GermanCloud" | *"PublicCloud"
// the domain name of the ACR registry
// e.g. foobarexample.azurecr.io
registry: string
// Define the scope for the access token, e.g. pull/push access
// for a repository.
// if not provided it will return a refresh token that has full
// scope.
// Note: you need to pin it down to the repository level, there is
// no wildcard available.
//
//
// examples:
// repository:my-repository:pull,push
// repository:my-repository:pull
//
//
// see docs for details:
// https://docs.docker.com/registry/spec/auth/scope/
scope?: string
// TenantID configures the Azure Tenant to send requests to.
// Required for ServicePrincipal auth type.
tenantId?: string
}

View File

@@ -0,0 +1,142 @@
// 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"
// ECRAuthorizationTokenSpec uses the GetAuthorizationToken API to
// retrieve an
// authorization token.
// The authorization token is valid for 12 hours.
// The authorizationToken returned is a base64 encoded string that
// can be decoded
// and used in a docker login command to authenticate to a
// registry.
// For more information, see Registry authentication
// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html#registry_auth)
// in the Amazon Elastic Container Registry User Guide.
#ECRAuthorizationToken: {
// 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: "generators.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: "ECRAuthorizationToken"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
spec!: #ECRAuthorizationTokenSpec
}
#ECRAuthorizationTokenSpec: {
// Auth defines how to authenticate with AWS
auth?: {
jwt?: {
// A reference to a ServiceAccount resource.
serviceAccountRef?: {
// Audience specifies the `aud` claim for the service account
// token
// If the service account uses a well-known annotation for e.g.
// IRSA or GCP Workload Identity
// then this audiences will be appended to the list
audiences?: [...string]
// The name of the ServiceAccount resource being referred to.
name: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// AWSAuthSecretRef holds secret references for AWS credentials
// both AccessKeyID and SecretAccessKey must be defined in order
// to properly authenticate.
secretRef?: {
// The AccessKeyID is used for authentication
accessKeyIDSecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// The SecretAccessKey is used for authentication
secretAccessKeySecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// The SessionToken used for authentication
// This must be defined if AccessKeyID and SecretAccessKey are
// temporary credentials
// see:
// https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
sessionTokenSecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
}
// Region specifies the region to operate in.
region: string
// You can assume a role before making calls to the
// desired AWS service.
role?: string
}

View File

@@ -0,0 +1,62 @@
// 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"
// Fake generator is used for testing. It lets you define
// a static set of credentials that is always returned.
#Fake: {
// 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: "generators.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: "Fake"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// FakeSpec contains the static data.
spec!: #FakeSpec
}
// FakeSpec contains the static data.
#FakeSpec: {
// Used to select the correct ESO controller (think:
// ingress.ingressClassName)
// The ESO controller is instantiated with a specific controller
// name and filters VDS based on this property
controller?: string
// Data defines the static data returned
// by this generator.
data?: {
[string]: string
}
}

View File

@@ -0,0 +1,93 @@
// 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"
// GCRAccessToken generates an GCP access token
// that can be used to authenticate with GCR.
#GCRAccessToken: {
// 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: "generators.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: "GCRAccessToken"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
spec!: #GCRAccessTokenSpec
}
#GCRAccessTokenSpec: {
// Auth defines the means for authenticating with GCP
auth: {
secretRef?: {
// The SecretAccessKey is used for authentication
secretAccessKeySecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
workloadIdentity?: {
clusterLocation: string
clusterName: string
clusterProjectID?: string
// A reference to a ServiceAccount resource.
serviceAccountRef: {
// Audience specifies the `aud` claim for the service account
// token
// If the service account uses a well-known annotation for e.g.
// IRSA or GCP Workload Identity
// then this audiences will be appended to the list
audiences?: [...string]
// The name of the ServiceAccount resource being referred to.
name: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
}
// ProjectID defines which project to use to authenticate with
projectID: string
}

View File

@@ -0,0 +1,77 @@
// 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"
// Password generates a random password based on the
// configuration parameters in spec.
// You can specify the length, characterset and other attributes.
#Password: {
// 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: "generators.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: "Password"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// PasswordSpec controls the behavior of the password generator.
spec!: #PasswordSpec
}
// PasswordSpec controls the behavior of the password generator.
#PasswordSpec: {
// set AllowRepeat to true to allow repeating characters.
allowRepeat: bool | *false
// Digits specifies the number of digits in the generated
// password. If omitted it defaults to 25% of the length of the
// password
digits?: int
// Length of the password to be generated.
// Defaults to 24
length: int | *24
// Set NoUpper to disable uppercase characters
noUpper: bool | *false
// SymbolCharacters specifies the special characters that should
// be used
// in the generated password.
symbolCharacters?: string
// Symbols specifies the number of symbol characters in the
// generated
// password. If omitted it defaults to 25% of the length of the
// password
symbols?: int
}

View File

@@ -0,0 +1,609 @@
// 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"
#VaultDynamicSecret: {
// 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: "generators.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: "VaultDynamicSecret"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
spec!: #VaultDynamicSecretSpec
}
#VaultDynamicSecretSpec: {
// Used to select the correct ESO controller (think:
// ingress.ingressClassName)
// The ESO controller is instantiated with a specific controller
// name and filters VDS based on this property
controller?: string
// Vault API method to use (GET/POST/other)
method?: string
// Parameters to pass to Vault write (for non-GET methods)
parameters?: _
// Vault path to obtain the dynamic secret from
path: string
// Vault provider common spec
provider: {
// Auth configures how secret-manager authenticates with the Vault
// server.
auth: {
// AppRole authenticates with Vault using the App Role auth
// mechanism,
// with the role and secret stored in a Kubernetes Secret
// resource.
appRole?: {
// Path where the App Role authentication backend is mounted
// in Vault, e.g: "approle"
path: string | *"approle"
// RoleID configured in the App Role authentication backend when
// setting
// up the authentication backend in Vault.
roleId?: string
// Reference to a key in a Secret that contains the App Role ID
// used
// to authenticate with Vault.
// The `key` field must be specified and denotes which entry
// within the Secret
// resource is used as the app role id.
roleRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// Reference to a key in a Secret that contains the App Role
// secret used
// to authenticate with Vault.
// The `key` field must be specified and denotes which entry
// within the Secret
// resource is used as the app role secret.
secretRef: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// Cert authenticates with TLS Certificates by passing client
// certificate, private key and ca certificate
// Cert authentication method
cert?: {
// ClientCert is a certificate to authenticate using the Cert
// Vault
// authentication method
clientCert?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// SecretRef to a key in a Secret resource containing client
// private key to
// authenticate with Vault using the Cert authentication method
secretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// Iam authenticates with vault by passing a special AWS request
// signed with AWS IAM credentials
// AWS IAM authentication method
iam?: {
// AWS External ID set on assumed IAM roles
externalID?: string
jwt?: {
// A reference to a ServiceAccount resource.
serviceAccountRef?: {
// Audience specifies the `aud` claim for the service account
// token
// If the service account uses a well-known annotation for e.g.
// IRSA or GCP Workload Identity
// then this audiences will be appended to the list
audiences?: [...string]
// The name of the ServiceAccount resource being referred to.
name: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// Path where the AWS auth method is enabled in Vault, e.g: "aws"
path?: string
// AWS region
region?: string
// This is the AWS role to be assumed before talking to vault
role?: string
// Specify credentials in a Secret object
secretRef?: {
// The AccessKeyID is used for authentication
accessKeyIDSecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// The SecretAccessKey is used for authentication
secretAccessKeySecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// The SessionToken used for authentication
// This must be defined if AccessKeyID and SecretAccessKey are
// temporary credentials
// see:
// https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
sessionTokenSecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// X-Vault-AWS-IAM-Server-ID is an additional header used by Vault
// IAM auth method to mitigate against different types of replay
// attacks. More details here:
// https://developer.hashicorp.com/vault/docs/auth/aws
vaultAwsIamServerID?: string
// Vault Role. In vault, a role describes an identity with a set
// of permissions, groups, or policies you want to attach a user
// of the secrets engine
vaultRole: string
}
// Jwt authenticates with Vault by passing role and JWT token
// using the
// JWT/OIDC authentication method
jwt?: {
// Optional ServiceAccountToken specifies the Kubernetes service
// account for which to request
// a token for with the `TokenRequest` API.
kubernetesServiceAccountToken?: {
// Optional audiences field that will be used to request a
// temporary Kubernetes service
// account token for the service account referenced by
// `serviceAccountRef`.
// Defaults to a single audience `vault` it not specified.
// Deprecated: use serviceAccountRef.Audiences instead
audiences?: [...string]
// Optional expiration time in seconds that will be used to
// request a temporary
// Kubernetes service account token for the service account
// referenced by
// `serviceAccountRef`.
// Deprecated: this will be removed in the future.
// Defaults to 10 minutes.
expirationSeconds?: int
// Service account field containing the name of a kubernetes
// ServiceAccount.
serviceAccountRef: {
// Audience specifies the `aud` claim for the service account
// token
// If the service account uses a well-known annotation for e.g.
// IRSA or GCP Workload Identity
// then this audiences will be appended to the list
audiences?: [...string]
// The name of the ServiceAccount resource being referred to.
name: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// Path where the JWT authentication backend is mounted
// in Vault, e.g: "jwt"
path: string | *"jwt"
// Role is a JWT role to authenticate using the JWT/OIDC Vault
// authentication method
role?: string
// Optional SecretRef that refers to a key in a Secret resource
// containing JWT token to
// authenticate with Vault using the JWT/OIDC authentication
// method.
secretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// Kubernetes authenticates with Vault by passing the
// ServiceAccount
// token stored in the named Secret resource to the Vault server.
kubernetes?: {
// Path where the Kubernetes authentication backend is mounted in
// Vault, e.g:
// "kubernetes"
mountPath: string | *"kubernetes"
// A required field containing the Vault Role to assume. A Role
// binds a
// Kubernetes ServiceAccount with a set of Vault policies.
role: string
// Optional secret field containing a Kubernetes ServiceAccount
// JWT used
// for authenticating with Vault. If a name is specified without a
// key,
// `token` is the default. If one is not specified, the one bound
// to
// the controller will be used.
secretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// Optional service account field containing the name of a
// kubernetes ServiceAccount.
// If the service account is specified, the service account secret
// token JWT will be used
// for authenticating with Vault. If the service account selector
// is not supplied,
// the secretRef will be used instead.
serviceAccountRef?: {
// Audience specifies the `aud` claim for the service account
// token
// If the service account uses a well-known annotation for e.g.
// IRSA or GCP Workload Identity
// then this audiences will be appended to the list
audiences?: [...string]
// The name of the ServiceAccount resource being referred to.
name: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// Ldap authenticates with Vault by passing username/password pair
// using
// the LDAP authentication method
ldap?: {
// Path where the LDAP authentication backend is mounted
// in Vault, e.g: "ldap"
path: string | *"ldap"
// SecretRef to a key in a Secret resource containing password for
// the LDAP
// user used to authenticate with Vault using the LDAP
// authentication
// method
secretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// Username is a LDAP user name used to authenticate using the
// LDAP Vault
// authentication method
username: string
}
// TokenSecretRef authenticates with Vault by presenting a token.
tokenSecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// UserPass authenticates with Vault by passing username/password
// pair
userPass?: {
// Path where the UserPassword authentication backend is mounted
// in Vault, e.g: "user"
path: string | *"user"
// SecretRef to a key in a Secret resource containing password for
// the
// user used to authenticate with Vault using the UserPass
// authentication
// method
secretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// Username is a user name used to authenticate using the UserPass
// Vault
// authentication method
username: string
}
}
// PEM encoded CA bundle used to validate Vault server
// certificate. Only used
// if the Server URL is using HTTPS protocol. This parameter is
// ignored for
// plain HTTP protocol connection. If not set the system root
// certificates
// are used to validate the TLS connection.
caBundle?: string
// The provider for the CA bundle to use to validate Vault server
// certificate.
caProvider?: {
// The key where the CA certificate can be found in the Secret or
// ConfigMap.
key?: string
// The name of the object located at the provider type.
name: string
// The namespace the Provider type is in.
// Can only be defined when used in a ClusterSecretStore.
namespace?: string
// The type of provider to use such as "Secret", or "ConfigMap".
type: "Secret" | "ConfigMap"
}
// ForwardInconsistent tells Vault to forward read-after-write
// requests to the Vault
// leader instead of simply retrying within a loop. This can
// increase performance if
// the option is enabled serverside.
// https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header
forwardInconsistent?: bool
// Name of the vault namespace. Namespaces is a set of features
// within Vault Enterprise that allows
// Vault environments to support Secure Multi-tenancy. e.g: "ns1".
// More about namespaces can be found here
// https://www.vaultproject.io/docs/enterprise/namespaces
namespace?: string
// Path is the mount path of the Vault KV backend endpoint, e.g:
// "secret". The v2 KV secret engine version specific "/data" path
// suffix
// for fetching secrets from Vault is optional and will be
// appended
// if not present in specified path.
path?: string
// ReadYourWrites ensures isolated read-after-write semantics by
// providing discovered cluster replication states in each
// request.
// More information about eventual consistency in Vault can be
// found here
// https://www.vaultproject.io/docs/enterprise/consistency
readYourWrites?: bool
// Server is the connection address for the Vault server, e.g:
// "https://vault.example.com:8200".
server: string
// The configuration used for client side related TLS
// communication, when the Vault server
// requires mutual authentication. Only used if the Server URL is
// using HTTPS protocol.
// This parameter is ignored for plain HTTP protocol connection.
// It's worth noting this configuration is different from the "TLS
// certificates auth method",
// which is available under the `auth.cert` section.
tls?: {
// CertSecretRef is a certificate added to the transport layer
// when communicating with the Vault server.
// If no key for the Secret is specified, external-secret will
// default to 'tls.crt'.
certSecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
// KeySecretRef to a key in a Secret resource containing client
// private key
// added to the transport layer when communicating with the Vault
// server.
// If no key for the Secret is specified, external-secret will
// default to 'tls.key'.
keySecretRef?: {
// 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
// The name of the Secret resource being referred to.
name?: string
// Namespace of the resource being referred to. Ignored if
// referent is not cluster-scoped. cluster-scoped defaults
// to the namespace of the referent.
namespace?: string
}
}
// Version is the Vault KV secret engine version. This can be
// either "v1" or
// "v2". Version defaults to "v2".
version?: "v1" | "v2" | *"v2"
}
// Result type defines which data is returned from the generator.
// By default it is the "data" section of the Vault API response.
// When using e.g. /auth/token/create the "data" section is empty
// but
// the "auth" section contains the generated token.
// Please refer to the vault docs regarding the result data
// structure.
resultType?: "Data" | "Auth" | *"Data"
}

View File

@@ -0,0 +1,26 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// BuildPlan is the primary interface between CUE and the Holos cli.
#BuildPlan: {
#TypeMeta
// Metadata represents the holos component name
metadata?: #ObjectMeta @go(Metadata)
spec?: #BuildPlanSpec @go(Spec)
}
#BuildPlanSpec: {
disabled?: bool @go(Disabled)
components?: #BuildPlanComponents @go(Components)
}
#BuildPlanComponents: {
helmChartList?: [...#HelmChart] @go(HelmChartList,[]HelmChart)
kubernetesObjectsList?: [...#KubernetesObjects] @go(KubernetesObjectsList,[]KubernetesObjects)
kustomizeBuildList?: [...#KustomizeBuild] @go(KustomizeBuildList,[]KustomizeBuild)
resources?: {[string]: #KubernetesObjects} @go(Resources,map[string]KubernetesObjects)
}

View File

@@ -0,0 +1,24 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// HolosComponent defines the fields common to all holos component kinds including the Render Result.
#HolosComponent: {
#TypeMeta
// Metadata represents the holos component name
metadata?: #ObjectMeta @go(Metadata)
// APIObjectMap holds the marshalled representation of api objects. Think of
// these as resources overlaid at the back of the render pipeline.
apiObjectMap?: #APIObjectMap @go(APIObjectMap)
#Kustomization
#Kustomize
// Skip causes holos to take no action regarding the component.
Skip: bool
}

View File

@@ -0,0 +1,15 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#APIVersion: "holos.run/v1alpha1"
#BuildPlanKind: "BuildPlan"
#HelmChartKind: "HelmChart"
// ChartDir is the directory name created in the holos component directory to cache a chart.
#ChartDir: "vendor"
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
#ResourcesFile: "resources.yaml"

View File

@@ -0,0 +1,6 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
// Package v1alpha1 defines the api boundary between CUE and Holos.
package v1alpha1

View File

@@ -0,0 +1,28 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// A HelmChart represents a helm command to provide chart values in order to render kubernetes api objects.
#HelmChart: {
#HolosComponent
// Namespace is the namespace to install into. TODO: Use metadata.namespace instead.
namespace: string @go(Namespace)
chart: #Chart @go(Chart)
valuesContent: string @go(ValuesContent)
enableHooks: bool @go(EnableHooks)
}
#Chart: {
name: string @go(Name)
version: string @go(Version)
release: string @go(Release)
repository?: #Repository @go(Repository)
}
#Repository: {
name: string @go(Name)
url: string @go(URL)
}

View File

@@ -0,0 +1,12 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#KubernetesObjectsKind: "KubernetesObjects"
// KubernetesObjects represents CUE output which directly provides Kubernetes api objects to holos.
#KubernetesObjects: {
#HolosComponent
}

View File

@@ -0,0 +1,11 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// Kustomization holds the rendered flux kustomization api object content for git ops.
#Kustomization: {
// KsContent is the yaml representation of the flux kustomization for gitops.
ksContent?: string @go(KsContent)
}

View File

@@ -0,0 +1,25 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#KustomizeBuildKind: "KustomizeBuild"
// Kustomize represents resources necessary to execute a kustomize build.
// Intended for at least two use cases:
//
// 1. Process raw yaml file resources in a holos component directory.
// 2. Post process a HelmChart to inject istio, add custom labels, etc...
#Kustomize: {
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
kustomizeFiles?: #FileContentMap @go(KustomizeFiles)
// ResourcesFile is the file name used for api objects in kustomization.yaml
resourcesFile?: string @go(ResourcesFile)
}
// KustomizeBuild renders plain yaml files in the holos component directory using kubectl kustomize build.
#KustomizeBuild: {
#HolosComponent
}

View File

@@ -0,0 +1,12 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#KustomizeBuildKind: "KustomizeBuild"
// KustomizeBuild
#KustomizeBuild: {
#HolosComponent
}

View File

@@ -0,0 +1,18 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// Label is an arbitrary unique identifier. Defined as a type for clarity and type checking.
#Label: string
// Kind is a kubernetes api object kind. Defined as a type for clarity and type checking.
#Kind: string
// APIObjectMap is the shape of marshalled api objects returned from cue to the
// holos cli. A map is used to improve the clarity of error messages from cue.
#APIObjectMap: {[string]: [string]: string}
// FileContentMap is a map of file names to file contents.
#FileContentMap: {[string]: string}

View File

@@ -0,0 +1,22 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// ObjectMeta represents metadata of a holos component object. The fields are a
// copy of upstream kubernetes api machinery but are by holos objects distinct
// from kubernetes api objects.
#ObjectMeta: {
// Name uniquely identifies the holos component instance and must be suitable as a file name.
name?: string @go(Name)
// Namespace confines a holos component to a single namespace via kustomize if set.
namespace?: string @go(Namespace)
// Labels are not used but are copied from api machinery ObjectMeta for completeness.
labels?: {[string]: string} @go(Labels,map[string]string)
// Annotations are not used but are copied from api machinery ObjectMeta for completeness.
annotations?: {[string]: string} @go(Annotations,map[string]string)
}

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#Renderer: _

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// Result is the build result for display or writing. Holos components Render the Result as a data pipeline.
#Result: {
HolosComponent: #HolosComponent
}

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#TypeMeta: {
kind?: string @go(Kind)
apiVersion?: string @go(APIVersion)
}

View File

@@ -0,0 +1,692 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f https://github.com/fluxcd/flux2/releases/download/v2.2.3/install.yaml
package v2beta1
import "strings"
// HelmRelease is the Schema for the helmreleases API
#HelmRelease: {
// 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: "helm.toolkit.fluxcd.io/v2beta1"
// 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: "HelmRelease"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// HelmReleaseSpec defines the desired state of a Helm release.
spec!: #HelmReleaseSpec
}
// HelmReleaseSpec defines the desired state of a Helm release.
#HelmReleaseSpec: {
// Chart defines the template of the v1beta2.HelmChart that should
// be created for this HelmRelease.
chart: {
// ObjectMeta holds the template for metadata like labels and
// annotations.
metadata?: {
// 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 queryable and should
// be preserved when modifying objects. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
annotations?: {
[string]: string
}
// Map of string keys and values that can be used to organize and
// categorize (scope and select) objects. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
labels?: {
[string]: string
}
}
// Spec holds the template for the v1beta2.HelmChartSpec for this
// HelmRelease.
spec: {
// The name or path the Helm chart is available at in the
// SourceRef.
chart: string
// Interval at which to check the v1beta2.Source for updates.
// Defaults to 'HelmReleaseSpec.Interval'.
interval?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// Determines what enables the creation of a new artifact. Valid
// values are ('ChartVersion', 'Revision'). See the documentation
// of the values for an explanation on their behavior. Defaults
// to ChartVersion when omitted.
reconcileStrategy?: "ChartVersion" | "Revision" | *"ChartVersion"
// The name and namespace of the v1beta2.Source the chart is
// available at.
sourceRef: {
// APIVersion of the referent.
apiVersion?: string
// Kind of the referent.
kind?: "HelmRepository" | "GitRepository" | "Bucket"
// Name of the referent.
name: strings.MaxRunes(253) & strings.MinRunes(1)
// Namespace of the referent.
namespace?: strings.MaxRunes(63) & strings.MinRunes(1)
}
// Alternative values file to use as the default chart values,
// expected to be a relative path in the SourceRef. Deprecated in
// favor of ValuesFiles, for backwards compatibility the file
// defined here is merged before the ValuesFiles items. Ignored
// when omitted.
valuesFile?: string
// Alternative list of values files to use as the chart values
// (values.yaml is not included by default), expected to be a
// relative path in the SourceRef. Values files are merged in the
// order of this list with the last file overriding the first.
// Ignored when omitted.
valuesFiles?: [...string]
// Verify contains the secret name containing the trusted public
// keys used to verify the signature and specifies which provider
// to use to check whether OCI image is authentic. This field is
// only supported for OCI sources. Chart dependencies, which are
// not bundled in the umbrella chart artifact, are not verified.
verify?: {
// Provider specifies the technology used to sign the OCI Helm
// chart.
provider: "cosign" | *"cosign"
secretRef?: {
// Name of the referent.
name: string
}
}
// Version semver expression, ignored for charts from
// v1beta2.GitRepository and v1beta2.Bucket sources. Defaults to
// latest when omitted.
version?: string | *"*"
}
}
// DependsOn may contain a meta.NamespacedObjectReference slice
// with references to HelmRelease resources that must be ready
// before this HelmRelease can be reconciled.
dependsOn?: [...{
// Name of the referent.
name: string
// Namespace of the referent, when not specified it acts as
// LocalObjectReference.
namespace?: string
}]
// DriftDetection holds the configuration for detecting and
// handling differences between the manifest in the Helm storage
// and the resources currently existing in the cluster.
// Note: this field is provisional to the v2beta2 API, and not
// actively used by v2beta1 HelmReleases.
driftDetection?: {
// Ignore contains a list of rules for specifying which changes to
// ignore during diffing.
ignore?: [...{
// Paths is a list of JSON Pointer (RFC 6901) paths to be excluded
// from consideration in a Kubernetes object.
paths: [...string]
// Target is a selector for specifying Kubernetes objects to which
// this rule applies. If Target is not set, the Paths will be
// ignored for all Kubernetes objects within the manifest of the
// Helm release.
target?: {
// AnnotationSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource annotations.
annotationSelector?: string
// Group is the API group to select resources from. Together with
// Version and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
group?: string
// Kind of the API Group to select resources from. Together with
// Group and Version it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
kind?: string
// LabelSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource labels.
labelSelector?: string
// Name to match resources with.
name?: string
// Namespace to select resources from.
namespace?: string
// Version of the API Group to select resources from. Together
// with Group and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
version?: string
}
}]
// Mode defines how differences should be handled between the Helm
// manifest and the manifest currently applied to the cluster. If
// not explicitly set, it defaults to DiffModeDisabled.
mode?: "enabled" | "warn" | "disabled"
}
// Install holds the configuration for Helm install actions for
// this HelmRelease.
install?: {
// CRDs upgrade CRDs from the Helm Chart's crds directory
// according to the CRD upgrade policy provided here. Valid
// values are `Skip`, `Create` or `CreateReplace`. Default is
// `Create` and if omitted CRDs are installed but not updated.
// Skip: do neither install nor replace (update) any CRDs.
// Create: new CRDs are created, existing CRDs are neither updated
// nor deleted.
// CreateReplace: new CRDs are created, existing CRDs are updated
// (replaced) but not deleted.
// By default, CRDs are applied (installed) during Helm install
// action. With this option users can opt-in to CRD replace
// existing CRDs on Helm install actions, which is not (yet)
// natively supported by Helm.
// https://helm.sh/docs/chart_best_practices/custom_resource_definitions.
crds?: "Skip" | "Create" | "CreateReplace"
// CreateNamespace tells the Helm install action to create the
// HelmReleaseSpec.TargetNamespace if it does not exist yet. On
// uninstall, the namespace will not be garbage collected.
createNamespace?: bool
// DisableHooks prevents hooks from running during the Helm
// install action.
disableHooks?: bool
// DisableOpenAPIValidation prevents the Helm install action from
// validating rendered templates against the Kubernetes OpenAPI
// Schema.
disableOpenAPIValidation?: bool
// DisableWait disables the waiting for resources to be ready
// after a Helm install has been performed.
disableWait?: bool
// DisableWaitForJobs disables waiting for jobs to complete after
// a Helm install has been performed.
disableWaitForJobs?: bool
// Remediation holds the remediation configuration for when the
// Helm install action for the HelmRelease fails. The default is
// to not perform any action.
remediation?: {
// IgnoreTestFailures tells the controller to skip remediation
// when the Helm tests are run after an install action but fail.
// Defaults to 'Test.IgnoreFailures'.
ignoreTestFailures?: bool
// RemediateLastFailure tells the controller to remediate the last
// failure, when no retries remain. Defaults to 'false'.
remediateLastFailure?: bool
// Retries is the number of retries that should be attempted on
// failures before bailing. Remediation, using an uninstall, is
// performed between each attempt. Defaults to '0', a negative
// integer equals to unlimited retries.
retries?: int
}
// Replace tells the Helm install action to re-use the
// 'ReleaseName', but only if that name is a deleted release
// which remains in the history.
replace?: bool
// SkipCRDs tells the Helm install action to not install any CRDs.
// By default, CRDs are installed if not already present.
// Deprecated use CRD policy (`crds`) attribute with value `Skip`
// instead.
skipCRDs?: bool
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm install action. Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// Interval at which to reconcile the Helm release. This interval
// is approximate and may be subject to jitter to ensure
// efficient use of resources.
interval: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
kubeConfig?: {
// SecretRef holds the name of a secret that contains a key with
// the kubeconfig file as the value. If no key is set, the key
// will default to 'value'. It is recommended that the kubeconfig
// is self-contained, and the secret is regularly updated if
// credentials such as a cloud-access-token expire. Cloud
// specific `cmd-path` auth helpers will not function without
// adding binaries and credentials to the Pod that is responsible
// for reconciling Kubernetes resources.
secretRef: {
// Key in the Secret, when not specified an
// implementation-specific default key is used.
key?: string
// Name of the Secret.
name: string
}
}
// MaxHistory is the number of revisions saved by Helm for this
// HelmRelease. Use '0' for an unlimited number of revisions;
// defaults to '10'.
maxHistory?: int
// PersistentClient tells the controller to use a persistent
// Kubernetes client for this release. When enabled, the client
// will be reused for the duration of the reconciliation, instead
// of being created and destroyed for each (step of a) Helm
// action.
// This can improve performance, but may cause issues with some
// Helm charts that for example do create Custom Resource
// Definitions during installation outside Helm's CRD lifecycle
// hooks, which are then not observed to be available by e.g.
// post-install hooks.
// If not set, it defaults to true.
persistentClient?: bool
// PostRenderers holds an array of Helm PostRenderers, which will
// be applied in order of their definition.
postRenderers?: [...{
// Kustomization to apply as PostRenderer.
kustomize?: {
// Images is a list of (image name, new name, new tag or digest)
// for changing image names, tags or digests. This can also be
// achieved with a patch, but this operator is simpler to
// specify.
images?: [...{
// Digest is the value used to replace the original image tag. If
// digest is present NewTag value is ignored.
digest?: string
// Name is a tag-less image name.
name: string
// NewName is the value used to replace the original name.
newName?: string
// NewTag is the value used to replace the original tag.
newTag?: string
}]
// Strategic merge and JSON patches, defined as inline YAML
// objects, capable of targeting objects based on kind, label and
// annotation selectors.
patches?: [...{
// Patch contains an inline StrategicMerge patch or an inline
// JSON6902 patch with an array of operation objects.
patch: string
// Target points to the resources that the patch document should
// be applied to.
target?: {
// AnnotationSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource annotations.
annotationSelector?: string
// Group is the API group to select resources from. Together with
// Version and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
group?: string
// Kind of the API Group to select resources from. Together with
// Group and Version it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
kind?: string
// LabelSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource labels.
labelSelector?: string
// Name to match resources with.
name?: string
// Namespace to select resources from.
namespace?: string
// Version of the API Group to select resources from. Together
// with Group and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
version?: string
}
}]
// JSON 6902 patches, defined as inline YAML objects.
patchesJson6902?: [...{
// Patch contains the JSON6902 patch document with an array of
// operation objects.
patch: [...{
// From contains a JSON-pointer value that references a location
// within the target document where the operation is performed.
// The meaning of the value depends on the value of Op, and is
// NOT taken into account by all operations.
from?: string
// Op indicates the operation to perform. Its value MUST be one of
// "add", "remove", "replace", "move", "copy", or "test".
// https://datatracker.ietf.org/doc/html/rfc6902#section-4
op: "test" | "remove" | "add" | "replace" | "move" | "copy"
// Path contains the JSON-pointer value that references a location
// within the target document where the operation is performed.
// The meaning of the value depends on the value of Op.
path: string
// Value contains a valid JSON structure. The meaning of the value
// depends on the value of Op, and is NOT taken into account by
// all operations.
value?: _
}]
// Target points to the resources that the patch document should
// be applied to.
target: {
// AnnotationSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource annotations.
annotationSelector?: string
// Group is the API group to select resources from. Together with
// Version and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
group?: string
// Kind of the API Group to select resources from. Together with
// Group and Version it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
kind?: string
// LabelSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource labels.
labelSelector?: string
// Name to match resources with.
name?: string
// Namespace to select resources from.
namespace?: string
// Version of the API Group to select resources from. Together
// with Group and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
version?: string
}
}]
// Strategic merge patches, defined as inline YAML objects.
patchesStrategicMerge?: [...]
}
}]
// ReleaseName used for the Helm release. Defaults to a
// composition of '[TargetNamespace-]Name'.
releaseName?: strings.MaxRunes(53) & strings.MinRunes(1)
// Rollback holds the configuration for Helm rollback actions for
// this HelmRelease.
rollback?: {
// CleanupOnFail allows deletion of new resources created during
// the Helm rollback action when it fails.
cleanupOnFail?: bool
// DisableHooks prevents hooks from running during the Helm
// rollback action.
disableHooks?: bool
// DisableWait disables the waiting for resources to be ready
// after a Helm rollback has been performed.
disableWait?: bool
// DisableWaitForJobs disables waiting for jobs to complete after
// a Helm rollback has been performed.
disableWaitForJobs?: bool
// Force forces resource updates through a replacement strategy.
force?: bool
// Recreate performs pod restarts for the resource if applicable.
recreate?: bool
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm rollback action. Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// The name of the Kubernetes service account to impersonate when
// reconciling this HelmRelease.
serviceAccountName?: string
// StorageNamespace used for the Helm storage. Defaults to the
// namespace of the HelmRelease.
storageNamespace?: strings.MaxRunes(63) & strings.MinRunes(1)
// Suspend tells the controller to suspend reconciliation for this
// HelmRelease, it does not apply to already started
// reconciliations. Defaults to false.
suspend?: bool
// TargetNamespace to target when performing operations for the
// HelmRelease. Defaults to the namespace of the HelmRelease.
targetNamespace?: strings.MaxRunes(63) & strings.MinRunes(1)
// Test holds the configuration for Helm test actions for this
// HelmRelease.
test?: {
// Enable enables Helm test actions for this HelmRelease after an
// Helm install or upgrade action has been performed.
enable?: bool
// IgnoreFailures tells the controller to skip remediation when
// the Helm tests are run but fail. Can be overwritten for tests
// run after install or upgrade actions in
// 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'.
ignoreFailures?: bool
// Timeout is the time to wait for any individual Kubernetes
// operation during the performance of a Helm test action.
// Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm action. Defaults to '5m0s'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// Uninstall holds the configuration for Helm uninstall actions
// for this HelmRelease.
uninstall?: {
// DeletionPropagation specifies the deletion propagation policy
// when a Helm uninstall is performed.
deletionPropagation?: "background" | "foreground" | "orphan" | *"background"
// DisableHooks prevents hooks from running during the Helm
// rollback action.
disableHooks?: bool
// DisableWait disables waiting for all the resources to be
// deleted after a Helm uninstall is performed.
disableWait?: bool
// KeepHistory tells Helm to remove all associated resources and
// mark the release as deleted, but retain the release history.
keepHistory?: bool
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm uninstall action. Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// Upgrade holds the configuration for Helm upgrade actions for
// this HelmRelease.
upgrade?: {
// CleanupOnFail allows deletion of new resources created during
// the Helm upgrade action when it fails.
cleanupOnFail?: bool
// CRDs upgrade CRDs from the Helm Chart's crds directory
// according to the CRD upgrade policy provided here. Valid
// values are `Skip`, `Create` or `CreateReplace`. Default is
// `Skip` and if omitted CRDs are neither installed nor upgraded.
// Skip: do neither install nor replace (update) any CRDs.
// Create: new CRDs are created, existing CRDs are neither updated
// nor deleted.
// CreateReplace: new CRDs are created, existing CRDs are updated
// (replaced) but not deleted.
// By default, CRDs are not applied during Helm upgrade action.
// With this option users can opt-in to CRD upgrade, which is not
// (yet) natively supported by Helm.
// https://helm.sh/docs/chart_best_practices/custom_resource_definitions.
crds?: "Skip" | "Create" | "CreateReplace"
// DisableHooks prevents hooks from running during the Helm
// upgrade action.
disableHooks?: bool
// DisableOpenAPIValidation prevents the Helm upgrade action from
// validating rendered templates against the Kubernetes OpenAPI
// Schema.
disableOpenAPIValidation?: bool
// DisableWait disables the waiting for resources to be ready
// after a Helm upgrade has been performed.
disableWait?: bool
// DisableWaitForJobs disables waiting for jobs to complete after
// a Helm upgrade has been performed.
disableWaitForJobs?: bool
// Force forces resource updates through a replacement strategy.
force?: bool
// PreserveValues will make Helm reuse the last release's values
// and merge in overrides from 'Values'. Setting this flag makes
// the HelmRelease non-declarative.
preserveValues?: bool
// Remediation holds the remediation configuration for when the
// Helm upgrade action for the HelmRelease fails. The default is
// to not perform any action.
remediation?: {
// IgnoreTestFailures tells the controller to skip remediation
// when the Helm tests are run after an upgrade action but fail.
// Defaults to 'Test.IgnoreFailures'.
ignoreTestFailures?: bool
// RemediateLastFailure tells the controller to remediate the last
// failure, when no retries remain. Defaults to 'false' unless
// 'Retries' is greater than 0.
remediateLastFailure?: bool
// Retries is the number of retries that should be attempted on
// failures before bailing. Remediation, using 'Strategy', is
// performed between each attempt. Defaults to '0', a negative
// integer equals to unlimited retries.
retries?: int
// Strategy to use for failure remediation. Defaults to
// 'rollback'.
strategy?: "rollback" | "uninstall"
}
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm upgrade action. Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// Values holds the values for this Helm release.
values?: _
// ValuesFrom holds references to resources containing Helm values
// for this HelmRelease, and information about how they should be
// merged.
valuesFrom?: [...{
// Kind of the values referent, valid values are ('Secret',
// 'ConfigMap').
kind: "Secret" | "ConfigMap"
// Name of the values referent. Should reside in the same
// namespace as the referring resource.
name: strings.MaxRunes(253) & strings.MinRunes(1)
// Optional marks this ValuesReference as optional. When set, a
// not found error for the values reference is ignored, but any
// ValuesKey, TargetPath or transient error will still result in
// a reconciliation failure.
optional?: bool
// TargetPath is the YAML dot notation path the value should be
// merged at. When set, the ValuesKey is expected to be a single
// flat value. Defaults to 'None', which results in the values
// getting merged at the root.
targetPath?: strings.MaxRunes(250) & {
=~"^([a-zA-Z0-9_\\-.\\\\\\/]|\\[[0-9]{1,5}\\])+$"
}
// ValuesKey is the data key where the values.yaml or a specific
// value can be found at. Defaults to 'values.yaml'. When set,
// must be a valid Data Key, consisting of alphanumeric
// characters, '-', '_' or '.'.
valuesKey?: strings.MaxRunes(253) & {
=~"^[\\-._a-zA-Z0-9]+$"
}
}]
}

View File

@@ -0,0 +1,697 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f https://github.com/fluxcd/flux2/releases/download/v2.2.3/install.yaml
package v2beta2
import "strings"
// HelmRelease is the Schema for the helmreleases API
#HelmRelease: {
// 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: "helm.toolkit.fluxcd.io/v2beta2"
// 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: "HelmRelease"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// HelmReleaseSpec defines the desired state of a Helm release.
spec!: #HelmReleaseSpec
}
// HelmReleaseSpec defines the desired state of a Helm release.
#HelmReleaseSpec: {
// Chart defines the template of the v1beta2.HelmChart that should
// be created for this HelmRelease.
chart: {
// ObjectMeta holds the template for metadata like labels and
// annotations.
metadata?: {
// 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 queryable and should
// be preserved when modifying objects. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
annotations?: {
[string]: string
}
// Map of string keys and values that can be used to organize and
// categorize (scope and select) objects. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
labels?: {
[string]: string
}
}
// Spec holds the template for the v1beta2.HelmChartSpec for this
// HelmRelease.
spec: {
// The name or path the Helm chart is available at in the
// SourceRef.
chart: strings.MaxRunes(2048) & strings.MinRunes(1)
// Interval at which to check the v1.Source for updates. Defaults
// to 'HelmReleaseSpec.Interval'.
interval?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// Determines what enables the creation of a new artifact. Valid
// values are ('ChartVersion', 'Revision'). See the documentation
// of the values for an explanation on their behavior. Defaults
// to ChartVersion when omitted.
reconcileStrategy?: "ChartVersion" | "Revision" | *"ChartVersion"
// The name and namespace of the v1.Source the chart is available
// at.
sourceRef: {
// APIVersion of the referent.
apiVersion?: string
// Kind of the referent.
kind?: "HelmRepository" | "GitRepository" | "Bucket"
// Name of the referent.
name: strings.MaxRunes(253) & strings.MinRunes(1)
// Namespace of the referent.
namespace?: strings.MaxRunes(63) & strings.MinRunes(1)
}
// Alternative values file to use as the default chart values,
// expected to be a relative path in the SourceRef. Deprecated in
// favor of ValuesFiles, for backwards compatibility the file
// defined here is merged before the ValuesFiles items. Ignored
// when omitted.
valuesFile?: string
// Alternative list of values files to use as the chart values
// (values.yaml is not included by default), expected to be a
// relative path in the SourceRef. Values files are merged in the
// order of this list with the last file overriding the first.
// Ignored when omitted.
valuesFiles?: [...string]
// Verify contains the secret name containing the trusted public
// keys used to verify the signature and specifies which provider
// to use to check whether OCI image is authentic. This field is
// only supported for OCI sources. Chart dependencies, which are
// not bundled in the umbrella chart artifact, are not verified.
verify?: {
// Provider specifies the technology used to sign the OCI Helm
// chart.
provider: "cosign" | *"cosign"
secretRef?: {
// Name of the referent.
name: string
}
}
// Version semver expression, ignored for charts from
// v1beta2.GitRepository and v1beta2.Bucket sources. Defaults to
// latest when omitted.
version?: string | *"*"
}
}
// DependsOn may contain a meta.NamespacedObjectReference slice
// with references to HelmRelease resources that must be ready
// before this HelmRelease can be reconciled.
dependsOn?: [...{
// Name of the referent.
name: string
// Namespace of the referent, when not specified it acts as
// LocalObjectReference.
namespace?: string
}]
// DriftDetection holds the configuration for detecting and
// handling differences between the manifest in the Helm storage
// and the resources currently existing in the cluster.
driftDetection?: {
// Ignore contains a list of rules for specifying which changes to
// ignore during diffing.
ignore?: [...{
// Paths is a list of JSON Pointer (RFC 6901) paths to be excluded
// from consideration in a Kubernetes object.
paths: [...string]
// Target is a selector for specifying Kubernetes objects to which
// this rule applies. If Target is not set, the Paths will be
// ignored for all Kubernetes objects within the manifest of the
// Helm release.
target?: {
// AnnotationSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource annotations.
annotationSelector?: string
// Group is the API group to select resources from. Together with
// Version and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
group?: string
// Kind of the API Group to select resources from. Together with
// Group and Version it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
kind?: string
// LabelSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource labels.
labelSelector?: string
// Name to match resources with.
name?: string
// Namespace to select resources from.
namespace?: string
// Version of the API Group to select resources from. Together
// with Group and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
version?: string
}
}]
// Mode defines how differences should be handled between the Helm
// manifest and the manifest currently applied to the cluster. If
// not explicitly set, it defaults to DiffModeDisabled.
mode?: "enabled" | "warn" | "disabled"
}
// Install holds the configuration for Helm install actions for
// this HelmRelease.
install?: {
// CRDs upgrade CRDs from the Helm Chart's crds directory
// according to the CRD upgrade policy provided here. Valid
// values are `Skip`, `Create` or `CreateReplace`. Default is
// `Create` and if omitted CRDs are installed but not updated.
// Skip: do neither install nor replace (update) any CRDs.
// Create: new CRDs are created, existing CRDs are neither updated
// nor deleted.
// CreateReplace: new CRDs are created, existing CRDs are updated
// (replaced) but not deleted.
// By default, CRDs are applied (installed) during Helm install
// action. With this option users can opt in to CRD replace
// existing CRDs on Helm install actions, which is not (yet)
// natively supported by Helm.
// https://helm.sh/docs/chart_best_practices/custom_resource_definitions.
crds?: "Skip" | "Create" | "CreateReplace"
// CreateNamespace tells the Helm install action to create the
// HelmReleaseSpec.TargetNamespace if it does not exist yet. On
// uninstall, the namespace will not be garbage collected.
createNamespace?: bool
// DisableHooks prevents hooks from running during the Helm
// install action.
disableHooks?: bool
// DisableOpenAPIValidation prevents the Helm install action from
// validating rendered templates against the Kubernetes OpenAPI
// Schema.
disableOpenAPIValidation?: bool
// DisableWait disables the waiting for resources to be ready
// after a Helm install has been performed.
disableWait?: bool
// DisableWaitForJobs disables waiting for jobs to complete after
// a Helm install has been performed.
disableWaitForJobs?: bool
// Remediation holds the remediation configuration for when the
// Helm install action for the HelmRelease fails. The default is
// to not perform any action.
remediation?: {
// IgnoreTestFailures tells the controller to skip remediation
// when the Helm tests are run after an install action but fail.
// Defaults to 'Test.IgnoreFailures'.
ignoreTestFailures?: bool
// RemediateLastFailure tells the controller to remediate the last
// failure, when no retries remain. Defaults to 'false'.
remediateLastFailure?: bool
// Retries is the number of retries that should be attempted on
// failures before bailing. Remediation, using an uninstall, is
// performed between each attempt. Defaults to '0', a negative
// integer equals to unlimited retries.
retries?: int
}
// Replace tells the Helm install action to re-use the
// 'ReleaseName', but only if that name is a deleted release
// which remains in the history.
replace?: bool
// SkipCRDs tells the Helm install action to not install any CRDs.
// By default, CRDs are installed if not already present.
// Deprecated use CRD policy (`crds`) attribute with value `Skip`
// instead.
skipCRDs?: bool
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm install action. Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// Interval at which to reconcile the Helm release.
interval: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
kubeConfig?: {
// SecretRef holds the name of a secret that contains a key with
// the kubeconfig file as the value. If no key is set, the key
// will default to 'value'. It is recommended that the kubeconfig
// is self-contained, and the secret is regularly updated if
// credentials such as a cloud-access-token expire. Cloud
// specific `cmd-path` auth helpers will not function without
// adding binaries and credentials to the Pod that is responsible
// for reconciling Kubernetes resources.
secretRef: {
// Key in the Secret, when not specified an
// implementation-specific default key is used.
key?: string
// Name of the Secret.
name: string
}
}
// MaxHistory is the number of revisions saved by Helm for this
// HelmRelease. Use '0' for an unlimited number of revisions;
// defaults to '5'.
maxHistory?: int
// PersistentClient tells the controller to use a persistent
// Kubernetes client for this release. When enabled, the client
// will be reused for the duration of the reconciliation, instead
// of being created and destroyed for each (step of a) Helm
// action.
// This can improve performance, but may cause issues with some
// Helm charts that for example do create Custom Resource
// Definitions during installation outside Helm's CRD lifecycle
// hooks, which are then not observed to be available by e.g.
// post-install hooks.
// If not set, it defaults to true.
persistentClient?: bool
// PostRenderers holds an array of Helm PostRenderers, which will
// be applied in order of their definition.
postRenderers?: [...{
// Kustomization to apply as PostRenderer.
kustomize?: {
// Images is a list of (image name, new name, new tag or digest)
// for changing image names, tags or digests. This can also be
// achieved with a patch, but this operator is simpler to
// specify.
images?: [...{
// Digest is the value used to replace the original image tag. If
// digest is present NewTag value is ignored.
digest?: string
// Name is a tag-less image name.
name: string
// NewName is the value used to replace the original name.
newName?: string
// NewTag is the value used to replace the original tag.
newTag?: string
}]
// Strategic merge and JSON patches, defined as inline YAML
// objects, capable of targeting objects based on kind, label and
// annotation selectors.
patches?: [...{
// Patch contains an inline StrategicMerge patch or an inline
// JSON6902 patch with an array of operation objects.
patch: string
// Target points to the resources that the patch document should
// be applied to.
target?: {
// AnnotationSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource annotations.
annotationSelector?: string
// Group is the API group to select resources from. Together with
// Version and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
group?: string
// Kind of the API Group to select resources from. Together with
// Group and Version it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
kind?: string
// LabelSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource labels.
labelSelector?: string
// Name to match resources with.
name?: string
// Namespace to select resources from.
namespace?: string
// Version of the API Group to select resources from. Together
// with Group and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
version?: string
}
}]
// JSON 6902 patches, defined as inline YAML objects. Deprecated:
// use Patches instead.
patchesJson6902?: [...{
// Patch contains the JSON6902 patch document with an array of
// operation objects.
patch: [...{
// From contains a JSON-pointer value that references a location
// within the target document where the operation is performed.
// The meaning of the value depends on the value of Op, and is
// NOT taken into account by all operations.
from?: string
// Op indicates the operation to perform. Its value MUST be one of
// "add", "remove", "replace", "move", "copy", or "test".
// https://datatracker.ietf.org/doc/html/rfc6902#section-4
op: "test" | "remove" | "add" | "replace" | "move" | "copy"
// Path contains the JSON-pointer value that references a location
// within the target document where the operation is performed.
// The meaning of the value depends on the value of Op.
path: string
// Value contains a valid JSON structure. The meaning of the value
// depends on the value of Op, and is NOT taken into account by
// all operations.
value?: _
}]
// Target points to the resources that the patch document should
// be applied to.
target: {
// AnnotationSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource annotations.
annotationSelector?: string
// Group is the API group to select resources from. Together with
// Version and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
group?: string
// Kind of the API Group to select resources from. Together with
// Group and Version it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
kind?: string
// LabelSelector is a string that follows the label selection
// expression
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
// It matches with the resource labels.
labelSelector?: string
// Name to match resources with.
name?: string
// Namespace to select resources from.
namespace?: string
// Version of the API Group to select resources from. Together
// with Group and Kind it is capable of unambiguously identifying
// and/or selecting resources.
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
version?: string
}
}]
// Strategic merge patches, defined as inline YAML objects.
// Deprecated: use Patches instead.
patchesStrategicMerge?: [...]
}
}]
// ReleaseName used for the Helm release. Defaults to a
// composition of '[TargetNamespace-]Name'.
releaseName?: strings.MaxRunes(53) & strings.MinRunes(1)
// Rollback holds the configuration for Helm rollback actions for
// this HelmRelease.
rollback?: {
// CleanupOnFail allows deletion of new resources created during
// the Helm rollback action when it fails.
cleanupOnFail?: bool
// DisableHooks prevents hooks from running during the Helm
// rollback action.
disableHooks?: bool
// DisableWait disables the waiting for resources to be ready
// after a Helm rollback has been performed.
disableWait?: bool
// DisableWaitForJobs disables waiting for jobs to complete after
// a Helm rollback has been performed.
disableWaitForJobs?: bool
// Force forces resource updates through a replacement strategy.
force?: bool
// Recreate performs pod restarts for the resource if applicable.
recreate?: bool
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm rollback action. Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// The name of the Kubernetes service account to impersonate when
// reconciling this HelmRelease.
serviceAccountName?: strings.MaxRunes(253) & strings.MinRunes(1)
// StorageNamespace used for the Helm storage. Defaults to the
// namespace of the HelmRelease.
storageNamespace?: strings.MaxRunes(63) & strings.MinRunes(1)
// Suspend tells the controller to suspend reconciliation for this
// HelmRelease, it does not apply to already started
// reconciliations. Defaults to false.
suspend?: bool
// TargetNamespace to target when performing operations for the
// HelmRelease. Defaults to the namespace of the HelmRelease.
targetNamespace?: strings.MaxRunes(63) & strings.MinRunes(1)
// Test holds the configuration for Helm test actions for this
// HelmRelease.
test?: {
// Enable enables Helm test actions for this HelmRelease after an
// Helm install or upgrade action has been performed.
enable?: bool
// Filters is a list of tests to run or exclude from running.
filters?: [...{
// Exclude specifies whether the named test should be excluded.
exclude?: bool
// Name is the name of the test.
name: strings.MaxRunes(253) & strings.MinRunes(1)
}]
// IgnoreFailures tells the controller to skip remediation when
// the Helm tests are run but fail. Can be overwritten for tests
// run after install or upgrade actions in
// 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'.
ignoreFailures?: bool
// Timeout is the time to wait for any individual Kubernetes
// operation during the performance of a Helm test action.
// Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm action. Defaults to '5m0s'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// Uninstall holds the configuration for Helm uninstall actions
// for this HelmRelease.
uninstall?: {
// DeletionPropagation specifies the deletion propagation policy
// when a Helm uninstall is performed.
deletionPropagation?: "background" | "foreground" | "orphan" | *"background"
// DisableHooks prevents hooks from running during the Helm
// rollback action.
disableHooks?: bool
// DisableWait disables waiting for all the resources to be
// deleted after a Helm uninstall is performed.
disableWait?: bool
// KeepHistory tells Helm to remove all associated resources and
// mark the release as deleted, but retain the release history.
keepHistory?: bool
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm uninstall action. Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// Upgrade holds the configuration for Helm upgrade actions for
// this HelmRelease.
upgrade?: {
// CleanupOnFail allows deletion of new resources created during
// the Helm upgrade action when it fails.
cleanupOnFail?: bool
// CRDs upgrade CRDs from the Helm Chart's crds directory
// according to the CRD upgrade policy provided here. Valid
// values are `Skip`, `Create` or `CreateReplace`. Default is
// `Skip` and if omitted CRDs are neither installed nor upgraded.
// Skip: do neither install nor replace (update) any CRDs.
// Create: new CRDs are created, existing CRDs are neither updated
// nor deleted.
// CreateReplace: new CRDs are created, existing CRDs are updated
// (replaced) but not deleted.
// By default, CRDs are not applied during Helm upgrade action.
// With this option users can opt-in to CRD upgrade, which is not
// (yet) natively supported by Helm.
// https://helm.sh/docs/chart_best_practices/custom_resource_definitions.
crds?: "Skip" | "Create" | "CreateReplace"
// DisableHooks prevents hooks from running during the Helm
// upgrade action.
disableHooks?: bool
// DisableOpenAPIValidation prevents the Helm upgrade action from
// validating rendered templates against the Kubernetes OpenAPI
// Schema.
disableOpenAPIValidation?: bool
// DisableWait disables the waiting for resources to be ready
// after a Helm upgrade has been performed.
disableWait?: bool
// DisableWaitForJobs disables waiting for jobs to complete after
// a Helm upgrade has been performed.
disableWaitForJobs?: bool
// Force forces resource updates through a replacement strategy.
force?: bool
// PreserveValues will make Helm reuse the last release's values
// and merge in overrides from 'Values'. Setting this flag makes
// the HelmRelease non-declarative.
preserveValues?: bool
// Remediation holds the remediation configuration for when the
// Helm upgrade action for the HelmRelease fails. The default is
// to not perform any action.
remediation?: {
// IgnoreTestFailures tells the controller to skip remediation
// when the Helm tests are run after an upgrade action but fail.
// Defaults to 'Test.IgnoreFailures'.
ignoreTestFailures?: bool
// RemediateLastFailure tells the controller to remediate the last
// failure, when no retries remain. Defaults to 'false' unless
// 'Retries' is greater than 0.
remediateLastFailure?: bool
// Retries is the number of retries that should be attempted on
// failures before bailing. Remediation, using 'Strategy', is
// performed between each attempt. Defaults to '0', a negative
// integer equals to unlimited retries.
retries?: int
// Strategy to use for failure remediation. Defaults to
// 'rollback'.
strategy?: "rollback" | "uninstall"
}
// Timeout is the time to wait for any individual Kubernetes
// operation (like Jobs for hooks) during the performance of a
// Helm upgrade action. Defaults to 'HelmReleaseSpec.Timeout'.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
}
// Values holds the values for this Helm release.
values?: _
// ValuesFrom holds references to resources containing Helm values
// for this HelmRelease, and information about how they should be
// merged.
valuesFrom?: [...{
// Kind of the values referent, valid values are ('Secret',
// 'ConfigMap').
kind: "Secret" | "ConfigMap"
// Name of the values referent. Should reside in the same
// namespace as the referring resource.
name: strings.MaxRunes(253) & strings.MinRunes(1)
// Optional marks this ValuesReference as optional. When set, a
// not found error for the values reference is ignored, but any
// ValuesKey, TargetPath or transient error will still result in
// a reconciliation failure.
optional?: bool
// TargetPath is the YAML dot notation path the value should be
// merged at. When set, the ValuesKey is expected to be a single
// flat value. Defaults to 'None', which results in the values
// getting merged at the root.
targetPath?: strings.MaxRunes(250) & {
=~"^([a-zA-Z0-9_\\-.\\\\\\/]|\\[[0-9]{1,5}\\])+$"
}
// ValuesKey is the data key where the values.yaml or a specific
// value can be found at. Defaults to 'values.yaml'.
valuesKey?: strings.MaxRunes(253) & {
=~"^[\\-._a-zA-Z0-9]+$"
}
}]
}

View File

@@ -0,0 +1,93 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f https://github.com/fluxcd/flux2/releases/download/v2.2.3/install.yaml
package v1beta1
import "strings"
// ImagePolicy is the Schema for the imagepolicies API
#ImagePolicy: {
// 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: "image.toolkit.fluxcd.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: "ImagePolicy"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ImagePolicySpec defines the parameters for calculating the
// ImagePolicy
spec!: #ImagePolicySpec
}
// ImagePolicySpec defines the parameters for calculating the
// ImagePolicy
#ImagePolicySpec: {
// FilterTags enables filtering for only a subset of tags based on
// a set of rules. If no rules are provided, all the tags from
// the repository will be ordered and compared.
filterTags?: {
// Extract allows a capture group to be extracted from the
// specified regular expression pattern, useful before tag
// evaluation.
extract?: string
// Pattern specifies a regular expression pattern used to filter
// for image tags.
pattern?: string
}
// ImageRepositoryRef points at the object specifying the image
// being scanned
imageRepositoryRef: {
// Name of the referent.
name: string
// Namespace of the referent, when not specified it acts as
// LocalObjectReference.
namespace?: string
}
// Policy gives the particulars of the policy to be followed in
// selecting the most recent image
policy: {
alphabetical?: {
// Order specifies the sorting order of the tags. Given the
// letters of the alphabet as tags, ascending order would select
// Z, and descending order would select A.
order?: "asc" | "desc" | *"asc"
}
numerical?: {
// Order specifies the sorting order of the tags. Given the
// integer values from 0 to 9 as tags, ascending order would
// select 9, and descending order would select 0.
order?: "asc" | "desc" | *"asc"
}
semver?: {
// Range gives a semver range for the image tag; the highest
// version within the range that's a tag yields the latest image.
range: string
}
}
}

View File

@@ -0,0 +1,93 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f https://github.com/fluxcd/flux2/releases/download/v2.2.3/install.yaml
package v1beta2
import "strings"
// ImagePolicy is the Schema for the imagepolicies API
#ImagePolicy: {
// 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: "image.toolkit.fluxcd.io/v1beta2"
// 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: "ImagePolicy"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ImagePolicySpec defines the parameters for calculating the
// ImagePolicy.
spec!: #ImagePolicySpec
}
// ImagePolicySpec defines the parameters for calculating the
// ImagePolicy.
#ImagePolicySpec: {
// FilterTags enables filtering for only a subset of tags based on
// a set of rules. If no rules are provided, all the tags from
// the repository will be ordered and compared.
filterTags?: {
// Extract allows a capture group to be extracted from the
// specified regular expression pattern, useful before tag
// evaluation.
extract?: string
// Pattern specifies a regular expression pattern used to filter
// for image tags.
pattern?: string
}
// ImageRepositoryRef points at the object specifying the image
// being scanned
imageRepositoryRef: {
// Name of the referent.
name: string
// Namespace of the referent, when not specified it acts as
// LocalObjectReference.
namespace?: string
}
// Policy gives the particulars of the policy to be followed in
// selecting the most recent image
policy: {
alphabetical?: {
// Order specifies the sorting order of the tags. Given the
// letters of the alphabet as tags, ascending order would select
// Z, and descending order would select A.
order?: "asc" | "desc" | *"asc"
}
numerical?: {
// Order specifies the sorting order of the tags. Given the
// integer values from 0 to 9 as tags, ascending order would
// select 9, and descending order would select 0.
order?: "asc" | "desc" | *"asc"
}
semver?: {
// Range gives a semver range for the image tag; the highest
// version within the range that's a tag yields the latest image.
range: string
}
}
}

View File

@@ -0,0 +1,94 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f https://github.com/fluxcd/flux2/releases/download/v2.2.3/install.yaml
package v1beta1
import "strings"
// ImageRepository is the Schema for the imagerepositories API
#ImageRepository: {
// 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: "image.toolkit.fluxcd.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: "ImageRepository"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ImageRepositorySpec defines the parameters for scanning an
// image repository, e.g., `fluxcd/flux`.
spec!: #ImageRepositorySpec
}
// ImageRepositorySpec defines the parameters for scanning an
// image repository, e.g., `fluxcd/flux`.
#ImageRepositorySpec: {
accessFrom?: {
// NamespaceSelectors is the list of namespace selectors to which
// this ACL applies. Items in this list are evaluated using a
// logical OR operation.
namespaceSelectors: [...{
// 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
}
}]
}
certSecretRef?: {
// Name of the referent.
name: string
}
// ExclusionList is a list of regex strings used to exclude
// certain tags from being stored in the database.
exclusionList?: [...string]
// Image is the name of the image repository
image?: string
// Interval is the length of time to wait between scans of the
// image repository.
interval?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
secretRef?: {
// Name of the referent.
name: string
}
// ServiceAccountName is the name of the Kubernetes ServiceAccount
// used to authenticate the image pull if the service account has
// attached pull secrets.
serviceAccountName?: strings.MaxRunes(253)
// This flag tells the controller to suspend subsequent image
// scans. It does not apply to already started scans. Defaults to
// false.
suspend?: bool
// Timeout for image scanning. Defaults to 'Interval' duration.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m))+$"
}

View File

@@ -0,0 +1,105 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f https://github.com/fluxcd/flux2/releases/download/v2.2.3/install.yaml
package v1beta2
import (
"strings"
"list"
)
// ImageRepository is the Schema for the imagerepositories API
#ImageRepository: {
// 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: "image.toolkit.fluxcd.io/v1beta2"
// 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: "ImageRepository"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ImageRepositorySpec defines the parameters for scanning an
// image repository, e.g., `fluxcd/flux`.
spec!: #ImageRepositorySpec
}
// ImageRepositorySpec defines the parameters for scanning an
// image repository, e.g., `fluxcd/flux`.
#ImageRepositorySpec: {
accessFrom?: {
// NamespaceSelectors is the list of namespace selectors to which
// this ACL applies. Items in this list are evaluated using a
// logical OR operation.
namespaceSelectors: [...{
// 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
}
}]
}
certSecretRef?: {
// Name of the referent.
name: string
}
// ExclusionList is a list of regex strings used to exclude
// certain tags from being stored in the database.
exclusionList?: list.MaxItems(25) & [...string] | *["^.*\\.sig$"]
// Image is the name of the image repository
image?: string
// Insecure allows connecting to a non-TLS HTTP container
// registry.
insecure?: bool
// Interval is the length of time to wait between scans of the
// image repository.
interval?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// The provider used for authentication, can be 'aws', 'azure',
// 'gcp' or 'generic'. When not specified, defaults to 'generic'.
provider?: "generic" | "aws" | "azure" | "gcp" | *"generic"
secretRef?: {
// Name of the referent.
name: string
}
// ServiceAccountName is the name of the Kubernetes ServiceAccount
// used to authenticate the image pull if the service account has
// attached pull secrets.
serviceAccountName?: strings.MaxRunes(253)
// This flag tells the controller to suspend subsequent image
// scans. It does not apply to already started scans. Defaults to
// false.
suspend?: bool
// Timeout for image scanning. Defaults to 'Interval' duration.
timeout?: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m))+$"
}

View File

@@ -0,0 +1,170 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f https://github.com/fluxcd/flux2/releases/download/v2.2.3/install.yaml
package v1beta1
import "strings"
// ImageUpdateAutomation is the Schema for the
// imageupdateautomations API
#ImageUpdateAutomation: {
// 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: "image.toolkit.fluxcd.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: "ImageUpdateAutomation"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// ImageUpdateAutomationSpec defines the desired state of
// ImageUpdateAutomation
spec!: #ImageUpdateAutomationSpec
}
// ImageUpdateAutomationSpec defines the desired state of
// ImageUpdateAutomation
#ImageUpdateAutomationSpec: {
// GitSpec contains all the git-specific definitions. This is
// technically optional, but in practice mandatory until there
// are other kinds of source allowed.
git?: {
checkout?: {
// Reference gives a branch, tag or commit to clone from the Git
// repository.
ref: {
// Branch to check out, defaults to 'master' if no other field is
// defined.
branch?: string
// Commit SHA to check out, takes precedence over all reference
// fields.
// This can be combined with Branch to shallow clone the branch,
// in which the commit is expected to exist.
commit?: string
// Name of the reference to check out; takes precedence over
// Branch, Tag and SemVer.
// It must be a valid Git reference:
// https://git-scm.com/docs/git-check-ref-format#_description
// Examples: "refs/heads/main", "refs/tags/v0.1.0",
// "refs/pull/420/head", "refs/merge-requests/1/head"
name?: string
// SemVer tag expression to check out, takes precedence over Tag.
semver?: string
// Tag to check out, takes precedence over Branch.
tag?: string
}
}
// Commit specifies how to commit to the git repository.
commit: {
// Author gives the email and optionally the name to use as the
// author of commits.
author: {
// Email gives the email to provide when making a commit.
email: string
// Name gives the name to provide when making a commit.
name?: string
}
// MessageTemplate provides a template for the commit message,
// into which will be interpolated the details of the change
// made.
messageTemplate?: string
signingKey?: {
secretRef?: {
// Name of the referent.
name: string
}
}
}
// Push specifies how and where to push commits made by the
// automation. If missing, commits are pushed (back) to
// `.spec.checkout.branch` or its default.
push?: {
// Branch specifies that commits should be pushed to the branch
// named. The branch is created using `.spec.checkout.branch` as
// the starting point, if it doesn't already exist.
branch?: string
// Options specifies the push options that are sent to the Git
// server when performing a push operation. For details, see:
// https://git-scm.com/docs/git-push#Documentation/git-push.txt---push-optionltoptiongt
options?: {
[string]: string
}
// Refspec specifies the Git Refspec to use for a push operation.
// If both Branch and Refspec are provided, then the commit is
// pushed to the branch and also using the specified refspec. For
// more details about Git Refspecs, see:
// https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
refspec?: string
}
}
// Interval gives an lower bound for how often the automation run
// should be attempted.
interval: =~"^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// SourceRef refers to the resource giving access details to a git
// repository.
sourceRef: {
// API version of the referent.
apiVersion?: string
// Kind of the referent.
kind: "GitRepository" | *"GitRepository"
// Name of the referent.
name: string
// Namespace of the referent, defaults to the namespace of the
// Kubernetes resource object that contains the reference.
namespace?: string
}
// Suspend tells the controller to not run this automation, until
// it is unset (or set to false). Defaults to false.
suspend?: bool
// Update gives the specification for how to update the files in
// the repository. This can be left empty, to use the default
// value.
update?: {
// Path to the directory containing the manifests to be updated.
// Defaults to 'None', which translates to the root path of the
// GitRepositoryRef.
path?: string
// Strategy names the strategy to be used.
strategy: "Setters" | *"Setters"
} | *{
strategy: "Setters"
}
}

View File

@@ -0,0 +1,27 @@
// 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-istio-base/prod-mesh-istio-base.gen.yaml
package v1alpha1
import "strings"
#IstioOperator: {
apiVersion: "install.istio.io/v1alpha1"
kind: "IstioOperator"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
...
}

View File

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

View File

@@ -0,0 +1,172 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/admission/v1
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
authenticationv1 "k8s.io/api/authentication/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// AdmissionReview describes an admission review request/response.
#AdmissionReview: {
metav1.#TypeMeta
// Request describes the attributes for the admission request.
// +optional
request?: null | #AdmissionRequest @go(Request,*AdmissionRequest) @protobuf(1,bytes,opt)
// Response describes the attributes for the admission response.
// +optional
response?: null | #AdmissionResponse @go(Response,*AdmissionResponse) @protobuf(2,bytes,opt)
}
// AdmissionRequest describes the admission.Attributes for the admission request.
#AdmissionRequest: {
// UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
uid: types.#UID @go(UID) @protobuf(1,bytes,opt)
// Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)
kind: metav1.#GroupVersionKind @go(Kind) @protobuf(2,bytes,opt)
// Resource is the fully-qualified resource being requested (for example, v1.pods)
resource: metav1.#GroupVersionResource @go(Resource) @protobuf(3,bytes,opt)
// SubResource is the subresource being requested, if any (for example, "status" or "scale")
// +optional
subResource?: string @go(SubResource) @protobuf(4,bytes,opt)
// RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale).
// If this is specified and differs from the value in "kind", an equivalent match and conversion was performed.
//
// For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of
// `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`,
// an API request to apps/v1beta1 deployments would be converted and sent to the webhook
// with `kind: {group:"apps", version:"v1", kind:"Deployment"}` (matching the rule the webhook registered for),
// and `requestKind: {group:"apps", version:"v1beta1", kind:"Deployment"}` (indicating the kind of the original API request).
//
// See documentation for the "matchPolicy" field in the webhook configuration type for more details.
// +optional
requestKind?: null | metav1.#GroupVersionKind @go(RequestKind,*metav1.GroupVersionKind) @protobuf(13,bytes,opt)
// RequestResource is the fully-qualified resource of the original API request (for example, v1.pods).
// If this is specified and differs from the value in "resource", an equivalent match and conversion was performed.
//
// For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of
// `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`,
// an API request to apps/v1beta1 deployments would be converted and sent to the webhook
// with `resource: {group:"apps", version:"v1", resource:"deployments"}` (matching the resource the webhook registered for),
// and `requestResource: {group:"apps", version:"v1beta1", resource:"deployments"}` (indicating the resource of the original API request).
//
// See documentation for the "matchPolicy" field in the webhook configuration type.
// +optional
requestResource?: null | metav1.#GroupVersionResource @go(RequestResource,*metav1.GroupVersionResource) @protobuf(14,bytes,opt)
// RequestSubResource is the name of the subresource of the original API request, if any (for example, "status" or "scale")
// If this is specified and differs from the value in "subResource", an equivalent match and conversion was performed.
// See documentation for the "matchPolicy" field in the webhook configuration type.
// +optional
requestSubResource?: string @go(RequestSubResource) @protobuf(15,bytes,opt)
// Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and
// rely on the server to generate the name. If that is the case, this field will contain an empty string.
// +optional
name?: string @go(Name) @protobuf(5,bytes,opt)
// Namespace is the namespace associated with the request (if any).
// +optional
namespace?: string @go(Namespace) @protobuf(6,bytes,opt)
// Operation is the operation being performed. This may be different than the operation
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
operation: #Operation @go(Operation) @protobuf(7,bytes,opt)
// UserInfo is information about the requesting user
userInfo: authenticationv1.#UserInfo @go(UserInfo) @protobuf(8,bytes,opt)
// Object is the object from the incoming request.
// +optional
object?: runtime.#RawExtension @go(Object) @protobuf(9,bytes,opt)
// OldObject is the existing object. Only populated for DELETE and UPDATE requests.
// +optional
oldObject?: runtime.#RawExtension @go(OldObject) @protobuf(10,bytes,opt)
// DryRun indicates that modifications will definitely not be persisted for this request.
// Defaults to false.
// +optional
dryRun?: null | bool @go(DryRun,*bool) @protobuf(11,varint,opt)
// Options is the operation option structure of the operation being performed.
// e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be
// different than the options the caller provided. e.g. for a patch request the performed
// Operation might be a CREATE, in which case the Options will a
// `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.
// +optional
options?: runtime.#RawExtension @go(Options) @protobuf(12,bytes,opt)
}
// AdmissionResponse describes an admission response.
#AdmissionResponse: {
// UID is an identifier for the individual request/response.
// This must be copied over from the corresponding AdmissionRequest.
uid: types.#UID @go(UID) @protobuf(1,bytes,opt)
// Allowed indicates whether or not the admission request was permitted.
allowed: bool @go(Allowed) @protobuf(2,varint,opt)
// Result contains extra details into why an admission request was denied.
// This field IS NOT consulted in any way if "Allowed" is "true".
// +optional
status?: null | metav1.#Status @go(Result,*metav1.Status) @protobuf(3,bytes,opt)
// The patch body. Currently we only support "JSONPatch" which implements RFC 6902.
// +optional
patch?: bytes @go(Patch,[]byte) @protobuf(4,bytes,opt)
// The type of Patch. Currently we only allow "JSONPatch".
// +optional
patchType?: null | #PatchType @go(PatchType,*PatchType) @protobuf(5,bytes,opt)
// AuditAnnotations is an unstructured key value map set by remote admission controller (e.g. error=image-blacklisted).
// MutatingAdmissionWebhook and ValidatingAdmissionWebhook admission controller will prefix the keys with
// admission webhook name (e.g. imagepolicy.example.com/error=image-blacklisted). AuditAnnotations will be provided by
// the admission webhook to add additional context to the audit log for this request.
// +optional
auditAnnotations?: {[string]: string} @go(AuditAnnotations,map[string]string) @protobuf(6,bytes,opt)
// warnings is a list of warning messages to return to the requesting API client.
// Warning messages describe a problem the client making the API request should correct or be aware of.
// Limit warnings to 120 characters if possible.
// Warnings over 256 characters and large numbers of warnings may be truncated.
// +optional
warnings?: [...string] @go(Warnings,[]string) @protobuf(7,bytes,rep)
}
// PatchType is the type of patch being used to represent the mutated object
#PatchType: string // #enumPatchType
#enumPatchType:
#PatchTypeJSONPatch
#PatchTypeJSONPatch: #PatchType & "JSONPatch"
// Operation is the type of resource operation being checked for admission control
#Operation: string // #enumOperation
#enumOperation:
#Create |
#Update |
#Delete |
#Connect
#Create: #Operation & "CREATE"
#Update: #Operation & "UPDATE"
#Delete: #Operation & "DELETE"
#Connect: #Operation & "CONNECT"

View File

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

View File

@@ -0,0 +1,172 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/admission/v1beta1
package v1beta1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
authenticationv1 "k8s.io/api/authentication/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// AdmissionReview describes an admission review request/response.
#AdmissionReview: {
metav1.#TypeMeta
// Request describes the attributes for the admission request.
// +optional
request?: null | #AdmissionRequest @go(Request,*AdmissionRequest) @protobuf(1,bytes,opt)
// Response describes the attributes for the admission response.
// +optional
response?: null | #AdmissionResponse @go(Response,*AdmissionResponse) @protobuf(2,bytes,opt)
}
// AdmissionRequest describes the admission.Attributes for the admission request.
#AdmissionRequest: {
// UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
uid: types.#UID @go(UID) @protobuf(1,bytes,opt)
// Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)
kind: metav1.#GroupVersionKind @go(Kind) @protobuf(2,bytes,opt)
// Resource is the fully-qualified resource being requested (for example, v1.pods)
resource: metav1.#GroupVersionResource @go(Resource) @protobuf(3,bytes,opt)
// SubResource is the subresource being requested, if any (for example, "status" or "scale")
// +optional
subResource?: string @go(SubResource) @protobuf(4,bytes,opt)
// RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale).
// If this is specified and differs from the value in "kind", an equivalent match and conversion was performed.
//
// For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of
// `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`,
// an API request to apps/v1beta1 deployments would be converted and sent to the webhook
// with `kind: {group:"apps", version:"v1", kind:"Deployment"}` (matching the rule the webhook registered for),
// and `requestKind: {group:"apps", version:"v1beta1", kind:"Deployment"}` (indicating the kind of the original API request).
//
// See documentation for the "matchPolicy" field in the webhook configuration type for more details.
// +optional
requestKind?: null | metav1.#GroupVersionKind @go(RequestKind,*metav1.GroupVersionKind) @protobuf(13,bytes,opt)
// RequestResource is the fully-qualified resource of the original API request (for example, v1.pods).
// If this is specified and differs from the value in "resource", an equivalent match and conversion was performed.
//
// For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of
// `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`,
// an API request to apps/v1beta1 deployments would be converted and sent to the webhook
// with `resource: {group:"apps", version:"v1", resource:"deployments"}` (matching the resource the webhook registered for),
// and `requestResource: {group:"apps", version:"v1beta1", resource:"deployments"}` (indicating the resource of the original API request).
//
// See documentation for the "matchPolicy" field in the webhook configuration type.
// +optional
requestResource?: null | metav1.#GroupVersionResource @go(RequestResource,*metav1.GroupVersionResource) @protobuf(14,bytes,opt)
// RequestSubResource is the name of the subresource of the original API request, if any (for example, "status" or "scale")
// If this is specified and differs from the value in "subResource", an equivalent match and conversion was performed.
// See documentation for the "matchPolicy" field in the webhook configuration type.
// +optional
requestSubResource?: string @go(RequestSubResource) @protobuf(15,bytes,opt)
// Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and
// rely on the server to generate the name. If that is the case, this field will contain an empty string.
// +optional
name?: string @go(Name) @protobuf(5,bytes,opt)
// Namespace is the namespace associated with the request (if any).
// +optional
namespace?: string @go(Namespace) @protobuf(6,bytes,opt)
// Operation is the operation being performed. This may be different than the operation
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
operation: #Operation @go(Operation) @protobuf(7,bytes,opt)
// UserInfo is information about the requesting user
userInfo: authenticationv1.#UserInfo @go(UserInfo) @protobuf(8,bytes,opt)
// Object is the object from the incoming request.
// +optional
object?: runtime.#RawExtension @go(Object) @protobuf(9,bytes,opt)
// OldObject is the existing object. Only populated for DELETE and UPDATE requests.
// +optional
oldObject?: runtime.#RawExtension @go(OldObject) @protobuf(10,bytes,opt)
// DryRun indicates that modifications will definitely not be persisted for this request.
// Defaults to false.
// +optional
dryRun?: null | bool @go(DryRun,*bool) @protobuf(11,varint,opt)
// Options is the operation option structure of the operation being performed.
// e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be
// different than the options the caller provided. e.g. for a patch request the performed
// Operation might be a CREATE, in which case the Options will a
// `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.
// +optional
options?: runtime.#RawExtension @go(Options) @protobuf(12,bytes,opt)
}
// AdmissionResponse describes an admission response.
#AdmissionResponse: {
// UID is an identifier for the individual request/response.
// This should be copied over from the corresponding AdmissionRequest.
uid: types.#UID @go(UID) @protobuf(1,bytes,opt)
// Allowed indicates whether or not the admission request was permitted.
allowed: bool @go(Allowed) @protobuf(2,varint,opt)
// Result contains extra details into why an admission request was denied.
// This field IS NOT consulted in any way if "Allowed" is "true".
// +optional
status?: null | metav1.#Status @go(Result,*metav1.Status) @protobuf(3,bytes,opt)
// The patch body. Currently we only support "JSONPatch" which implements RFC 6902.
// +optional
patch?: bytes @go(Patch,[]byte) @protobuf(4,bytes,opt)
// The type of Patch. Currently we only allow "JSONPatch".
// +optional
patchType?: null | #PatchType @go(PatchType,*PatchType) @protobuf(5,bytes,opt)
// AuditAnnotations is an unstructured key value map set by remote admission controller (e.g. error=image-blacklisted).
// MutatingAdmissionWebhook and ValidatingAdmissionWebhook admission controller will prefix the keys with
// admission webhook name (e.g. imagepolicy.example.com/error=image-blacklisted). AuditAnnotations will be provided by
// the admission webhook to add additional context to the audit log for this request.
// +optional
auditAnnotations?: {[string]: string} @go(AuditAnnotations,map[string]string) @protobuf(6,bytes,opt)
// warnings is a list of warning messages to return to the requesting API client.
// Warning messages describe a problem the client making the API request should correct or be aware of.
// Limit warnings to 120 characters if possible.
// Warnings over 256 characters and large numbers of warnings may be truncated.
// +optional
warnings?: [...string] @go(Warnings,[]string) @protobuf(7,bytes,rep)
}
// PatchType is the type of patch being used to represent the mutated object
#PatchType: string // #enumPatchType
#enumPatchType:
#PatchTypeJSONPatch
#PatchTypeJSONPatch: #PatchType & "JSONPatch"
// Operation is the type of resource operation being checked for admission control
#Operation: string // #enumOperation
#enumOperation:
#Create |
#Update |
#Delete |
#Connect
#Create: #Operation & "CREATE"
#Update: #Operation & "UPDATE"
#Delete: #Operation & "DELETE"
#Connect: #Operation & "CONNECT"

View File

@@ -0,0 +1,9 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/admissionregistration/v1
// Package v1 is the v1 version of the API.
// AdmissionConfiguration and AdmissionPluginConfiguration are legacy static admission plugin configuration
// MutatingWebhookConfiguration and ValidatingWebhookConfiguration are for the
// new dynamic admission controller configuration.
package v1

View File

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

View File

@@ -0,0 +1,645 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/admissionregistration/v1
package v1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended
// to make sure that all the tuple expansions are valid.
#Rule: {
// APIGroups is the API groups the resources belong to. '*' is all groups.
// If '*' is present, the length of the slice must be one.
// Required.
// +listType=atomic
apiGroups?: [...string] @go(APIGroups,[]string) @protobuf(1,bytes,rep)
// APIVersions is the API versions the resources belong to. '*' is all versions.
// If '*' is present, the length of the slice must be one.
// Required.
// +listType=atomic
apiVersions?: [...string] @go(APIVersions,[]string) @protobuf(2,bytes,rep)
// Resources is a list of resources this rule applies to.
//
// For example:
// 'pods' means pods.
// 'pods/log' means the log subresource of pods.
// '*' means all resources, but not subresources.
// 'pods/*' means all subresources of pods.
// '*/scale' means all scale subresources.
// '*/*' means all resources and their subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// Depending on the enclosing object, subresources might not be allowed.
// Required.
// +listType=atomic
resources?: [...string] @go(Resources,[]string) @protobuf(3,bytes,rep)
// scope specifies the scope of this rule.
// Valid values are "Cluster", "Namespaced", and "*"
// "Cluster" means that only cluster-scoped resources will match this rule.
// Namespace API objects are cluster-scoped.
// "Namespaced" means that only namespaced resources will match this rule.
// "*" means that there are no scope restrictions.
// Subresources match the scope of their parent resource.
// Default is "*".
//
// +optional
scope?: null | #ScopeType @go(Scope,*ScopeType) @protobuf(4,bytes,rep)
}
// ScopeType specifies a scope for a Rule.
// +enum
#ScopeType: string // #enumScopeType
#enumScopeType:
#ClusterScope |
#NamespacedScope |
#AllScopes
// ClusterScope means that scope is limited to cluster-scoped objects.
// Namespace objects are cluster-scoped.
#ClusterScope: #ScopeType & "Cluster"
// NamespacedScope means that scope is limited to namespaced objects.
#NamespacedScope: #ScopeType & "Namespaced"
// AllScopes means that all scopes are included.
#AllScopes: #ScopeType & "*"
// FailurePolicyType specifies a failure policy that defines how unrecognized errors from the admission endpoint are handled.
// +enum
#FailurePolicyType: string // #enumFailurePolicyType
#enumFailurePolicyType:
#Ignore |
#Fail
// Ignore means that an error calling the webhook is ignored.
#Ignore: #FailurePolicyType & "Ignore"
// Fail means that an error calling the webhook causes the admission to fail.
#Fail: #FailurePolicyType & "Fail"
// MatchPolicyType specifies the type of match policy.
// +enum
#MatchPolicyType: string // #enumMatchPolicyType
#enumMatchPolicyType:
#Exact |
#Equivalent
// Exact means requests should only be sent to the webhook if they exactly match a given rule.
#Exact: #MatchPolicyType & "Exact"
// Equivalent means requests should be sent to the webhook if they modify a resource listed in rules via another API group or version.
#Equivalent: #MatchPolicyType & "Equivalent"
// SideEffectClass specifies the types of side effects a webhook may have.
// +enum
#SideEffectClass: string // #enumSideEffectClass
#enumSideEffectClass:
#SideEffectClassUnknown |
#SideEffectClassNone |
#SideEffectClassSome |
#SideEffectClassNoneOnDryRun
// SideEffectClassUnknown means that no information is known about the side effects of calling the webhook.
// If a request with the dry-run attribute would trigger a call to this webhook, the request will instead fail.
#SideEffectClassUnknown: #SideEffectClass & "Unknown"
// SideEffectClassNone means that calling the webhook will have no side effects.
#SideEffectClassNone: #SideEffectClass & "None"
// SideEffectClassSome means that calling the webhook will possibly have side effects.
// If a request with the dry-run attribute would trigger a call to this webhook, the request will instead fail.
#SideEffectClassSome: #SideEffectClass & "Some"
// SideEffectClassNoneOnDryRun means that calling the webhook will possibly have side effects, but if the
// request being reviewed has the dry-run attribute, the side effects will be suppressed.
#SideEffectClassNoneOnDryRun: #SideEffectClass & "NoneOnDryRun"
// ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.
#ValidatingWebhookConfiguration: {
metav1.#TypeMeta
// Standard object 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)
// Webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
webhooks?: [...#ValidatingWebhook] @go(Webhooks,[]ValidatingWebhook) @protobuf(2,bytes,rep,name=Webhooks)
}
// ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.
#ValidatingWebhookConfigurationList: {
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 ValidatingWebhookConfiguration.
items: [...#ValidatingWebhookConfiguration] @go(Items,[]ValidatingWebhookConfiguration) @protobuf(2,bytes,rep)
}
// MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object.
#MutatingWebhookConfiguration: {
metav1.#TypeMeta
// Standard object 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)
// Webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
webhooks?: [...#MutatingWebhook] @go(Webhooks,[]MutatingWebhook) @protobuf(2,bytes,rep,name=Webhooks)
}
// MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.
#MutatingWebhookConfigurationList: {
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 MutatingWebhookConfiguration.
items: [...#MutatingWebhookConfiguration] @go(Items,[]MutatingWebhookConfiguration) @protobuf(2,bytes,rep)
}
// ValidatingWebhook describes an admission webhook and the resources and operations it applies to.
#ValidatingWebhook: {
// The name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
name: string @go(Name) @protobuf(1,bytes,opt)
// ClientConfig defines how to communicate with the hook.
// Required
clientConfig: #WebhookClientConfig @go(ClientConfig) @protobuf(2,bytes,opt)
// Rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
// disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called
// on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.
rules?: [...#RuleWithOperations] @go(Rules,[]RuleWithOperations) @protobuf(3,bytes,rep)
// FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Fail.
// +optional
failurePolicy?: null | #FailurePolicyType @go(FailurePolicy,*FailurePolicyType) @protobuf(4,bytes,opt,casttype=FailurePolicyType)
// matchPolicy defines how the "rules" list is used to match incoming requests.
// Allowed values are "Exact" or "Equivalent".
//
// - Exact: match a request only if it exactly matches a specified rule.
// For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1,
// but "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`,
// a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.
//
// - Equivalent: match a request if modifies a resource listed in rules, even via another API group or version.
// For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1,
// and "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`,
// a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.
//
// Defaults to "Equivalent"
// +optional
matchPolicy?: null | #MatchPolicyType @go(MatchPolicy,*MatchPolicyType) @protobuf(9,bytes,opt,casttype=MatchPolicyType)
// NamespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
// it never skips the webhook.
//
// For example, to run the webhook on any objects whose namespace is not
// associated with "runlevel" of "0" or "1"; you will set the selector as
// follows:
// "namespaceSelector": {
// "matchExpressions": [
// {
// "key": "runlevel",
// "operator": "NotIn",
// "values": [
// "0",
// "1"
// ]
// }
// ]
// }
//
// If instead you want to only run the webhook on any objects whose
// namespace is associated with the "environment" of "prod" or "staging";
// you will set the selector as follows:
// "namespaceSelector": {
// "matchExpressions": [
// {
// "key": "environment",
// "operator": "In",
// "values": [
// "prod",
// "staging"
// ]
// }
// ]
// }
//
// See
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
// for more examples of label selectors.
//
// Default to the empty LabelSelector, which matches everything.
// +optional
namespaceSelector?: null | metav1.#LabelSelector @go(NamespaceSelector,*metav1.LabelSelector) @protobuf(5,bytes,opt)
// ObjectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
// object (oldObject in the case of create, or newObject in the case of
// delete) or an object that cannot have labels (like a
// DeploymentRollback or a PodProxyOptions object) is not considered to
// match.
// Use the object selector only if the webhook is opt-in, because end
// users may skip the admission webhook by setting the labels.
// Default to the empty LabelSelector, which matches everything.
// +optional
objectSelector?: null | metav1.#LabelSelector @go(ObjectSelector,*metav1.LabelSelector) @protobuf(10,bytes,opt)
// SideEffects states whether this webhook has side effects.
// Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown).
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
// Requests with the dryRun attribute will be auto-rejected if they match a webhook with
// sideEffects == Unknown or Some.
sideEffects?: null | #SideEffectClass @go(SideEffects,*SideEffectClass) @protobuf(6,bytes,opt,casttype=SideEffectClass)
// TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
// Default to 10 seconds.
// +optional
timeoutSeconds?: null | int32 @go(TimeoutSeconds,*int32) @protobuf(7,varint,opt)
// AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
// If a persisted webhook configuration specifies allowed versions and does not
// include any versions known to the API Server, calls to the webhook will fail
// and be subject to the failure policy.
admissionReviewVersions: [...string] @go(AdmissionReviewVersions,[]string) @protobuf(8,bytes,rep)
// MatchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
//
// The exact matching logic is (in order):
// 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.
// 2. If ALL matchConditions evaluate to TRUE, the webhook is called.
// 3. If any matchCondition evaluates to an error (but none are FALSE):
// - If failurePolicy=Fail, reject the request
// - If failurePolicy=Ignore, the error is ignored and the webhook is skipped
//
// This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.
//
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +featureGate=AdmissionWebhookMatchConditions
// +optional
matchConditions?: [...#MatchCondition] @go(MatchConditions,[]MatchCondition) @protobuf(11,bytes,opt)
}
// MutatingWebhook describes an admission webhook and the resources and operations it applies to.
#MutatingWebhook: {
// The name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
name: string @go(Name) @protobuf(1,bytes,opt)
// ClientConfig defines how to communicate with the hook.
// Required
clientConfig: #WebhookClientConfig @go(ClientConfig) @protobuf(2,bytes,opt)
// Rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
// disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called
// on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.
rules?: [...#RuleWithOperations] @go(Rules,[]RuleWithOperations) @protobuf(3,bytes,rep)
// FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Fail.
// +optional
failurePolicy?: null | #FailurePolicyType @go(FailurePolicy,*FailurePolicyType) @protobuf(4,bytes,opt,casttype=FailurePolicyType)
// matchPolicy defines how the "rules" list is used to match incoming requests.
// Allowed values are "Exact" or "Equivalent".
//
// - Exact: match a request only if it exactly matches a specified rule.
// For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1,
// but "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`,
// a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.
//
// - Equivalent: match a request if modifies a resource listed in rules, even via another API group or version.
// For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1,
// and "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`,
// a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.
//
// Defaults to "Equivalent"
// +optional
matchPolicy?: null | #MatchPolicyType @go(MatchPolicy,*MatchPolicyType) @protobuf(9,bytes,opt,casttype=MatchPolicyType)
// NamespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
// it never skips the webhook.
//
// For example, to run the webhook on any objects whose namespace is not
// associated with "runlevel" of "0" or "1"; you will set the selector as
// follows:
// "namespaceSelector": {
// "matchExpressions": [
// {
// "key": "runlevel",
// "operator": "NotIn",
// "values": [
// "0",
// "1"
// ]
// }
// ]
// }
//
// If instead you want to only run the webhook on any objects whose
// namespace is associated with the "environment" of "prod" or "staging";
// you will set the selector as follows:
// "namespaceSelector": {
// "matchExpressions": [
// {
// "key": "environment",
// "operator": "In",
// "values": [
// "prod",
// "staging"
// ]
// }
// ]
// }
//
// See
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
// for more examples of label selectors.
//
// Default to the empty LabelSelector, which matches everything.
// +optional
namespaceSelector?: null | metav1.#LabelSelector @go(NamespaceSelector,*metav1.LabelSelector) @protobuf(5,bytes,opt)
// ObjectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
// object (oldObject in the case of create, or newObject in the case of
// delete) or an object that cannot have labels (like a
// DeploymentRollback or a PodProxyOptions object) is not considered to
// match.
// Use the object selector only if the webhook is opt-in, because end
// users may skip the admission webhook by setting the labels.
// Default to the empty LabelSelector, which matches everything.
// +optional
objectSelector?: null | metav1.#LabelSelector @go(ObjectSelector,*metav1.LabelSelector) @protobuf(11,bytes,opt)
// SideEffects states whether this webhook has side effects.
// Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown).
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
// Requests with the dryRun attribute will be auto-rejected if they match a webhook with
// sideEffects == Unknown or Some.
sideEffects?: null | #SideEffectClass @go(SideEffects,*SideEffectClass) @protobuf(6,bytes,opt,casttype=SideEffectClass)
// TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
// Default to 10 seconds.
// +optional
timeoutSeconds?: null | int32 @go(TimeoutSeconds,*int32) @protobuf(7,varint,opt)
// AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
// If a persisted webhook configuration specifies allowed versions and does not
// include any versions known to the API Server, calls to the webhook will fail
// and be subject to the failure policy.
admissionReviewVersions: [...string] @go(AdmissionReviewVersions,[]string) @protobuf(8,bytes,rep)
// reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation.
// Allowed values are "Never" and "IfNeeded".
//
// Never: the webhook will not be called more than once in a single admission evaluation.
//
// IfNeeded: the webhook will be called at least one additional time as part of the admission evaluation
// if the object being admitted is modified by other admission plugins after the initial webhook call.
// Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted.
// Note:
// * the number of additional invocations is not guaranteed to be exactly one.
// * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again.
// * webhooks that use this option may be reordered to minimize the number of additional invocations.
// * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.
//
// Defaults to "Never".
// +optional
reinvocationPolicy?: null | #ReinvocationPolicyType @go(ReinvocationPolicy,*ReinvocationPolicyType) @protobuf(10,bytes,opt,casttype=ReinvocationPolicyType)
// MatchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
//
// The exact matching logic is (in order):
// 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.
// 2. If ALL matchConditions evaluate to TRUE, the webhook is called.
// 3. If any matchCondition evaluates to an error (but none are FALSE):
// - If failurePolicy=Fail, reject the request
// - If failurePolicy=Ignore, the error is ignored and the webhook is skipped
//
// This is a beta feature and managed by the AdmissionWebhookMatchConditions feature gate.
//
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +featureGate=AdmissionWebhookMatchConditions
// +optional
matchConditions?: [...#MatchCondition] @go(MatchConditions,[]MatchCondition) @protobuf(12,bytes,opt)
}
// ReinvocationPolicyType specifies what type of policy the admission hook uses.
// +enum
#ReinvocationPolicyType: string // #enumReinvocationPolicyType
#enumReinvocationPolicyType:
#NeverReinvocationPolicy |
#IfNeededReinvocationPolicy
// NeverReinvocationPolicy indicates that the webhook must not be called more than once in a
// single admission evaluation.
#NeverReinvocationPolicy: #ReinvocationPolicyType & "Never"
// IfNeededReinvocationPolicy indicates that the webhook may be called at least one
// additional time as part of the admission evaluation if the object being admitted is
// modified by other admission plugins after the initial webhook call.
#IfNeededReinvocationPolicy: #ReinvocationPolicyType & "IfNeeded"
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
// sure that all the tuple expansions are valid.
#RuleWithOperations: {
// Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or *
// for all of those operations and any future admission operations that are added.
// If '*' is present, the length of the slice must be one.
// Required.
// +listType=atomic
operations?: [...#OperationType] @go(Operations,[]OperationType) @protobuf(1,bytes,rep,casttype=OperationType)
#Rule
}
// OperationType specifies an operation for a request.
// +enum
#OperationType: string // #enumOperationType
#enumOperationType:
#OperationAll |
#Create |
#Update |
#Delete |
#Connect
#OperationAll: #OperationType & "*"
#Create: #OperationType & "CREATE"
#Update: #OperationType & "UPDATE"
#Delete: #OperationType & "DELETE"
#Connect: #OperationType & "CONNECT"
// WebhookClientConfig contains the information to make a TLS
// connection with the webhook
#WebhookClientConfig: {
// `url` gives the location of the webhook, in standard URL form
// (`scheme://host:port/path`). Exactly one of `url` or `service`
// must be specified.
//
// The `host` should not refer to a service running in the cluster; use
// the `service` field instead. The host might be resolved via external
// DNS in some apiservers (e.g., `kube-apiserver` cannot resolve
// in-cluster DNS as that would be a layering violation). `host` may
// also be an IP address.
//
// Please note that using `localhost` or `127.0.0.1` as a `host` is
// risky unless you take great care to run this webhook on all hosts
// which run an apiserver which might need to make calls to this
// webhook. Such installs are likely to be non-portable, i.e., not easy
// to turn up in a new cluster.
//
// The scheme must be "https"; the URL must begin with "https://".
//
// A path is optional, and if present may be any string permissible in
// a URL. You may use the path to pass an arbitrary string to the
// webhook, for example, a cluster identifier.
//
// Attempting to use a user or basic auth e.g. "user:password@" is not
// allowed. Fragments ("#...") and query parameters ("?...") are not
// allowed, either.
//
// +optional
url?: null | string @go(URL,*string) @protobuf(3,bytes,opt)
// `service` is a reference to the service for this webhook. Either
// `service` or `url` must be specified.
//
// If the webhook is running within the cluster, then you should use `service`.
//
// +optional
service?: null | #ServiceReference @go(Service,*ServiceReference) @protobuf(1,bytes,opt)
// `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// If unspecified, system trust roots on the apiserver are used.
// +optional
caBundle?: bytes @go(CABundle,[]byte) @protobuf(2,bytes,opt)
}
// ServiceReference holds a reference to Service.legacy.k8s.io
#ServiceReference: {
// `namespace` is the namespace of the service.
// Required
namespace: string @go(Namespace) @protobuf(1,bytes,opt)
// `name` is the name of the service.
// Required
name: string @go(Name) @protobuf(2,bytes,opt)
// `path` is an optional URL path which will be sent in any request to
// this service.
// +optional
path?: null | string @go(Path,*string) @protobuf(3,bytes,opt)
// If specified, the port on the service that hosting webhook.
// Default to 443 for backward compatibility.
// `port` should be a valid port number (1-65535, inclusive).
// +optional
port?: null | int32 @go(Port,*int32) @protobuf(4,varint,opt)
}
// MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook.
#MatchCondition: {
// Name is an identifier for this match condition, used for strategic merging of MatchConditions,
// as well as providing an identifier for logging purposes. A good name should be descriptive of
// the associated expression.
// Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and
// must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or
// '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an
// optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')
//
// Required.
name: string @go(Name) @protobuf(1,bytes,opt)
// Expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
// CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:
//
// 'object' - The object from the incoming request. The value is null for DELETE requests.
// 'oldObject' - The existing object. The value is null for CREATE requests.
// 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest).
// 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.
// See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
// 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the
// request resource.
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
//
// Required.
expression: string @go(Expression) @protobuf(2,bytes,opt)
}

View File

@@ -0,0 +1,6 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/admissionregistration/v1alpha1
// Package v1alpha1 is the v1alpha1 version of the API.
package v1alpha1

View File

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

View File

@@ -0,0 +1,679 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/admissionregistration/v1alpha1
package v1alpha1
import (
"k8s.io/api/admissionregistration/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended
// to make sure that all the tuple expansions are valid.
#Rule: v1.#Rule
// ScopeType specifies a scope for a Rule.
// +enum
#ScopeType: v1.#ScopeType // #enumScopeType
#enumScopeType:
#ClusterScope |
#NamespacedScope |
#AllScopes
// ClusterScope means that scope is limited to cluster-scoped objects.
// Namespace objects are cluster-scoped.
#ClusterScope: v1.#ScopeType & "Cluster"
// NamespacedScope means that scope is limited to namespaced objects.
#NamespacedScope: v1.#ScopeType & "Namespaced"
// AllScopes means that all scopes are included.
#AllScopes: v1.#ScopeType & "*"
// ParameterNotFoundActionType specifies a failure policy that defines how a binding
// is evaluated when the param referred by its perNamespaceParamRef is not found.
// +enum
#ParameterNotFoundActionType: string // #enumParameterNotFoundActionType
#enumParameterNotFoundActionType:
#AllowAction |
#DenyAction
// Ignore means that an error finding params for a binding is ignored
#AllowAction: #ParameterNotFoundActionType & "Allow"
// Fail means that an error finding params for a binding is ignored
#DenyAction: #ParameterNotFoundActionType & "Deny"
// FailurePolicyType specifies a failure policy that defines how unrecognized errors from the admission endpoint are handled.
// +enum
#FailurePolicyType: string // #enumFailurePolicyType
#enumFailurePolicyType:
#Ignore |
#Fail
// Ignore means that an error calling the webhook is ignored.
#Ignore: #FailurePolicyType & "Ignore"
// Fail means that an error calling the webhook causes the admission to fail.
#Fail: #FailurePolicyType & "Fail"
// MatchPolicyType specifies the type of match policy.
// +enum
#MatchPolicyType: string // #enumMatchPolicyType
#enumMatchPolicyType:
#Exact |
#Equivalent
// Exact means requests should only be sent to the webhook if they exactly match a given rule.
#Exact: #MatchPolicyType & "Exact"
// Equivalent means requests should be sent to the webhook if they modify a resource listed in rules via another API group or version.
#Equivalent: #MatchPolicyType & "Equivalent"
// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.
#ValidatingAdmissionPolicy: {
metav1.#TypeMeta
// Standard object 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 ValidatingAdmissionPolicy.
spec?: #ValidatingAdmissionPolicySpec @go(Spec) @protobuf(2,bytes,opt)
// The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
// behaves in the expected way.
// Populated by the system.
// Read-only.
// +optional
status?: #ValidatingAdmissionPolicyStatus @go(Status) @protobuf(3,bytes,opt)
}
// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.
#ValidatingAdmissionPolicyStatus: {
// The generation observed by the controller.
// +optional
observedGeneration?: int64 @go(ObservedGeneration) @protobuf(1,varint,opt)
// The results of type checking for each expression.
// Presence of this field indicates the completion of the type checking.
// +optional
typeChecking?: null | #TypeChecking @go(TypeChecking,*TypeChecking) @protobuf(2,bytes,opt)
// The conditions represent the latest available observations of a policy's current state.
// +optional
// +listType=map
// +listMapKey=type
conditions?: [...metav1.#Condition] @go(Conditions,[]metav1.Condition) @protobuf(3,bytes,rep)
}
// TypeChecking contains results of type checking the expressions in the
// ValidatingAdmissionPolicy
#TypeChecking: {
// The type checking warnings for each expression.
// +optional
// +listType=atomic
expressionWarnings?: [...#ExpressionWarning] @go(ExpressionWarnings,[]ExpressionWarning) @protobuf(1,bytes,rep)
}
// ExpressionWarning is a warning information that targets a specific expression.
#ExpressionWarning: {
// The path to the field that refers the expression.
// For example, the reference to the expression of the first item of
// validations is "spec.validations[0].expression"
fieldRef: string @go(FieldRef) @protobuf(2,bytes,opt)
// The content of type checking information in a human-readable form.
// Each line of the warning contains the type that the expression is checked
// against, followed by the type check error from the compiler.
warning: string @go(Warning) @protobuf(3,bytes,opt)
}
// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.
#ValidatingAdmissionPolicyList: {
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 ValidatingAdmissionPolicy.
items?: [...#ValidatingAdmissionPolicy] @go(Items,[]ValidatingAdmissionPolicy) @protobuf(2,bytes,rep)
}
// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.
#ValidatingAdmissionPolicySpec: {
// ParamKind specifies the kind of resources used to parameterize this policy.
// If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
// If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
// If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.
// +optional
paramKind?: null | #ParamKind @go(ParamKind,*ParamKind) @protobuf(1,bytes,rep)
// MatchConstraints specifies what resources this policy is designed to validate.
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
// However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
// ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding.
// Required.
matchConstraints?: null | #MatchResources @go(MatchConstraints,*MatchResources) @protobuf(2,bytes,rep)
// Validations contain CEL expressions which is used to apply the validation.
// Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is
// required.
// +listType=atomic
// +optional
validations?: [...#Validation] @go(Validations,[]Validation) @protobuf(3,bytes,rep)
// failurePolicy defines how to handle failures for the admission policy. Failures can
// occur from CEL expression parse errors, type check errors, runtime errors and invalid
// or mis-configured policy definitions or bindings.
//
// A policy is invalid if spec.paramKind refers to a non-existent Kind.
// A binding is invalid if spec.paramRef.name refers to a non-existent resource.
//
// failurePolicy does not define how validations that evaluate to false are handled.
//
// When failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions
// define how failures are enforced.
//
// Allowed values are Ignore or Fail. Defaults to Fail.
// +optional
failurePolicy?: null | #FailurePolicyType @go(FailurePolicy,*FailurePolicyType) @protobuf(4,bytes,opt,casttype=FailurePolicyType)
// auditAnnotations contains CEL expressions which are used to produce audit
// annotations for the audit event of the API request.
// validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is
// required.
// +listType=atomic
// +optional
auditAnnotations?: [...#AuditAnnotation] @go(AuditAnnotations,[]AuditAnnotation) @protobuf(5,bytes,rep)
// MatchConditions is a list of conditions that must be met for a request to be validated.
// Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
//
// If a parameter object is provided, it can be accessed via the `params` handle in the same
// manner as validation expressions.
//
// The exact matching logic is (in order):
// 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.
// 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.
// 3. If any matchCondition evaluates to an error (but none are FALSE):
// - If failurePolicy=Fail, reject the request
// - If failurePolicy=Ignore, the policy is skipped
//
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +optional
matchConditions?: [...#MatchCondition] @go(MatchConditions,[]MatchCondition) @protobuf(6,bytes,rep)
// Variables contain definitions of variables that can be used in composition of other expressions.
// Each variable is defined as a named CEL expression.
// The variables defined here will be available under `variables` in other expressions of the policy
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
//
// The expression of a variable can refer to other variables defined earlier in the list but not those after.
// Thus, Variables must be sorted by the order of first appearance and acyclic.
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +optional
variables?: [...#Variable] @go(Variables,[]Variable) @protobuf(7,bytes,rep)
}
#MatchCondition: v1.#MatchCondition
// ParamKind is a tuple of Group Kind and Version.
// +structType=atomic
#ParamKind: {
// APIVersion is the API group version the resources belong to.
// In format of "group/version".
// Required.
apiVersion?: string @go(APIVersion) @protobuf(1,bytes,rep)
// Kind is the API kind the resources belong to.
// Required.
kind?: string @go(Kind) @protobuf(2,bytes,rep)
}
// Validation specifies the CEL expression which is used to apply the validation.
#Validation: {
// Expression represents the expression which will be evaluated by CEL.
// ref: https://github.com/google/cel-spec
// CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:
//
// - 'object' - The object from the incoming request. The value is null for DELETE requests.
// - 'oldObject' - The existing object. The value is null for CREATE requests.
// - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)).
// - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind.
// - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources.
// - 'variables' - Map of composited variables, from its name to its lazily evaluated value.
// For example, a variable named 'foo' can be accessed as 'variables.foo'.
// - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.
// See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
// - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the
// request resource.
//
// The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the
// object. No other metadata properties are accessible.
//
// Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible.
// Accessible property names are escaped according to the following rules when accessed in the expression:
// - '__' escapes to '__underscores__'
// - '.' escapes to '__dot__'
// - '-' escapes to '__dash__'
// - '/' escapes to '__slash__'
// - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:
// "true", "false", "null", "in", "as", "break", "const", "continue", "else", "for", "function", "if",
// "import", "let", "loop", "package", "namespace", "return".
// Examples:
// - Expression accessing a property named "namespace": {"Expression": "object.__namespace__ > 0"}
// - Expression accessing a property named "x-prop": {"Expression": "object.x__dash__prop > 0"}
// - Expression accessing a property named "redact__d": {"Expression": "object.redact__underscores__d > 0"}
//
// Equality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1].
// Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:
// - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and
// non-intersecting elements in `Y` are appended, retaining their partial order.
// - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values
// are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with
// non-intersecting keys are appended, retaining their partial order.
// Required.
expression: string @go(Expression) @protobuf(1,bytes,opt,name=Expression)
// Message represents the message displayed when validation fails. The message is required if the Expression contains
// line breaks. The message must not contain line breaks.
// If unset, the message is "failed rule: {Rule}".
// e.g. "must be a URL with the host matching spec.host"
// If the Expression contains line breaks. Message is required.
// The message must not contain line breaks.
// If unset, the message is "failed Expression: {Expression}".
// +optional
message?: string @go(Message) @protobuf(2,bytes,opt)
// Reason represents a machine-readable description of why this validation failed.
// If this is the first validation in the list to fail, this reason, as well as the
// corresponding HTTP response code, are used in the
// HTTP response to the client.
// The currently supported reasons are: "Unauthorized", "Forbidden", "Invalid", "RequestEntityTooLarge".
// If not set, StatusReasonInvalid is used in the response to the client.
// +optional
reason?: null | metav1.#StatusReason @go(Reason,*metav1.StatusReason) @protobuf(3,bytes,opt)
// messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails.
// Since messageExpression is used as a failure message, it must evaluate to a string.
// If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails.
// If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced
// as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string
// that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and
// the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged.
// messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'.
// Example:
// "object.x must be less than max ("+string(params.max)+")"
// +optional
messageExpression?: string @go(MessageExpression) @protobuf(4,bytes,opt)
}
// Variable is the definition of a variable that is used for composition.
#Variable: {
// Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
// The variable can be accessed in other expressions through `variables`
// For example, if name is "foo", the variable will be available as `variables.foo`
name: string @go(Name) @protobuf(1,bytes,opt,name=Name)
// Expression is the expression that will be evaluated as the value of the variable.
// The CEL expression has access to the same identifiers as the CEL expressions in Validation.
expression: string @go(Expression) @protobuf(2,bytes,opt,name=Expression)
}
// AuditAnnotation describes how to produce an audit annotation for an API request.
#AuditAnnotation: {
// key specifies the audit annotation key. The audit annotation keys of
// a ValidatingAdmissionPolicy must be unique. The key must be a qualified
// name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length.
//
// The key is combined with the resource name of the
// ValidatingAdmissionPolicy to construct an audit annotation key:
// "{ValidatingAdmissionPolicy name}/{key}".
//
// If an admission webhook uses the same resource name as this ValidatingAdmissionPolicy
// and the same audit annotation key, the annotation key will be identical.
// In this case, the first annotation written with the key will be included
// in the audit event and all subsequent annotations with the same key
// will be discarded.
//
// Required.
key: string @go(Key) @protobuf(1,bytes,opt)
// valueExpression represents the expression which is evaluated by CEL to
// produce an audit annotation value. The expression must evaluate to either
// a string or null value. If the expression evaluates to a string, the
// audit annotation is included with the string value. If the expression
// evaluates to null or empty string the audit annotation will be omitted.
// The valueExpression may be no longer than 5kb in length.
// If the result of the valueExpression is more than 10kb in length, it
// will be truncated to 10kb.
//
// If multiple ValidatingAdmissionPolicyBinding resources match an
// API request, then the valueExpression will be evaluated for
// each binding. All unique values produced by the valueExpressions
// will be joined together in a comma-separated list.
//
// Required.
valueExpression: string @go(ValueExpression) @protobuf(2,bytes,opt)
}
// ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources.
// ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters.
//
// For a given admission request, each binding will cause its policy to be
// evaluated N times, where N is 1 for policies/bindings that don't use
// params, otherwise N is the number of parameters selected by the binding.
//
// The CEL expressions of a policy must have a computed CEL cost below the maximum
// CEL budget. Each evaluation of the policy is given an independent CEL cost budget.
// Adding/removing policies, bindings, or params can not affect whether a
// given (policy, binding, param) combination is within its own CEL budget.
#ValidatingAdmissionPolicyBinding: {
metav1.#TypeMeta
// Standard object 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 ValidatingAdmissionPolicyBinding.
spec?: #ValidatingAdmissionPolicyBindingSpec @go(Spec) @protobuf(2,bytes,opt)
}
// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.
#ValidatingAdmissionPolicyBindingList: {
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 PolicyBinding.
items?: [...#ValidatingAdmissionPolicyBinding] @go(Items,[]ValidatingAdmissionPolicyBinding) @protobuf(2,bytes,rep)
}
// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.
#ValidatingAdmissionPolicyBindingSpec: {
// PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
// If the referenced resource does not exist, this binding is considered invalid and will be ignored
// Required.
policyName?: string @go(PolicyName) @protobuf(1,bytes,rep)
// paramRef specifies the parameter resource used to configure the admission control policy.
// It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy.
// If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied.
// If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.
// +optional
paramRef?: null | #ParamRef @go(ParamRef,*ParamRef) @protobuf(2,bytes,rep)
// MatchResources declares what resources match this binding and will be validated by it.
// Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this.
// If this is unset, all resources matched by the policy are validated by this binding
// When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated.
// Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.
// +optional
matchResources?: null | #MatchResources @go(MatchResources,*MatchResources) @protobuf(3,bytes,rep)
// validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced.
// If a validation evaluates to false it is always enforced according to these actions.
//
// Failures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according
// to these actions only if the FailurePolicy is set to Fail, otherwise the failures are
// ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.
//
// validationActions is declared as a set of action values. Order does
// not matter. validationActions may not contain duplicates of the same action.
//
// The supported actions values are:
//
// "Deny" specifies that a validation failure results in a denied request.
//
// "Warn" specifies that a validation failure is reported to the request client
// in HTTP Warning headers, with a warning code of 299. Warnings can be sent
// both for allowed or denied admission responses.
//
// "Audit" specifies that a validation failure is included in the published
// audit event for the request. The audit event will contain a
// `validation.policy.admission.k8s.io/validation_failure` audit annotation
// with a value containing the details of the validation failures, formatted as
// a JSON list of objects, each with the following fields:
// - message: The validation failure message string
// - policy: The resource name of the ValidatingAdmissionPolicy
// - binding: The resource name of the ValidatingAdmissionPolicyBinding
// - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy
// - validationActions: The enforcement actions enacted for the validation failure
// Example audit annotation:
// `"validation.policy.admission.k8s.io/validation_failure": "[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]"`
//
// Clients should expect to handle additional values by ignoring
// any values not recognized.
//
// "Deny" and "Warn" may not be used together since this combination
// needlessly duplicates the validation failure both in the
// API response body and the HTTP warning headers.
//
// Required.
// +listType=set
validationActions?: [...#ValidationAction] @go(ValidationActions,[]ValidationAction) @protobuf(4,bytes,rep)
}
// ParamRef describes how to locate the params to be used as input to
// expressions of rules applied by a policy binding.
// +structType=atomic
#ParamRef: {
// `name` is the name of the resource being referenced.
//
// `name` and `selector` are mutually exclusive properties. If one is set,
// the other must be unset.
//
// +optional
name?: string @go(Name) @protobuf(1,bytes,rep)
// namespace is the namespace of the referenced resource. Allows limiting
// the search for params to a specific namespace. Applies to both `name` and
// `selector` fields.
//
// A per-namespace parameter may be used by specifying a namespace-scoped
// `paramKind` in the policy and leaving this field empty.
//
// - If `paramKind` is cluster-scoped, this field MUST be unset. Setting this
// field results in a configuration error.
//
// - If `paramKind` is namespace-scoped, the namespace of the object being
// evaluated for admission will be used when this field is left unset. Take
// care that if this is left empty the binding must not match any cluster-scoped
// resources, which will result in an error.
//
// +optional
namespace?: string @go(Namespace) @protobuf(2,bytes,rep)
// selector can be used to match multiple param objects based on their labels.
// Supply selector: {} to match all resources of the ParamKind.
//
// If multiple params are found, they are all evaluated with the policy expressions
// and the results are ANDed together.
//
// One of `name` or `selector` must be set, but `name` and `selector` are
// mutually exclusive properties. If one is set, the other must be unset.
//
// +optional
selector?: null | metav1.#LabelSelector @go(Selector,*metav1.LabelSelector) @protobuf(3,bytes,rep)
// `parameterNotFoundAction` controls the behavior of the binding when the resource
// exists, and name or selector is valid, but there are no parameters
// matched by the binding. If the value is set to `Allow`, then no
// matched parameters will be treated as successful validation by the binding.
// If set to `Deny`, then no matched parameters will be subject to the
// `failurePolicy` of the policy.
//
// Allowed values are `Allow` or `Deny`
// Default to `Deny`
// +optional
parameterNotFoundAction?: null | #ParameterNotFoundActionType @go(ParameterNotFoundAction,*ParameterNotFoundActionType) @protobuf(4,bytes,rep)
}
// MatchResources decides whether to run the admission control policy on an object based
// on whether it meets the match criteria.
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +structType=atomic
#MatchResources: {
// NamespaceSelector decides whether to run the admission control policy on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
// it never skips the policy.
//
// For example, to run the webhook on any objects whose namespace is not
// associated with "runlevel" of "0" or "1"; you will set the selector as
// follows:
// "namespaceSelector": {
// "matchExpressions": [
// {
// "key": "runlevel",
// "operator": "NotIn",
// "values": [
// "0",
// "1"
// ]
// }
// ]
// }
//
// If instead you want to only run the policy on any objects whose
// namespace is associated with the "environment" of "prod" or "staging";
// you will set the selector as follows:
// "namespaceSelector": {
// "matchExpressions": [
// {
// "key": "environment",
// "operator": "In",
// "values": [
// "prod",
// "staging"
// ]
// }
// ]
// }
//
// See
// https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
// for more examples of label selectors.
//
// Default to the empty LabelSelector, which matches everything.
// +optional
namespaceSelector?: null | metav1.#LabelSelector @go(NamespaceSelector,*metav1.LabelSelector) @protobuf(1,bytes,opt)
// ObjectSelector decides whether to run the validation based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the cel validation, and
// is considered to match if either object matches the selector. A null
// object (oldObject in the case of create, or newObject in the case of
// delete) or an object that cannot have labels (like a
// DeploymentRollback or a PodProxyOptions object) is not considered to
// match.
// Use the object selector only if the webhook is opt-in, because end
// users may skip the admission webhook by setting the labels.
// Default to the empty LabelSelector, which matches everything.
// +optional
objectSelector?: null | metav1.#LabelSelector @go(ObjectSelector,*metav1.LabelSelector) @protobuf(2,bytes,opt)
// ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
// The policy cares about an operation if it matches _any_ Rule.
// +listType=atomic
// +optional
resourceRules?: [...#NamedRuleWithOperations] @go(ResourceRules,[]NamedRuleWithOperations) @protobuf(3,bytes,rep)
// ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +listType=atomic
// +optional
excludeResourceRules?: [...#NamedRuleWithOperations] @go(ExcludeResourceRules,[]NamedRuleWithOperations) @protobuf(4,bytes,rep)
// matchPolicy defines how the "MatchResources" list is used to match incoming requests.
// Allowed values are "Exact" or "Equivalent".
//
// - Exact: match a request only if it exactly matches a specified rule.
// For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1,
// but "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`,
// a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy.
//
// - Equivalent: match a request if modifies a resource listed in rules, even via another API group or version.
// For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1,
// and "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`,
// a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy.
//
// Defaults to "Equivalent"
// +optional
matchPolicy?: null | #MatchPolicyType @go(MatchPolicy,*MatchPolicyType) @protobuf(7,bytes,opt,casttype=MatchPolicyType)
}
// ValidationAction specifies a policy enforcement action.
// +enum
#ValidationAction: string // #enumValidationAction
#enumValidationAction:
#Deny |
#Warn |
#Audit
// Deny specifies that a validation failure results in a denied request.
#Deny: #ValidationAction & "Deny"
// Warn specifies that a validation failure is reported to the request client
// in HTTP Warning headers, with a warning code of 299. Warnings can be sent
// both for allowed or denied admission responses.
#Warn: #ValidationAction & "Warn"
// Audit specifies that a validation failure is included in the published
// audit event for the request. The audit event will contain a
// `validation.policy.admission.k8s.io/validation_failure` audit annotation
// with a value containing the details of the validation failure.
#Audit: #ValidationAction & "Audit"
// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.
// +structType=atomic
#NamedRuleWithOperations: {
// ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +listType=atomic
// +optional
resourceNames?: [...string] @go(ResourceNames,[]string) @protobuf(1,bytes,rep)
v1.#RuleWithOperations
}
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
// sure that all the tuple expansions are valid.
#RuleWithOperations: v1.#RuleWithOperations
// OperationType specifies an operation for a request.
// +enum
#OperationType: v1.#OperationType // #enumOperationType
#enumOperationType:
#OperationAll |
#Create |
#Update |
#Delete |
#Connect
#OperationAll: v1.#OperationType & "*"
#Create: v1.#OperationType & "CREATE"
#Update: v1.#OperationType & "UPDATE"
#Delete: v1.#OperationType & "DELETE"
#Connect: v1.#OperationType & "CONNECT"

View File

@@ -0,0 +1,9 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/admissionregistration/v1beta1
// Package v1beta1 is the v1beta1 version of the API.
// AdmissionConfiguration and AdmissionPluginConfiguration are legacy static admission plugin configuration
// MutatingWebhookConfiguration and ValidatingWebhookConfiguration are for the
// new dynamic admission controller configuration.
package v1beta1

View File

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

View File

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

View File

@@ -0,0 +1,157 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/apidiscovery/v2beta1
package v2beta1
import "k8s.io/apimachinery/pkg/apis/meta/v1"
// APIGroupDiscoveryList is a resource containing a list of APIGroupDiscovery.
// This is one of the types able to be returned from the /api and /apis endpoint and contains an aggregated
// list of API resources (built-ins, Custom Resource Definitions, resources from aggregated servers)
// that a cluster supports.
#APIGroupDiscoveryList: {
v1.#TypeMeta
// ResourceVersion will not be set, because this does not have a replayable ordering among multiple apiservers.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: v1.#ListMeta @go(ListMeta) @protobuf(1,bytes,opt)
// items is the list of groups for discovery. The groups are listed in priority order.
items: [...#APIGroupDiscovery] @go(Items,[]APIGroupDiscovery) @protobuf(2,bytes,rep)
}
// APIGroupDiscovery holds information about which resources are being served for all version of the API Group.
// It contains a list of APIVersionDiscovery that holds a list of APIResourceDiscovery types served for a version.
// Versions are in descending order of preference, with the first version being the preferred entry.
#APIGroupDiscovery: {
v1.#TypeMeta
// Standard object's metadata.
// The only field completed will be name. For instance, resourceVersion will be empty.
// name is the name of the API group whose discovery information is presented here.
// name is allowed to be "" to represent the legacy, ungroupified resources.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metadata?: v1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// versions are the versions supported in this group. They are sorted in descending order of preference,
// with the preferred version being the first entry.
// +listType=map
// +listMapKey=version
versions?: [...#APIVersionDiscovery] @go(Versions,[]APIVersionDiscovery) @protobuf(2,bytes,rep)
}
// APIVersionDiscovery holds a list of APIResourceDiscovery types that are served for a particular version within an API Group.
#APIVersionDiscovery: {
// version is the name of the version within a group version.
version: string @go(Version) @protobuf(1,bytes,opt)
// resources is a list of APIResourceDiscovery objects for the corresponding group version.
// +listType=map
// +listMapKey=resource
resources?: [...#APIResourceDiscovery] @go(Resources,[]APIResourceDiscovery) @protobuf(2,bytes,rep)
// freshness marks whether a group version's discovery document is up to date.
// "Current" indicates the discovery document was recently
// refreshed. "Stale" indicates the discovery document could not
// be retrieved and the returned discovery document may be
// significantly out of date. Clients that require the latest
// version of the discovery information be retrieved before
// performing an operation should not use the aggregated document
freshness?: #DiscoveryFreshness @go(Freshness) @protobuf(3,bytes,opt)
}
// APIResourceDiscovery provides information about an API resource for discovery.
#APIResourceDiscovery: {
// resource is the plural name of the resource. This is used in the URL path and is the unique identifier
// for this resource across all versions in the API group.
// Resources with non-empty groups are located at /apis/<APIGroupDiscovery.objectMeta.name>/<APIVersionDiscovery.version>/<APIResourceDiscovery.Resource>
// Resources with empty groups are located at /api/v1/<APIResourceDiscovery.Resource>
resource: string @go(Resource) @protobuf(1,bytes,opt)
// responseKind describes the group, version, and kind of the serialization schema for the object type this endpoint typically returns.
// APIs may return other objects types at their discretion, such as error conditions, requests for alternate representations, or other operation specific behavior.
// This value will be null or empty if an APIService reports subresources but supports no operations on the parent resource
responseKind?: null | v1.#GroupVersionKind @go(ResponseKind,*v1.GroupVersionKind) @protobuf(2,bytes,opt)
// scope indicates the scope of a resource, either Cluster or Namespaced
scope: #ResourceScope @go(Scope) @protobuf(3,bytes,opt)
// singularResource is the singular name of the resource. This allows clients to handle plural and singular opaquely.
// For many clients the singular form of the resource will be more understandable to users reading messages and should be used when integrating the name of the resource into a sentence.
// The command line tool kubectl, for example, allows use of the singular resource name in place of plurals.
// The singular form of a resource should always be an optional element - when in doubt use the canonical resource name.
singularResource: string @go(SingularResource) @protobuf(4,bytes,opt)
// verbs is a list of supported API operation types (this includes
// but is not limited to get, list, watch, create, update, patch,
// delete, deletecollection, and proxy).
// +listType=set
verbs: [...string] @go(Verbs,[]string) @protobuf(5,bytes,opt)
// shortNames is a list of suggested short names of the resource.
// +listType=set
shortNames?: [...string] @go(ShortNames,[]string) @protobuf(6,bytes,rep)
// categories is a list of the grouped resources this resource belongs to (e.g. 'all').
// Clients may use this to simplify acting on multiple resource types at once.
// +listType=set
categories?: [...string] @go(Categories,[]string) @protobuf(7,bytes,rep)
// subresources is a list of subresources provided by this resource. Subresources are located at /apis/<APIGroupDiscovery.objectMeta.name>/<APIVersionDiscovery.version>/<APIResourceDiscovery.Resource>/name-of-instance/<APIResourceDiscovery.subresources[i].subresource>
// +listType=map
// +listMapKey=subresource
subresources?: [...#APISubresourceDiscovery] @go(Subresources,[]APISubresourceDiscovery) @protobuf(8,bytes,rep)
}
// ResourceScope is an enum defining the different scopes available to a resource.
#ResourceScope: string // #enumResourceScope
#enumResourceScope:
#ScopeCluster |
#ScopeNamespace
#ScopeCluster: #ResourceScope & "Cluster"
#ScopeNamespace: #ResourceScope & "Namespaced"
// DiscoveryFreshness is an enum defining whether the Discovery document published by an apiservice is up to date (fresh).
#DiscoveryFreshness: string // #enumDiscoveryFreshness
#enumDiscoveryFreshness:
#DiscoveryFreshnessCurrent |
#DiscoveryFreshnessStale
#DiscoveryFreshnessCurrent: #DiscoveryFreshness & "Current"
#DiscoveryFreshnessStale: #DiscoveryFreshness & "Stale"
// APISubresourceDiscovery provides information about an API subresource for discovery.
#APISubresourceDiscovery: {
// subresource is the name of the subresource. This is used in the URL path and is the unique identifier
// for this resource across all versions.
subresource: string @go(Subresource) @protobuf(1,bytes,opt)
// responseKind describes the group, version, and kind of the serialization schema for the object type this endpoint typically returns.
// Some subresources do not return normal resources, these will have null or empty return types.
responseKind?: null | v1.#GroupVersionKind @go(ResponseKind,*v1.GroupVersionKind) @protobuf(2,bytes,opt)
// acceptedTypes describes the kinds that this endpoint accepts.
// Subresources may accept the standard content types or define
// custom negotiation schemes. The list may not be exhaustive for
// all operations.
// +listType=map
// +listMapKey=group
// +listMapKey=version
// +listMapKey=kind
acceptedTypes?: [...v1.#GroupVersionKind] @go(AcceptedTypes,[]v1.GroupVersionKind) @protobuf(3,bytes,rep)
// verbs is a list of supported API operation types (this includes
// but is not limited to get, list, watch, create, update, patch,
// delete, deletecollection, and proxy). Subresources may define
// custom verbs outside the standard Kubernetes verb set. Clients
// should expect the behavior of standard verbs to align with
// Kubernetes interaction conventions.
// +listType=set
verbs: [...string] @go(Verbs,[]string) @protobuf(4,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/apiserverinternal/v1alpha1
// Package v1alpha1 contains the v1alpha1 version of the API used by the
// apiservers themselves.
package v1alpha1

View File

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

View File

@@ -0,0 +1,129 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/apiserverinternal/v1alpha1
package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// Storage version of a specific resource.
#StorageVersion: {
metav1.#TypeMeta
// The name is <group>.<resource>.
metadata?: metav1.#ObjectMeta @go(ObjectMeta) @protobuf(1,bytes,opt)
// Spec is an empty spec. It is here to comply with Kubernetes API style.
spec: #StorageVersionSpec @go(Spec) @protobuf(2,bytes,opt)
// API server instances report the version they can decode and the version they
// encode objects to when persisting objects in the backend.
status: #StorageVersionStatus @go(Status) @protobuf(3,bytes,opt)
}
// StorageVersionSpec is an empty spec.
#StorageVersionSpec: {
}
// API server instances report the versions they can decode and the version they
// encode objects to when persisting objects in the backend.
#StorageVersionStatus: {
// The reported versions per API server instance.
// +optional
// +listType=map
// +listMapKey=apiServerID
storageVersions?: [...#ServerStorageVersion] @go(StorageVersions,[]ServerStorageVersion) @protobuf(1,bytes,opt)
// If all API server instances agree on the same encoding storage version,
// then this field is set to that version. Otherwise this field is left empty.
// API servers should finish updating its storageVersionStatus entry before
// serving write operations, so that this field will be in sync with the reality.
// +optional
commonEncodingVersion?: null | string @go(CommonEncodingVersion,*string) @protobuf(2,bytes,opt)
// The latest available observations of the storageVersion's state.
// +optional
// +listType=map
// +listMapKey=type
conditions?: [...#StorageVersionCondition] @go(Conditions,[]StorageVersionCondition) @protobuf(3,bytes,opt)
}
// An API server instance reports the version it can decode and the version it
// encodes objects to when persisting objects in the backend.
#ServerStorageVersion: {
// The ID of the reporting API server.
apiServerID?: string @go(APIServerID) @protobuf(1,bytes,opt)
// The API server encodes the object to this version when persisting it in
// the backend (e.g., etcd).
encodingVersion?: string @go(EncodingVersion) @protobuf(2,bytes,opt)
// The API server can decode objects encoded in these versions.
// The encodingVersion must be included in the decodableVersions.
// +listType=set
decodableVersions?: [...string] @go(DecodableVersions,[]string) @protobuf(3,bytes,opt)
// The API server can serve these versions.
// DecodableVersions must include all ServedVersions.
// +listType=set
servedVersions?: [...string] @go(ServedVersions,[]string) @protobuf(4,bytes,opt)
}
#StorageVersionConditionType: string // #enumStorageVersionConditionType
#enumStorageVersionConditionType:
#AllEncodingVersionsEqual
// Indicates that encoding storage versions reported by all servers are equal.
#AllEncodingVersionsEqual: #StorageVersionConditionType & "AllEncodingVersionsEqual"
#ConditionStatus: string // #enumConditionStatus
#enumConditionStatus:
#ConditionTrue |
#ConditionFalse |
#ConditionUnknown
#ConditionTrue: #ConditionStatus & "True"
#ConditionFalse: #ConditionStatus & "False"
#ConditionUnknown: #ConditionStatus & "Unknown"
// Describes the state of the storageVersion at a certain point.
#StorageVersionCondition: {
// Type of the condition.
// +required
type: #StorageVersionConditionType @go(Type) @protobuf(1,bytes,opt)
// Status of the condition, one of True, False, Unknown.
// +required
status: #ConditionStatus @go(Status) @protobuf(2,bytes,opt)
// If set, this represents the .metadata.generation that the condition was set based upon.
// +optional
observedGeneration?: int64 @go(ObservedGeneration) @protobuf(3,varint,opt)
// Last time the condition transitioned from one status to another.
// +required
lastTransitionTime?: metav1.#Time @go(LastTransitionTime) @protobuf(4,bytes,opt)
// The reason for the condition's last transition.
// +required
reason: string @go(Reason) @protobuf(5,bytes,opt)
// A human readable message indicating details about the transition.
// +required
message?: string @go(Message) @protobuf(6,bytes,opt)
}
// A list of StorageVersions.
#StorageVersionList: {
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 holds a list of StorageVersion
items: [...#StorageVersion] @go(Items,[]StorageVersion) @protobuf(2,bytes,rep)
}

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