Compare commits

...

147 Commits

Author SHA1 Message Date
Jeff McCune
5ebc54b5b7 (#124) Go Tools 2024-04-12 09:14:13 -07:00
Jeff McCune
2954a57872 (#120) Fix NATS target namespace
The upstream nats charts don't specify namespaces for each attribute.
This works with helm update, but not helm template which holos uses to
render the yaml.

The missing namespace causes flux to fail.

This patch uses the flux kustomization to add the target namespace to
all resources.
2024-04-10 21:54:58 -07:00
Jeff McCune
df705bd79f (#121) Fix Multiple Charts cause holos render to fail
When rendering a holos component which contains more than one helm chart, rendering fails.  It should succeed.

```
holos render --cluster-name=k2 /home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/holos/... --log-level debug
```

```
9:03PM ERR could not execute version=0.64.2 err="could not rename: rename /home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/holos/nats/envs/vendor553679311 /home/jeff/workspace/holos-run/holos/docs/examples/platforms/reference/clusters/holos/nats/envs/vendor: file exists" loc=helm.go:145
```

This patch fixes the problem by moving each child item of the temporary
directory charts are installed into.  This avoids the problem of moving
the parent when the parent target already exists.
2024-04-10 21:27:39 -07:00
Jeff McCune
4e8ce3585d (#115) Minor clean up of cue code 2024-04-10 21:21:16 -07:00
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
386 changed files with 128169 additions and 1325 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,34 @@ 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 Packages
run: sudo apt update && sudo apt -qq -y install git curl zip unzip tar bzip2 make
- name: Install Tools
run: |
set -x
make tools
make buf
go generate ./...
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

@@ -2,32 +2,58 @@ name: Release
on:
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 Tools
run: |
set -x
make tools
make buf
go generate ./...
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,38 @@ 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 Packages
run: sudo apt update && sudo apt -qq -y install git 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 Tools
run: |
set -x
make tools
make buf
go generate ./...
make frontend
go mod tidy
- name: Test
run: ./scripts/test

5
.gitignore vendored
View File

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

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,40 @@ 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: tools
tools: go-deps frontend-deps ## install tool dependencies
.PHONY: go-deps
go-deps: ## tool versions pinned in tools.go
go install github.com/bufbuild/buf/cmd/buf
go install github.com/fullstorydev/grpcurl/cmd/grpcurl
go install google.golang.org/protobuf/cmd/protoc-gen-go
go install connectrpc.com/connect/cmd/protoc-gen-connect-go
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

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

@@ -0,0 +1,170 @@
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.MkdirAll(cachePath, 0777); err != nil {
return errors.Wrap(fmt.Errorf("could not mkdir: %w", err))
}
items, err := os.ReadDir(cacheTemp)
if err != nil {
return errors.Wrap(fmt.Errorf("could not read directory: %w", err))
}
for _, item := range items {
src := filepath.Join(cacheTemp, item.Name())
dst := filepath.Join(cachePath, item.Name())
log.DebugContext(ctx, "rename", "src", src, "dst", dst)
if err := os.Rename(src, dst); err != nil {
return errors.Wrap(fmt.Errorf("could not rename: %w", err))
}
}
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,7 +1,6 @@
# Want support for intermediary constraints
exec holos build ./foo/... --log-level debug
stdout '^bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b$'
stderr 'processing holos component kind Skip'
-- cue.mod --
package holos
@@ -12,31 +11,21 @@ metadata: name: "jeff"
-- foo/bar/bar.cue --
package holos
#KubernetesObjects & {
apiObjectMap: foo: bar: "bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b"
}
spec: components: KubernetesObjectsList: [
#KubernetesObjects & {
apiObjectMap: foo: bar: "bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b"
}
]
-- schema.cue --
package holos
cluster: string @tag(cluster, string)
// #OutputTypeMeta is shared among all output types
#OutputTypeMeta: {
apiVersion: "holos.run/v1alpha1"
kind: #KubernetesObjects.kind | #NoOutput.kind
metadata: name: string
}
_cluster: string @tag(cluster, string)
#KubernetesObjects: {
#OutputTypeMeta
apiVersion: "holos.run/v1alpha1"
kind: "KubernetesObjects"
apiObjectMap: {...}
}
#NoOutput: {
#OutputTypeMeta
kind: string | *"Skip"
metadata: name: string | *"skipped"
}
#NoOutput & {}
apiVersion: "holos.run/v1alpha1"
kind: "BuildPlan"

View File

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

View File

@@ -9,15 +9,17 @@ package holos
package holos
apiVersion: "holos.run/v1alpha1"
kind: "KubernetesObjects"
cluster: string @tag(cluster, string)
kind: "BuildPlan"
spec: components: KubernetesObjectsList: [{apiObjectMap: #APIObjects.apiObjectMap}]
_cluster: string @tag(cluster, string)
#SecretStore: {
kind: string
metadata: name: string
}
#APIObjects & {
#APIObjects: {
apiObjects: {
SecretStore: {
default: #SecretStore & { metadata: name: "default" }
@@ -54,4 +56,3 @@ import "encoding/yaml"
}
}
}

View File

@@ -10,15 +10,17 @@ package holos
package holos
apiVersion: "holos.run/v1alpha1"
kind: "HelmChart"
cluster: string @tag(cluster, string)
kind: "BuildPlan"
spec: components: HelmChartList: [{apiObjectMap: #APIObjects.apiObjectMap}]
_cluster: string @tag(cluster, string)
#SecretStore: {
kind: string
metadata: name: string
}
#APIObjects & {
#APIObjects: {
apiObjects: {
SecretStore: {
default: #SecretStore & { metadata: name: "default" }
@@ -55,4 +57,3 @@ import "encoding/yaml"
}
}
}

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: []

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

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,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)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,546 @@
// 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-monitoring/prod-platform-monitoring.gen.yaml
package v1
import "strings"
// PodMonitor defines monitoring for a set of pods.
#PodMonitor: {
// 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: "monitoring.coreos.com/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: "PodMonitor"
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 desired Pod selection for target discovery by
// Prometheus.
spec!: #PodMonitorSpec
}
// Specification of desired Pod selection for target discovery by
// Prometheus.
#PodMonitorSpec: {
attachMetadata?: {
// When set to true, Prometheus must have the `get` permission on
// the `Nodes` objects.
node?: bool
}
// The label to use to retrieve the job name from. `jobLabel`
// selects the label from the associated Kubernetes `Pod` object
// which will be used as the `job` label for all metrics.
// For example if `jobLabel` is set to `foo` and the Kubernetes
// `Pod` object is labeled with `foo: bar`, then Prometheus adds
// the `job="bar"` label to all ingested metrics.
// If the value of this field is empty, the `job` label of the
// metrics defaults to the namespace and name of the PodMonitor
// object (e.g. `<namespace>/<name>`).
jobLabel?: string
// Per-scrape limit on the number of targets dropped by relabeling
// that will be kept in memory. 0 means no limit.
// It requires Prometheus >= v2.47.0.
keepDroppedTargets?: int
// Per-scrape limit on number of labels that will be accepted for
// a sample.
// It requires Prometheus >= v2.27.0.
labelLimit?: int
// Per-scrape limit on length of labels name that will be accepted
// for a sample.
// It requires Prometheus >= v2.27.0.
labelNameLengthLimit?: int
// Per-scrape limit on length of labels value that will be
// accepted for a sample.
// It requires Prometheus >= v2.27.0.
labelValueLengthLimit?: int
// Selector to select which namespaces the Kubernetes `Pods`
// objects are discovered from.
namespaceSelector?: {
// Boolean describing whether all namespaces are selected in
// contrast to a list restricting them.
any?: bool
// List of namespace names to select from.
matchNames?: [...string]
}
// List of endpoints part of this PodMonitor.
podMetricsEndpoints?: [...{
// `authorization` configures the Authorization header credentials
// to use when scraping the target.
// Cannot be set at the same time as `basicAuth`, or `oauth2`.
authorization?: {
// Selects a key of a Secret in the namespace that contains the
// credentials for authentication.
credentials?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// Defines the authentication type. The value is case-insensitive.
// "Basic" is not a supported value.
// Default: "Bearer"
type?: string
}
// `basicAuth` configures the Basic Authentication credentials to
// use when scraping the target.
// Cannot be set at the same time as `authorization`, or `oauth2`.
basicAuth?: {
// `password` specifies a key of a Secret containing the password
// for authentication.
password?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// `username` specifies a key of a Secret containing the username
// for authentication.
username?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// `bearerTokenSecret` specifies a key of a Secret containing the
// bearer token for scraping targets. The secret needs to be in
// the same namespace as the PodMonitor object and readable by
// the Prometheus Operator.
// Deprecated: use `authorization` instead.
bearerTokenSecret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// `enableHttp2` can be used to disable HTTP2 when scraping the
// target.
enableHttp2?: bool
// When true, the pods which are not running (e.g. either in
// Failed or Succeeded state) are dropped during the target
// discovery.
// If unset, the filtering is enabled.
// More info:
// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
filterRunning?: bool
// `followRedirects` defines whether the scrape requests should
// follow HTTP 3xx redirects.
followRedirects?: bool
// When true, `honorLabels` preserves the metric's labels when
// they collide with the target's labels.
honorLabels?: bool
// `honorTimestamps` controls whether Prometheus preserves the
// timestamps when exposed by the target.
honorTimestamps?: bool
// Interval at which Prometheus scrapes the metrics from the
// target.
// If empty, Prometheus uses the global scrape interval.
interval?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
// `metricRelabelings` configures the relabeling rules to apply to
// the samples before ingestion.
metricRelabelings?: [...{
// Action to perform based on the regex matching.
// `Uppercase` and `Lowercase` actions require Prometheus >=
// v2.36.0. `DropEqual` and `KeepEqual` actions require
// Prometheus >= v2.41.0.
// Default: "Replace"
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
// Modulus to take of the hash of the source label values.
// Only applicable when the action is `HashMod`.
modulus?: int
// Regular expression against which the extracted value is
// matched.
regex?: string
// Replacement value against which a Replace action is performed
// if the regular expression matches.
// Regex capture groups are available.
replacement?: string
// Separator is the string between concatenated SourceLabels.
separator?: string
// The source labels select values from existing labels. Their
// content is concatenated using the configured Separator and
// matched against the configured regular expression.
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
// Label to which the resulting string is written in a
// replacement.
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
// Regex capture groups are available.
targetLabel?: string
}]
// `oauth2` configures the OAuth2 settings to use when scraping
// the target.
// It requires Prometheus >= 2.27.0.
// Cannot be set at the same time as `authorization`, or
// `basicAuth`.
oauth2?: {
// `clientId` specifies a key of a Secret or ConfigMap containing
// the OAuth2 client's ID.
clientId: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// `clientSecret` specifies a key of a Secret containing the
// OAuth2 client's secret.
clientSecret: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// `endpointParams` configures the HTTP parameters to append to
// the token URL.
endpointParams?: {
[string]: string
}
// `scopes` defines the OAuth2 scopes used for the token request.
scopes?: [...string]
// `tokenURL` configures the URL to fetch the token from.
tokenUrl: strings.MinRunes(1)
}
// `params` define optional HTTP URL parameters.
params?: {
[string]: [...string]
}
// HTTP path from which to scrape for metrics.
// If empty, Prometheus uses the default value (e.g. `/metrics`).
path?: string
// Name of the Pod port which this endpoint refers to.
// It takes precedence over `targetPort`.
port?: string
// `proxyURL` configures the HTTP Proxy URL (e.g.
// "http://proxyserver:2195") to go through when scraping the
// target.
proxyUrl?: string
// `relabelings` configures the relabeling rules to apply the
// target's metadata labels.
// The Operator automatically adds relabelings for a few standard
// Kubernetes fields.
// The original scrape job's name is available via the
// `__tmp_prometheus_job_name` label.
// More info:
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
relabelings?: [...{
// Action to perform based on the regex matching.
// `Uppercase` and `Lowercase` actions require Prometheus >=
// v2.36.0. `DropEqual` and `KeepEqual` actions require
// Prometheus >= v2.41.0.
// Default: "Replace"
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
// Modulus to take of the hash of the source label values.
// Only applicable when the action is `HashMod`.
modulus?: int
// Regular expression against which the extracted value is
// matched.
regex?: string
// Replacement value against which a Replace action is performed
// if the regular expression matches.
// Regex capture groups are available.
replacement?: string
// Separator is the string between concatenated SourceLabels.
separator?: string
// The source labels select values from existing labels. Their
// content is concatenated using the configured Separator and
// matched against the configured regular expression.
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
// Label to which the resulting string is written in a
// replacement.
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
// Regex capture groups are available.
targetLabel?: string
}]
// HTTP scheme to use for scraping.
// `http` and `https` are the expected values unless you rewrite
// the `__scheme__` label via relabeling.
// If empty, Prometheus uses the default value `http`.
scheme?: "http" | "https"
// Timeout after which Prometheus considers the scrape to be
// failed.
// If empty, Prometheus uses the global scrape timeout unless it
// is less than the target's scrape interval value in which the
// latter is used.
scrapeTimeout?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
// Name or number of the target port of the `Pod` object behind
// the Service, the port must be specified with container port
// property.
// Deprecated: use 'port' instead.
targetPort?: (int | string) & {
string
}
// TLS configuration to use when scraping the target.
tlsConfig?: {
// Certificate authority used when verifying server certificates.
ca?: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// Client certificate to present when doing client-authentication.
cert?: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// Disable target certificate validation.
insecureSkipVerify?: bool
// Secret containing the client key file for the targets.
keySecret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// Used to verify the hostname for the targets.
serverName?: string
}
// `trackTimestampsStaleness` defines whether Prometheus tracks
// staleness of the metrics that have an explicit timestamp
// present in scraped data. Has no effect if `honorTimestamps` is
// false.
// It requires Prometheus >= v2.48.0.
trackTimestampsStaleness?: bool
}]
// `podTargetLabels` defines the labels which are transferred from
// the associated Kubernetes `Pod` object onto the ingested
// metrics.
podTargetLabels?: [...string]
// `sampleLimit` defines a per-scrape limit on the number of
// scraped samples that will be accepted.
sampleLimit?: int
// The scrape class to apply.
scrapeClass?: strings.MinRunes(1)
// `scrapeProtocols` defines the protocols to negotiate during a
// scrape. It tells clients the protocols supported by Prometheus
// in order of preference (from most to least preferred).
// If unset, Prometheus uses its default value.
// It requires Prometheus >= v2.49.0.
scrapeProtocols?: [..."PrometheusProto" | "OpenMetricsText0.0.1" | "OpenMetricsText1.0.0" | "PrometheusText0.0.4"]
// Label selector to select the Kubernetes `Pod` objects.
selector: {
// matchExpressions is a list of label selector requirements. The
// requirements are ANDed.
matchExpressions?: [...{
// key is the label key that the selector applies to.
key: string
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
operator: string
// values is an array of string values. If the operator is In or
// NotIn, the values array must be non-empty. If the operator is
// Exists or DoesNotExist, the values array must be empty. This
// array is replaced during a strategic merge patch.
values?: [...string]
}]
// matchLabels is a map of {key,value} pairs. A single {key,value}
// in the matchLabels map is equivalent to an element of
// matchExpressions, whose key field is "key", the operator is
// "In", and the values array contains only "value". The
// requirements are ANDed.
matchLabels?: {
[string]: string
}
}
// `targetLimit` defines a limit on the number of scraped targets
// that will be accepted.
targetLimit?: int
}

View File

@@ -0,0 +1,536 @@
// 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-monitoring/prod-platform-monitoring.gen.yaml
package v1
import "strings"
// Probe defines monitoring for a set of static targets or
// ingresses.
#Probe: {
// 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: "monitoring.coreos.com/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: "Probe"
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 desired Ingress selection for target discovery
// by Prometheus.
spec!: #ProbeSpec
}
// Specification of desired Ingress selection for target discovery
// by Prometheus.
#ProbeSpec: {
// Authorization section for this endpoint
authorization?: {
// Selects a key of a Secret in the namespace that contains the
// credentials for authentication.
credentials?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// Defines the authentication type. The value is case-insensitive.
// "Basic" is not a supported value.
// Default: "Bearer"
type?: string
}
// BasicAuth allow an endpoint to authenticate over basic
// authentication. More info:
// https://prometheus.io/docs/operating/configuration/#endpoint
basicAuth?: {
// `password` specifies a key of a Secret containing the password
// for authentication.
password?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// `username` specifies a key of a Secret containing the username
// for authentication.
username?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// Secret to mount to read bearer token for scraping targets. The
// secret needs to be in the same namespace as the probe and
// accessible by the Prometheus Operator.
bearerTokenSecret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// Interval at which targets are probed using the configured
// prober. If not specified Prometheus' global scrape interval is
// used.
interval?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
// The job name assigned to scraped metrics by default.
jobName?: string
// Per-scrape limit on the number of targets dropped by relabeling
// that will be kept in memory. 0 means no limit.
// It requires Prometheus >= v2.47.0.
keepDroppedTargets?: int
// Per-scrape limit on number of labels that will be accepted for
// a sample. Only valid in Prometheus versions 2.27.0 and newer.
labelLimit?: int
// Per-scrape limit on length of labels name that will be accepted
// for a sample. Only valid in Prometheus versions 2.27.0 and
// newer.
labelNameLengthLimit?: int
// Per-scrape limit on length of labels value that will be
// accepted for a sample. Only valid in Prometheus versions
// 2.27.0 and newer.
labelValueLengthLimit?: int
// MetricRelabelConfigs to apply to samples before ingestion.
metricRelabelings?: [...{
// Action to perform based on the regex matching.
// `Uppercase` and `Lowercase` actions require Prometheus >=
// v2.36.0. `DropEqual` and `KeepEqual` actions require
// Prometheus >= v2.41.0.
// Default: "Replace"
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
// Modulus to take of the hash of the source label values.
// Only applicable when the action is `HashMod`.
modulus?: int
// Regular expression against which the extracted value is
// matched.
regex?: string
// Replacement value against which a Replace action is performed
// if the regular expression matches.
// Regex capture groups are available.
replacement?: string
// Separator is the string between concatenated SourceLabels.
separator?: string
// The source labels select values from existing labels. Their
// content is concatenated using the configured Separator and
// matched against the configured regular expression.
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
// Label to which the resulting string is written in a
// replacement.
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
// Regex capture groups are available.
targetLabel?: string
}]
// The module to use for probing specifying how to probe the
// target. Example module configuring in the blackbox exporter:
// https://github.com/prometheus/blackbox_exporter/blob/master/example.yml
module?: string
// OAuth2 for the URL. Only valid in Prometheus versions 2.27.0
// and newer.
oauth2?: {
// `clientId` specifies a key of a Secret or ConfigMap containing
// the OAuth2 client's ID.
clientId: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// `clientSecret` specifies a key of a Secret containing the
// OAuth2 client's secret.
clientSecret: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// `endpointParams` configures the HTTP parameters to append to
// the token URL.
endpointParams?: {
[string]: string
}
// `scopes` defines the OAuth2 scopes used for the token request.
scopes?: [...string]
// `tokenURL` configures the URL to fetch the token from.
tokenUrl: strings.MinRunes(1)
}
// Specification for the prober to use for probing targets. The
// prober.URL parameter is required. Targets cannot be probed if
// left empty.
prober?: {
// Path to collect metrics from. Defaults to `/probe`.
path?: string | *"/probe"
// Optional ProxyURL.
proxyUrl?: string
// HTTP scheme to use for scraping. `http` and `https` are the
// expected values unless you rewrite the `__scheme__` label via
// relabeling. If empty, Prometheus uses the default value
// `http`.
scheme?: "http" | "https"
// Mandatory URL of the prober.
url: string
}
// SampleLimit defines per-scrape limit on number of scraped
// samples that will be accepted.
sampleLimit?: int
// The scrape class to apply.
scrapeClass?: strings.MinRunes(1)
// `scrapeProtocols` defines the protocols to negotiate during a
// scrape. It tells clients the protocols supported by Prometheus
// in order of preference (from most to least preferred).
// If unset, Prometheus uses its default value.
// It requires Prometheus >= v2.49.0.
scrapeProtocols?: [..."PrometheusProto" | "OpenMetricsText0.0.1" | "OpenMetricsText1.0.0" | "PrometheusText0.0.4"]
// Timeout for scraping metrics from the Prometheus exporter. If
// not specified, the Prometheus global scrape timeout is used.
scrapeTimeout?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
// TargetLimit defines a limit on the number of scraped targets
// that will be accepted.
targetLimit?: int
// Targets defines a set of static or dynamically discovered
// targets to probe.
targets?: {
// ingress defines the Ingress objects to probe and the relabeling
// configuration. If `staticConfig` is also defined,
// `staticConfig` takes precedence.
ingress?: {
// From which namespaces to select Ingress objects.
namespaceSelector?: {
// Boolean describing whether all namespaces are selected in
// contrast to a list restricting them.
any?: bool
// List of namespace names to select from.
matchNames?: [...string]
}
// RelabelConfigs to apply to the label set of the target before
// it gets scraped. The original ingress address is available via
// the `__tmp_prometheus_ingress_address` label. It can be used
// to customize the probed URL. The original scrape job's name is
// available via the `__tmp_prometheus_job_name` label. More
// info:
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
relabelingConfigs?: [...{
// Action to perform based on the regex matching.
// `Uppercase` and `Lowercase` actions require Prometheus >=
// v2.36.0. `DropEqual` and `KeepEqual` actions require
// Prometheus >= v2.41.0.
// Default: "Replace"
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
// Modulus to take of the hash of the source label values.
// Only applicable when the action is `HashMod`.
modulus?: int
// Regular expression against which the extracted value is
// matched.
regex?: string
// Replacement value against which a Replace action is performed
// if the regular expression matches.
// Regex capture groups are available.
replacement?: string
// Separator is the string between concatenated SourceLabels.
separator?: string
// The source labels select values from existing labels. Their
// content is concatenated using the configured Separator and
// matched against the configured regular expression.
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
// Label to which the resulting string is written in a
// replacement.
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
// Regex capture groups are available.
targetLabel?: string
}]
// Selector to select the Ingress objects.
selector?: {
// matchExpressions is a list of label selector requirements. The
// requirements are ANDed.
matchExpressions?: [...{
// key is the label key that the selector applies to.
key: string
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
operator: string
// values is an array of string values. If the operator is In or
// NotIn, the values array must be non-empty. If the operator is
// Exists or DoesNotExist, the values array must be empty. This
// array is replaced during a strategic merge patch.
values?: [...string]
}]
// matchLabels is a map of {key,value} pairs. A single {key,value}
// in the matchLabels map is equivalent to an element of
// matchExpressions, whose key field is "key", the operator is
// "In", and the values array contains only "value". The
// requirements are ANDed.
matchLabels?: {
[string]: string
}
}
}
// staticConfig defines the static list of targets to probe and
// the relabeling configuration. If `ingress` is also defined,
// `staticConfig` takes precedence. More info:
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#static_config.
staticConfig?: {
// Labels assigned to all metrics scraped from the targets.
labels?: {
[string]: string
}
// RelabelConfigs to apply to the label set of the targets before
// it gets scraped. More info:
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
relabelingConfigs?: [...{
// Action to perform based on the regex matching.
// `Uppercase` and `Lowercase` actions require Prometheus >=
// v2.36.0. `DropEqual` and `KeepEqual` actions require
// Prometheus >= v2.41.0.
// Default: "Replace"
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
// Modulus to take of the hash of the source label values.
// Only applicable when the action is `HashMod`.
modulus?: int
// Regular expression against which the extracted value is
// matched.
regex?: string
// Replacement value against which a Replace action is performed
// if the regular expression matches.
// Regex capture groups are available.
replacement?: string
// Separator is the string between concatenated SourceLabels.
separator?: string
// The source labels select values from existing labels. Their
// content is concatenated using the configured Separator and
// matched against the configured regular expression.
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
// Label to which the resulting string is written in a
// replacement.
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
// Regex capture groups are available.
targetLabel?: string
}]
// The list of hosts to probe.
static?: [...string]
}
}
// TLS configuration to use when scraping the endpoint.
tlsConfig?: {
// Certificate authority used when verifying server certificates.
ca?: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// Client certificate to present when doing client-authentication.
cert?: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// Disable target certificate validation.
insecureSkipVerify?: bool
// Secret containing the client key file for the targets.
keySecret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// Used to verify the hostname for the targets.
serverName?: string
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
// 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-monitoring/prod-platform-monitoring.gen.yaml
package v1
import "strings"
// PrometheusRule defines recording and alerting rules for a
// Prometheus instance
#PrometheusRule: {
// 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: "monitoring.coreos.com/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: "PrometheusRule"
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 desired alerting rule definitions for
// Prometheus.
spec!: #PrometheusRuleSpec
}
#PrometheusRuleSpec: {
// Content of Prometheus rule file
groups?: [...{
// Interval determines how often rules in the group are evaluated.
interval?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
// Limit the number of alerts an alerting rule and series a
// recording rule can produce. Limit is supported starting with
// Prometheus >= 2.31 and Thanos Ruler >= 0.24.
limit?: int
// Name of the rule group.
name: strings.MinRunes(1)
// PartialResponseStrategy is only used by ThanosRuler and will be
// ignored by Prometheus instances. More info:
// https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response
partial_response_strategy?: =~"^(?i)(abort|warn)?$"
// List of alerting and recording rules.
rules?: [...{
// Name of the alert. Must be a valid label value. Only one of
// `record` and `alert` must be set.
alert?: string
// Annotations to add to each alert. Only valid for alerting
// rules.
annotations?: {
[string]: string
}
// PromQL expression to evaluate.
expr: (int | string) & {
string
}
// Alerts are considered firing once they have been returned for
// this long.
for?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
// KeepFiringFor defines how long an alert will continue firing
// after the condition that triggered it has cleared.
keep_firing_for?: strings.MinRunes(1) & {
=~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
}
// Labels to add or overwrite.
labels?: {
[string]: string
}
// Name of the time series to output to. Must be a valid metric
// name. Only one of `record` and `alert` must be set.
record?: string
}]
}]
}

View File

@@ -0,0 +1,566 @@
// 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-monitoring/prod-platform-monitoring.gen.yaml
package v1
import "strings"
// ServiceMonitor defines monitoring for a set of services.
#ServiceMonitor: {
// 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: "monitoring.coreos.com/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: "ServiceMonitor"
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 desired Service selection for target discovery
// by Prometheus.
spec!: #ServiceMonitorSpec
}
// Specification of desired Service selection for target discovery
// by Prometheus.
#ServiceMonitorSpec: {
attachMetadata?: {
// When set to true, Prometheus must have the `get` permission on
// the `Nodes` objects.
node?: bool
}
// List of endpoints part of this ServiceMonitor.
endpoints?: [...{
// `authorization` configures the Authorization header credentials
// to use when scraping the target.
// Cannot be set at the same time as `basicAuth`, or `oauth2`.
authorization?: {
// Selects a key of a Secret in the namespace that contains the
// credentials for authentication.
credentials?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// Defines the authentication type. The value is case-insensitive.
// "Basic" is not a supported value.
// Default: "Bearer"
type?: string
}
// `basicAuth` configures the Basic Authentication credentials to
// use when scraping the target.
// Cannot be set at the same time as `authorization`, or `oauth2`.
basicAuth?: {
// `password` specifies a key of a Secret containing the password
// for authentication.
password?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// `username` specifies a key of a Secret containing the username
// for authentication.
username?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// File to read bearer token for scraping the target.
// Deprecated: use `authorization` instead.
bearerTokenFile?: string
// `bearerTokenSecret` specifies a key of a Secret containing the
// bearer token for scraping targets. The secret needs to be in
// the same namespace as the ServiceMonitor object and readable
// by the Prometheus Operator.
// Deprecated: use `authorization` instead.
bearerTokenSecret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// `enableHttp2` can be used to disable HTTP2 when scraping the
// target.
enableHttp2?: bool
// When true, the pods which are not running (e.g. either in
// Failed or Succeeded state) are dropped during the target
// discovery.
// If unset, the filtering is enabled.
// More info:
// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
filterRunning?: bool
// `followRedirects` defines whether the scrape requests should
// follow HTTP 3xx redirects.
followRedirects?: bool
// When true, `honorLabels` preserves the metric's labels when
// they collide with the target's labels.
honorLabels?: bool
// `honorTimestamps` controls whether Prometheus preserves the
// timestamps when exposed by the target.
honorTimestamps?: bool
// Interval at which Prometheus scrapes the metrics from the
// target.
// If empty, Prometheus uses the global scrape interval.
interval?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
// `metricRelabelings` configures the relabeling rules to apply to
// the samples before ingestion.
metricRelabelings?: [...{
// Action to perform based on the regex matching.
// `Uppercase` and `Lowercase` actions require Prometheus >=
// v2.36.0. `DropEqual` and `KeepEqual` actions require
// Prometheus >= v2.41.0.
// Default: "Replace"
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
// Modulus to take of the hash of the source label values.
// Only applicable when the action is `HashMod`.
modulus?: int
// Regular expression against which the extracted value is
// matched.
regex?: string
// Replacement value against which a Replace action is performed
// if the regular expression matches.
// Regex capture groups are available.
replacement?: string
// Separator is the string between concatenated SourceLabels.
separator?: string
// The source labels select values from existing labels. Their
// content is concatenated using the configured Separator and
// matched against the configured regular expression.
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
// Label to which the resulting string is written in a
// replacement.
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
// Regex capture groups are available.
targetLabel?: string
}]
// `oauth2` configures the OAuth2 settings to use when scraping
// the target.
// It requires Prometheus >= 2.27.0.
// Cannot be set at the same time as `authorization`, or
// `basicAuth`.
oauth2?: {
// `clientId` specifies a key of a Secret or ConfigMap containing
// the OAuth2 client's ID.
clientId: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// `clientSecret` specifies a key of a Secret containing the
// OAuth2 client's secret.
clientSecret: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// `endpointParams` configures the HTTP parameters to append to
// the token URL.
endpointParams?: {
[string]: string
}
// `scopes` defines the OAuth2 scopes used for the token request.
scopes?: [...string]
// `tokenURL` configures the URL to fetch the token from.
tokenUrl: strings.MinRunes(1)
}
// params define optional HTTP URL parameters.
params?: {
[string]: [...string]
}
// HTTP path from which to scrape for metrics.
// If empty, Prometheus uses the default value (e.g. `/metrics`).
path?: string
// Name of the Service port which this endpoint refers to.
// It takes precedence over `targetPort`.
port?: string
// `proxyURL` configures the HTTP Proxy URL (e.g.
// "http://proxyserver:2195") to go through when scraping the
// target.
proxyUrl?: string
// `relabelings` configures the relabeling rules to apply the
// target's metadata labels.
// The Operator automatically adds relabelings for a few standard
// Kubernetes fields.
// The original scrape job's name is available via the
// `__tmp_prometheus_job_name` label.
// More info:
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
relabelings?: [...{
// Action to perform based on the regex matching.
// `Uppercase` and `Lowercase` actions require Prometheus >=
// v2.36.0. `DropEqual` and `KeepEqual` actions require
// Prometheus >= v2.41.0.
// Default: "Replace"
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
// Modulus to take of the hash of the source label values.
// Only applicable when the action is `HashMod`.
modulus?: int
// Regular expression against which the extracted value is
// matched.
regex?: string
// Replacement value against which a Replace action is performed
// if the regular expression matches.
// Regex capture groups are available.
replacement?: string
// Separator is the string between concatenated SourceLabels.
separator?: string
// The source labels select values from existing labels. Their
// content is concatenated using the configured Separator and
// matched against the configured regular expression.
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
// Label to which the resulting string is written in a
// replacement.
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
// Regex capture groups are available.
targetLabel?: string
}]
// HTTP scheme to use for scraping.
// `http` and `https` are the expected values unless you rewrite
// the `__scheme__` label via relabeling.
// If empty, Prometheus uses the default value `http`.
scheme?: "http" | "https"
// Timeout after which Prometheus considers the scrape to be
// failed.
// If empty, Prometheus uses the global scrape timeout unless it
// is less than the target's scrape interval value in which the
// latter is used.
scrapeTimeout?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
// Name or number of the target port of the `Pod` object behind
// the Service. The port must be specified with the container's
// port property.
targetPort?: (int | string) & {
string
}
// TLS configuration to use when scraping the target.
tlsConfig?: {
// Certificate authority used when verifying server certificates.
ca?: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// Path to the CA cert in the Prometheus container to use for the
// targets.
caFile?: string
// Client certificate to present when doing client-authentication.
cert?: {
// ConfigMap containing data to use for the targets.
configMap?: {
// The key to select.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the ConfigMap or its key must be defined
optional?: bool
}
// Secret containing data to use for the targets.
secret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
}
// Path to the client cert file in the Prometheus container for
// the targets.
certFile?: string
// Disable target certificate validation.
insecureSkipVerify?: bool
// Path to the client key file in the Prometheus container for the
// targets.
keyFile?: string
// Secret containing the client key file for the targets.
keySecret?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
// TODO: Add other useful fields. apiVersion, kind, uid?
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// Used to verify the hostname for the targets.
serverName?: string
}
// `trackTimestampsStaleness` defines whether Prometheus tracks
// staleness of the metrics that have an explicit timestamp
// present in scraped data. Has no effect if `honorTimestamps` is
// false.
// It requires Prometheus >= v2.48.0.
trackTimestampsStaleness?: bool
}]
// `jobLabel` selects the label from the associated Kubernetes
// `Service` object which will be used as the `job` label for all
// metrics.
// For example if `jobLabel` is set to `foo` and the Kubernetes
// `Service` object is labeled with `foo: bar`, then Prometheus
// adds the `job="bar"` label to all ingested metrics.
// If the value of this field is empty or if the label doesn't
// exist for the given Service, the `job` label of the metrics
// defaults to the name of the associated Kubernetes `Service`.
jobLabel?: string
// Per-scrape limit on the number of targets dropped by relabeling
// that will be kept in memory. 0 means no limit.
// It requires Prometheus >= v2.47.0.
keepDroppedTargets?: int
// Per-scrape limit on number of labels that will be accepted for
// a sample.
// It requires Prometheus >= v2.27.0.
labelLimit?: int
// Per-scrape limit on length of labels name that will be accepted
// for a sample.
// It requires Prometheus >= v2.27.0.
labelNameLengthLimit?: int
// Per-scrape limit on length of labels value that will be
// accepted for a sample.
// It requires Prometheus >= v2.27.0.
labelValueLengthLimit?: int
// Selector to select which namespaces the Kubernetes `Endpoints`
// objects are discovered from.
namespaceSelector?: {
// Boolean describing whether all namespaces are selected in
// contrast to a list restricting them.
any?: bool
// List of namespace names to select from.
matchNames?: [...string]
}
// `podTargetLabels` defines the labels which are transferred from
// the associated Kubernetes `Pod` object onto the ingested
// metrics.
podTargetLabels?: [...string]
// `sampleLimit` defines a per-scrape limit on the number of
// scraped samples that will be accepted.
sampleLimit?: int
// The scrape class to apply.
scrapeClass?: strings.MinRunes(1)
// `scrapeProtocols` defines the protocols to negotiate during a
// scrape. It tells clients the protocols supported by Prometheus
// in order of preference (from most to least preferred).
// If unset, Prometheus uses its default value.
// It requires Prometheus >= v2.49.0.
scrapeProtocols?: [..."PrometheusProto" | "OpenMetricsText0.0.1" | "OpenMetricsText1.0.0" | "PrometheusText0.0.4"]
// Label selector to select the Kubernetes `Endpoints` objects.
selector: {
// matchExpressions is a list of label selector requirements. The
// requirements are ANDed.
matchExpressions?: [...{
// key is the label key that the selector applies to.
key: string
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
operator: string
// values is an array of string values. If the operator is In or
// NotIn, the values array must be non-empty. If the operator is
// Exists or DoesNotExist, the values array must be empty. This
// array is replaced during a strategic merge patch.
values?: [...string]
}]
// matchLabels is a map of {key,value} pairs. A single {key,value}
// in the matchLabels map is equivalent to an element of
// matchExpressions, whose key field is "key", the operator is
// "In", and the values array contains only "value". The
// requirements are ANDed.
matchLabels?: {
[string]: string
}
}
// `targetLabels` defines the labels which are transferred from
// the associated Kubernetes `Service` object onto the ingested
// metrics.
targetLabels?: [...string]
// `targetLimit` defines a limit on the number of scraped targets
// that will be accepted.
targetLimit?: int
}

File diff suppressed because it is too large Load Diff

View File

@@ -306,31 +306,16 @@ import "strings"
// "value"` for prefix-based match - `regex: "value"` for RE2
// style regex-based match
// (https://github.com/google/re2/wiki/Syntax).
uri?: ({} | {
exact: _
} | {
prefix: _
} | {
regex: _
}) & {
uri?: {
exact?: string
prefix?: string
// RE2 style regex-based match
// (https://github.com/google/re2/wiki/Syntax).
regex?: string
regex?: string
}
// withoutHeader has the same syntax with the header, but has
// opposite meaning.
withoutHeaders?: {
[string]: ({} | {
exact: _
} | {
prefix: _
} | {
regex: _
}) & {
[string]: {
exact?: string
prefix?: string
@@ -383,11 +368,7 @@ import "strings"
// A HTTP rule can either return a direct_response, redirect or
// forward (default) traffic.
redirect?: ({} | {
port: _
} | {
derivePort: _
}) & {
redirect?: {
// On a redirect, overwrite the Authority/Host portion of the URL
// with this value.
authority?: string

View File

@@ -0,0 +1,975 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/core2/components/prod-pgo-crds/prod-pgo-crds.gen.yaml
package v1beta1
import "strings"
// PGAdmin is the Schema for the pgadmins API
#PGAdmin: {
// 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: "postgres-operator.crunchydata.com/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: "PGAdmin"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// PGAdminSpec defines the desired state of PGAdmin
spec!: #PGAdminSpec
}
// PGAdminSpec defines the desired state of PGAdmin
#PGAdminSpec: {
// Scheduling constraints of the PGAdmin pod. More info:
// https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node
affinity?: {
// Describes node affinity scheduling rules for the pod.
nodeAffinity?: {
// The scheduler will prefer to schedule pods to nodes that
// satisfy the affinity expressions specified by this field, but
// it may choose a node that violates one or more of the
// expressions. The node that is most preferred is the one with
// the greatest sum of weights, i.e. for each node that meets all
// of the scheduling requirements (resource request,
// requiredDuringScheduling affinity expressions, etc.), compute
// a sum by iterating through the elements of this field and
// adding "weight" to the sum if the node matches the
// corresponding matchExpressions; the node(s) with the highest
// sum are the most preferred.
preferredDuringSchedulingIgnoredDuringExecution?: [...{
// A node selector term, associated with the corresponding weight.
preference: {
// A list of node selector requirements by node's labels.
matchExpressions?: [...{
// The label key that the selector applies to.
key: string
// Represents a key's relationship to a set of values. Valid
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
operator: string
// 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. If the operator
// is Gt or Lt, the values array must have a single element,
// which will be interpreted as an integer. This array is
// replaced during a strategic merge patch.
values?: [...string]
}]
// A list of node selector requirements by node's fields.
matchFields?: [...{
// The label key that the selector applies to.
key: string
// Represents a key's relationship to a set of values. Valid
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
operator: string
// 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. If the operator
// is Gt or Lt, the values array must have a single element,
// which will be interpreted as an integer. This array is
// replaced during a strategic merge patch.
values?: [...string]
}]
}
// Weight associated with matching the corresponding
// nodeSelectorTerm, in the range 1-100.
weight: int
}]
requiredDuringSchedulingIgnoredDuringExecution?: {
// Required. A list of node selector terms. The terms are ORed.
nodeSelectorTerms: [...{
// A list of node selector requirements by node's labels.
matchExpressions?: [...{
// The label key that the selector applies to.
key: string
// Represents a key's relationship to a set of values. Valid
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
operator: string
// 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. If the operator
// is Gt or Lt, the values array must have a single element,
// which will be interpreted as an integer. This array is
// replaced during a strategic merge patch.
values?: [...string]
}]
// A list of node selector requirements by node's fields.
matchFields?: [...{
// The label key that the selector applies to.
key: string
// Represents a key's relationship to a set of values. Valid
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
operator: string
// 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. If the operator
// is Gt or Lt, the values array must have a single element,
// which will be interpreted as an integer. This array is
// replaced during a strategic merge patch.
values?: [...string]
}]
}]
}
}
// Describes pod affinity scheduling rules (e.g. co-locate this
// pod in the same node, zone, etc. as some other pod(s)).
podAffinity?: {
// The scheduler will prefer to schedule pods to nodes that
// satisfy the affinity expressions specified by this field, but
// it may choose a node that violates one or more of the
// expressions. The node that is most preferred is the one with
// the greatest sum of weights, i.e. for each node that meets all
// of the scheduling requirements (resource request,
// requiredDuringScheduling affinity expressions, etc.), compute
// a sum by iterating through the elements of this field and
// adding "weight" to the sum if the node has pods which matches
// the corresponding podAffinityTerm; the node(s) with the
// highest sum are the most preferred.
preferredDuringSchedulingIgnoredDuringExecution?: [...{
// Required. A pod affinity term, associated with the
// corresponding weight.
podAffinityTerm: {
// A label query over a set of resources, in this case pods.
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
}
}
// A label query over the set of namespaces that the term applies
// to. The term is applied to the union of the namespaces
// selected by this field and the ones listed in the namespaces
// field. null selector and null or empty namespaces list means
// "this pod's namespace". An empty selector ({}) matches all
// namespaces.
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
}
}
// namespaces specifies a static list of namespace names that the
// term applies to. The term is applied to the union of the
// namespaces listed in this field and the ones selected by
// namespaceSelector. null or empty namespaces list and null
// namespaceSelector means "this pod's namespace".
namespaces?: [...string]
// This pod should be co-located (affinity) or not co-located
// (anti-affinity) with the pods matching the labelSelector in
// the specified namespaces, where co-located is defined as
// running on a node whose value of the label with key
// topologyKey matches that of any node on which any of the
// selected pods is running. Empty topologyKey is not allowed.
topologyKey: string
}
// weight associated with matching the corresponding
// podAffinityTerm, in the range 1-100.
weight: int
}]
// If the affinity requirements specified by this field are not
// met at scheduling time, the pod will not be scheduled onto the
// node. If the affinity requirements specified by this field
// cease to be met at some point during pod execution (e.g. due
// to a pod label update), the system may or may not try to
// eventually evict the pod from its node. When there are
// multiple elements, the lists of nodes corresponding to each
// podAffinityTerm are intersected, i.e. all terms must be
// satisfied.
requiredDuringSchedulingIgnoredDuringExecution?: [...{
// A label query over a set of resources, in this case pods.
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
}
}
// A label query over the set of namespaces that the term applies
// to. The term is applied to the union of the namespaces
// selected by this field and the ones listed in the namespaces
// field. null selector and null or empty namespaces list means
// "this pod's namespace". An empty selector ({}) matches all
// namespaces.
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
}
}
// namespaces specifies a static list of namespace names that the
// term applies to. The term is applied to the union of the
// namespaces listed in this field and the ones selected by
// namespaceSelector. null or empty namespaces list and null
// namespaceSelector means "this pod's namespace".
namespaces?: [...string]
// This pod should be co-located (affinity) or not co-located
// (anti-affinity) with the pods matching the labelSelector in
// the specified namespaces, where co-located is defined as
// running on a node whose value of the label with key
// topologyKey matches that of any node on which any of the
// selected pods is running. Empty topologyKey is not allowed.
topologyKey: string
}]
}
// Describes pod anti-affinity scheduling rules (e.g. avoid
// putting this pod in the same node, zone, etc. as some other
// pod(s)).
podAntiAffinity?: {
// The scheduler will prefer to schedule pods to nodes that
// satisfy the anti-affinity expressions specified by this field,
// but it may choose a node that violates one or more of the
// expressions. The node that is most preferred is the one with
// the greatest sum of weights, i.e. for each node that meets all
// of the scheduling requirements (resource request,
// requiredDuringScheduling anti-affinity expressions, etc.),
// compute a sum by iterating through the elements of this field
// and adding "weight" to the sum if the node has pods which
// matches the corresponding podAffinityTerm; the node(s) with
// the highest sum are the most preferred.
preferredDuringSchedulingIgnoredDuringExecution?: [...{
// Required. A pod affinity term, associated with the
// corresponding weight.
podAffinityTerm: {
// A label query over a set of resources, in this case pods.
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
}
}
// A label query over the set of namespaces that the term applies
// to. The term is applied to the union of the namespaces
// selected by this field and the ones listed in the namespaces
// field. null selector and null or empty namespaces list means
// "this pod's namespace". An empty selector ({}) matches all
// namespaces.
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
}
}
// namespaces specifies a static list of namespace names that the
// term applies to. The term is applied to the union of the
// namespaces listed in this field and the ones selected by
// namespaceSelector. null or empty namespaces list and null
// namespaceSelector means "this pod's namespace".
namespaces?: [...string]
// This pod should be co-located (affinity) or not co-located
// (anti-affinity) with the pods matching the labelSelector in
// the specified namespaces, where co-located is defined as
// running on a node whose value of the label with key
// topologyKey matches that of any node on which any of the
// selected pods is running. Empty topologyKey is not allowed.
topologyKey: string
}
// weight associated with matching the corresponding
// podAffinityTerm, in the range 1-100.
weight: int
}]
// If the anti-affinity requirements specified by this field are
// not met at scheduling time, the pod will not be scheduled onto
// the node. If the anti-affinity requirements specified by this
// field cease to be met at some point during pod execution (e.g.
// due to a pod label update), the system may or may not try to
// eventually evict the pod from its node. When there are
// multiple elements, the lists of nodes corresponding to each
// podAffinityTerm are intersected, i.e. all terms must be
// satisfied.
requiredDuringSchedulingIgnoredDuringExecution?: [...{
// A label query over a set of resources, in this case pods.
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
}
}
// A label query over the set of namespaces that the term applies
// to. The term is applied to the union of the namespaces
// selected by this field and the ones listed in the namespaces
// field. null selector and null or empty namespaces list means
// "this pod's namespace". An empty selector ({}) matches all
// namespaces.
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
}
}
// namespaces specifies a static list of namespace names that the
// term applies to. The term is applied to the union of the
// namespaces listed in this field and the ones selected by
// namespaceSelector. null or empty namespaces list and null
// namespaceSelector means "this pod's namespace".
namespaces?: [...string]
// This pod should be co-located (affinity) or not co-located
// (anti-affinity) with the pods matching the labelSelector in
// the specified namespaces, where co-located is defined as
// running on a node whose value of the label with key
// topologyKey matches that of any node on which any of the
// selected pods is running. Empty topologyKey is not allowed.
topologyKey: string
}]
}
}
// Configuration settings for the pgAdmin process. Changes to any
// of these values will be loaded without validation. Be careful,
// as you may put pgAdmin into an unusable state.
config?: {
// Files allows the user to mount projected volumes into the
// pgAdmin container so that files can be referenced by pgAdmin
// as needed.
files?: [...{
// configMap information about the configMap data to project
configMap?: {
// items if unspecified, each key-value pair in the Data field of
// the referenced ConfigMap will be projected into the volume as
// a file whose name is the key and content is the value. If
// specified, the listed keys will be projected into the
// specified paths, and unlisted keys will not be present. If a
// key is specified which is not present in the ConfigMap, the
// volume setup will error unless it is marked optional. Paths
// must be relative and may not contain the '..' path or start
// with '..'.
items?: [...{
// key is the key to project.
key: string
// mode is Optional: mode bits used to set permissions on this
// file. Must be an octal value between 0000 and 0777 or a
// decimal value between 0 and 511. YAML accepts both octal and
// decimal values, JSON requires decimal values for mode bits. If
// not specified, the volume defaultMode will be used. This might
// be in conflict with other options that affect the file mode,
// like fsGroup, and the result can be other mode bits set.
mode?: int
// path is the relative path of the file to map the key to. May
// not be an absolute path. May not contain the path element
// '..'. May not start with the string '..'.
path: string
}]
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name?: string
// optional specify whether the ConfigMap or its keys must be
// defined
optional?: bool
}
downwardAPI?: {
// Items is a list of DownwardAPIVolume file
items?: [...{
// Required: Selects a field of the pod: only annotations, labels,
// name and namespace are supported.
fieldRef?: {
// Version of the schema the FieldPath is written in terms of,
// defaults to "v1".
apiVersion?: string
// Path of the field to select in the specified API version.
fieldPath: string
}
// Optional: mode bits used to set permissions on this file, must
// be an octal value between 0000 and 0777 or a decimal value
// between 0 and 511. YAML accepts both octal and decimal values,
// JSON requires decimal values for mode bits. If not specified,
// the volume defaultMode will be used. This might be in conflict
// with other options that affect the file mode, like fsGroup,
// and the result can be other mode bits set.
mode?: int
// Required: Path is the relative path name of the file to be
// created. Must not be absolute or contain the '..' path. Must
// be utf-8 encoded. The first item of the relative path must not
// start with '..'
path: string
// Selects a resource of the container: only resources limits and
// requests (limits.cpu, limits.memory, requests.cpu and
// requests.memory) are currently supported.
resourceFieldRef?: {
// Container name: required for volumes, optional for env vars
containerName?: string
// Specifies the output format of the exposed resources, defaults
// to "1"
divisor?: (int | string) & {
=~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
}
// Required: resource to select
resource: string
}
}]
}
// secret information about the secret data to project
secret?: {
// items if unspecified, each key-value pair in the Data field of
// the referenced Secret will be projected into the volume as a
// file whose name is the key and content is the value. If
// specified, the listed keys will be projected into the
// specified paths, and unlisted keys will not be present. If a
// key is specified which is not present in the Secret, the
// volume setup will error unless it is marked optional. Paths
// must be relative and may not contain the '..' path or start
// with '..'.
items?: [...{
// key is the key to project.
key: string
// mode is Optional: mode bits used to set permissions on this
// file. Must be an octal value between 0000 and 0777 or a
// decimal value between 0 and 511. YAML accepts both octal and
// decimal values, JSON requires decimal values for mode bits. If
// not specified, the volume defaultMode will be used. This might
// be in conflict with other options that affect the file mode,
// like fsGroup, and the result can be other mode bits set.
mode?: int
// path is the relative path of the file to map the key to. May
// not be an absolute path. May not contain the path element
// '..'. May not start with the string '..'.
path: string
}]
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name?: string
// optional field specify whether the Secret or its key must be
// defined
optional?: bool
}
// serviceAccountToken is information about the
// serviceAccountToken data to project
serviceAccountToken?: {
// audience is the intended audience of the token. A recipient of
// a token must identify itself with an identifier specified in
// the audience of the token, and otherwise should reject the
// token. The audience defaults to the identifier of the
// apiserver.
audience?: string
// expirationSeconds is the requested duration of validity of the
// service account token. As the token approaches expiration, the
// kubelet volume plugin will proactively rotate the service
// account token. The kubelet will start trying to rotate the
// token if the token is older than 80 percent of its time to
// live or if the token is older than 24 hours.Defaults to 1 hour
// and must be at least 10 minutes.
expirationSeconds?: int
// path is the path relative to the mount point of the file to
// project the token into.
path: string
}
}]
// A Secret containing the value for the LDAP_BIND_PASSWORD
// setting. More info:
// https://www.pgadmin.org/docs/pgadmin4/latest/ldap.html
ldapBindPassword?: {
// The key of the secret to select from. Must be a valid secret
// key.
key: string
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name?: string
// Specify whether the Secret or its key must be defined
optional?: bool
}
// Settings for the pgAdmin server process. Keys should be
// uppercase and values must be constants. More info:
// https://www.pgadmin.org/docs/pgadmin4/latest/config_py.html
settings?: {
...
}
}
// Defines a PersistentVolumeClaim for pgAdmin data. More info:
// https://kubernetes.io/docs/concepts/storage/persistent-volumes
dataVolumeClaimSpec: {
// accessModes contains the desired access modes the volume should
// have. More info:
// https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
accessModes?: [...string]
// dataSource field can be used to specify either: * An existing
// VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
// * An existing PVC (PersistentVolumeClaim) If the provisioner
// or an external controller can support the specified data
// source, it will create a new volume based on the contents of
// the specified data source. If the AnyVolumeDataSource feature
// gate is enabled, this field will always have the same contents
// as the DataSourceRef field.
dataSource?: {
// APIGroup is the group for the resource being referenced. If
// APIGroup is not specified, the specified Kind must be in the
// core API group. For any other third-party types, APIGroup is
// required.
apiGroup?: string
// Kind is the type of resource being referenced
kind: string
// Name is the name of resource being referenced
name: string
}
// dataSourceRef specifies the object from which to populate the
// volume with data, if a non-empty volume is desired. This may
// be any local object from a non-empty API group (non core
// object) or a PersistentVolumeClaim object. When this field is
// specified, volume binding will only succeed if the type of the
// specified object matches some installed volume populator or
// dynamic provisioner. This field will replace the functionality
// of the DataSource field and as such if both fields are
// non-empty, they must have the same value. For backwards
// compatibility, both fields (DataSource and DataSourceRef) will
// be set to the same value automatically if one of them is empty
// and the other is non-empty. There are two important
// differences between DataSource and DataSourceRef: * While
// DataSource only allows two specific types of objects,
// DataSourceRef allows any non-core object, as well as
// PersistentVolumeClaim objects. * While DataSource ignores
// disallowed values (dropping them), DataSourceRef preserves all
// values, and generates an error if a disallowed value is
// specified. (Beta) Using this field requires the
// AnyVolumeDataSource feature gate to be enabled.
dataSourceRef?: {
// APIGroup is the group for the resource being referenced. If
// APIGroup is not specified, the specified Kind must be in the
// core API group. For any other third-party types, APIGroup is
// required.
apiGroup?: string
// Kind is the type of resource being referenced
kind: string
// Name is the name of resource being referenced
name: string
}
// resources represents the minimum resources the volume should
// have. If RecoverVolumeExpansionFailure feature is enabled
// users are allowed to specify resource requirements that are
// lower than previous value but must still be higher than
// capacity recorded in the status field of the claim. More info:
// https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
resources?: {
// Limits describes the maximum amount of compute resources
// allowed. More info:
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
limits?: {
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
}
// Requests describes the minimum amount of compute resources
// required. If Requests is omitted for a container, it defaults
// to Limits if that is explicitly specified, otherwise to an
// implementation-defined value. More info:
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
requests?: {
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
}
}
// selector is a label query over volumes to consider for binding.
selector?: {
// matchExpressions is a list of label selector requirements. The
// requirements are ANDed.
matchExpressions?: [...{
// key is the label key that the selector applies to.
key: string
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
operator: string
// values is an array of string values. If the operator is In or
// NotIn, the values array must be non-empty. If the operator is
// Exists or DoesNotExist, the values array must be empty. This
// array is replaced during a strategic merge patch.
values?: [...string]
}]
// matchLabels is a map of {key,value} pairs. A single {key,value}
// in the matchLabels map is equivalent to an element of
// matchExpressions, whose key field is "key", the operator is
// "In", and the values array contains only "value". The
// requirements are ANDed.
matchLabels?: {
[string]: string
}
}
// storageClassName is the name of the StorageClass required by
// the claim. More info:
// https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
storageClassName?: string
// volumeMode defines what type of volume is required by the
// claim. Value of Filesystem is implied when not included in
// claim spec.
volumeMode?: string
// volumeName is the binding reference to the PersistentVolume
// backing this claim.
volumeName?: string
}
// The image name to use for pgAdmin instance.
image?: string
// ImagePullPolicy is used to determine when Kubernetes will
// attempt to pull (download) container images. More info:
// https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy
imagePullPolicy?: "Always" | "Never" | "IfNotPresent"
// The image pull secrets used to pull from a private registry.
// Changing this value causes all running PGAdmin pods to
// restart.
// https://k8s.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets?: [...{
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name?: string
}]
// Metadata contains metadata for custom resources
metadata?: {
annotations?: {
[string]: string
}
labels?: {
[string]: string
}
}
// Priority class name for the PGAdmin pod. Changing this value
// causes PGAdmin pod to restart. More info:
// https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/
priorityClassName?: string
// Resource requirements for the PGAdmin container.
resources?: {
// Limits describes the maximum amount of compute resources
// allowed. More info:
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
limits?: {
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
}
// Requests describes the minimum amount of compute resources
// required. If Requests is omitted for a container, it defaults
// to Limits if that is explicitly specified, otherwise to an
// implementation-defined value. More info:
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
requests?: {
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
}
}
// ServerGroups for importing PostgresClusters to pgAdmin. To
// create a pgAdmin with no selectors, leave this field empty. A
// pgAdmin created with no `ServerGroups` will not automatically
// add any servers through discovery. PostgresClusters can still
// be added manually.
serverGroups?: [...{
// The name for the ServerGroup in pgAdmin. Must be unique in the
// pgAdmin's ServerGroups since it becomes the ServerGroup name
// in pgAdmin.
name: string
// PostgresClusterSelector selects clusters to dynamically add to
// pgAdmin by matching labels. An empty selector like `{}` will
// select ALL clusters in the namespace.
postgresClusterSelector: {
// 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
}
}
}]
// Tolerations of the PGAdmin pod. More info:
// https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
tolerations?: [...{
// Effect indicates the taint effect to match. Empty means match
// all taint effects. When specified, allowed values are
// NoSchedule, PreferNoSchedule and NoExecute.
effect?: string
// Key is the taint key that the toleration applies to. Empty
// means match all taint keys. If the key is empty, operator must
// be Exists; this combination means to match all values and all
// keys.
key?: string
// Operator represents a key's relationship to the value. Valid
// operators are Exists and Equal. Defaults to Equal. Exists is
// equivalent to wildcard for value, so that a pod can tolerate
// all taints of a particular category.
operator?: string
// TolerationSeconds represents the period of time the toleration
// (which must be of effect NoExecute, otherwise this field is
// ignored) tolerates the taint. By default, it is not set, which
// means tolerate the taint forever (do not evict). Zero and
// negative values will be treated as 0 (evict immediately) by
// the system.
tolerationSeconds?: int
// Value is the taint value the toleration matches to. If the
// operator is Exists, the value should be empty, otherwise just
// a regular string.
value?: string
}]
}

View File

@@ -0,0 +1,632 @@
// Code generated by timoni. DO NOT EDIT.
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/core2/components/prod-pgo-crds/prod-pgo-crds.gen.yaml
package v1beta1
import "strings"
// PGUpgrade is the Schema for the pgupgrades API
#PGUpgrade: {
// 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: "postgres-operator.crunchydata.com/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: "PGUpgrade"
metadata!: {
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
string
}
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
string
}
labels?: {
[string]: string
}
annotations?: {
[string]: string
}
}
// PGUpgradeSpec defines the desired state of PGUpgrade
spec!: #PGUpgradeSpec
}
// PGUpgradeSpec defines the desired state of PGUpgrade
#PGUpgradeSpec: {
// Scheduling constraints of the PGUpgrade pod. More info:
// https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node
affinity?: {
// Describes node affinity scheduling rules for the pod.
nodeAffinity?: {
// The scheduler will prefer to schedule pods to nodes that
// satisfy the affinity expressions specified by this field, but
// it may choose a node that violates one or more of the
// expressions. The node that is most preferred is the one with
// the greatest sum of weights, i.e. for each node that meets all
// of the scheduling requirements (resource request,
// requiredDuringScheduling affinity expressions, etc.), compute
// a sum by iterating through the elements of this field and
// adding "weight" to the sum if the node matches the
// corresponding matchExpressions; the node(s) with the highest
// sum are the most preferred.
preferredDuringSchedulingIgnoredDuringExecution?: [...{
// A node selector term, associated with the corresponding weight.
preference: {
// A list of node selector requirements by node's labels.
matchExpressions?: [...{
// The label key that the selector applies to.
key: string
// Represents a key's relationship to a set of values. Valid
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
operator: string
// 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. If the operator
// is Gt or Lt, the values array must have a single element,
// which will be interpreted as an integer. This array is
// replaced during a strategic merge patch.
values?: [...string]
}]
// A list of node selector requirements by node's fields.
matchFields?: [...{
// The label key that the selector applies to.
key: string
// Represents a key's relationship to a set of values. Valid
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
operator: string
// 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. If the operator
// is Gt or Lt, the values array must have a single element,
// which will be interpreted as an integer. This array is
// replaced during a strategic merge patch.
values?: [...string]
}]
}
// Weight associated with matching the corresponding
// nodeSelectorTerm, in the range 1-100.
weight: int
}]
requiredDuringSchedulingIgnoredDuringExecution?: {
// Required. A list of node selector terms. The terms are ORed.
nodeSelectorTerms: [...{
// A list of node selector requirements by node's labels.
matchExpressions?: [...{
// The label key that the selector applies to.
key: string
// Represents a key's relationship to a set of values. Valid
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
operator: string
// 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. If the operator
// is Gt or Lt, the values array must have a single element,
// which will be interpreted as an integer. This array is
// replaced during a strategic merge patch.
values?: [...string]
}]
// A list of node selector requirements by node's fields.
matchFields?: [...{
// The label key that the selector applies to.
key: string
// Represents a key's relationship to a set of values. Valid
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
operator: string
// 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. If the operator
// is Gt or Lt, the values array must have a single element,
// which will be interpreted as an integer. This array is
// replaced during a strategic merge patch.
values?: [...string]
}]
}]
}
}
// Describes pod affinity scheduling rules (e.g. co-locate this
// pod in the same node, zone, etc. as some other pod(s)).
podAffinity?: {
// The scheduler will prefer to schedule pods to nodes that
// satisfy the affinity expressions specified by this field, but
// it may choose a node that violates one or more of the
// expressions. The node that is most preferred is the one with
// the greatest sum of weights, i.e. for each node that meets all
// of the scheduling requirements (resource request,
// requiredDuringScheduling affinity expressions, etc.), compute
// a sum by iterating through the elements of this field and
// adding "weight" to the sum if the node has pods which matches
// the corresponding podAffinityTerm; the node(s) with the
// highest sum are the most preferred.
preferredDuringSchedulingIgnoredDuringExecution?: [...{
// Required. A pod affinity term, associated with the
// corresponding weight.
podAffinityTerm: {
// A label query over a set of resources, in this case pods.
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
}
}
// A label query over the set of namespaces that the term applies
// to. The term is applied to the union of the namespaces
// selected by this field and the ones listed in the namespaces
// field. null selector and null or empty namespaces list means
// "this pod's namespace". An empty selector ({}) matches all
// namespaces.
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
}
}
// namespaces specifies a static list of namespace names that the
// term applies to. The term is applied to the union of the
// namespaces listed in this field and the ones selected by
// namespaceSelector. null or empty namespaces list and null
// namespaceSelector means "this pod's namespace".
namespaces?: [...string]
// This pod should be co-located (affinity) or not co-located
// (anti-affinity) with the pods matching the labelSelector in
// the specified namespaces, where co-located is defined as
// running on a node whose value of the label with key
// topologyKey matches that of any node on which any of the
// selected pods is running. Empty topologyKey is not allowed.
topologyKey: string
}
// weight associated with matching the corresponding
// podAffinityTerm, in the range 1-100.
weight: int
}]
// If the affinity requirements specified by this field are not
// met at scheduling time, the pod will not be scheduled onto the
// node. If the affinity requirements specified by this field
// cease to be met at some point during pod execution (e.g. due
// to a pod label update), the system may or may not try to
// eventually evict the pod from its node. When there are
// multiple elements, the lists of nodes corresponding to each
// podAffinityTerm are intersected, i.e. all terms must be
// satisfied.
requiredDuringSchedulingIgnoredDuringExecution?: [...{
// A label query over a set of resources, in this case pods.
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
}
}
// A label query over the set of namespaces that the term applies
// to. The term is applied to the union of the namespaces
// selected by this field and the ones listed in the namespaces
// field. null selector and null or empty namespaces list means
// "this pod's namespace". An empty selector ({}) matches all
// namespaces.
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
}
}
// namespaces specifies a static list of namespace names that the
// term applies to. The term is applied to the union of the
// namespaces listed in this field and the ones selected by
// namespaceSelector. null or empty namespaces list and null
// namespaceSelector means "this pod's namespace".
namespaces?: [...string]
// This pod should be co-located (affinity) or not co-located
// (anti-affinity) with the pods matching the labelSelector in
// the specified namespaces, where co-located is defined as
// running on a node whose value of the label with key
// topologyKey matches that of any node on which any of the
// selected pods is running. Empty topologyKey is not allowed.
topologyKey: string
}]
}
// Describes pod anti-affinity scheduling rules (e.g. avoid
// putting this pod in the same node, zone, etc. as some other
// pod(s)).
podAntiAffinity?: {
// The scheduler will prefer to schedule pods to nodes that
// satisfy the anti-affinity expressions specified by this field,
// but it may choose a node that violates one or more of the
// expressions. The node that is most preferred is the one with
// the greatest sum of weights, i.e. for each node that meets all
// of the scheduling requirements (resource request,
// requiredDuringScheduling anti-affinity expressions, etc.),
// compute a sum by iterating through the elements of this field
// and adding "weight" to the sum if the node has pods which
// matches the corresponding podAffinityTerm; the node(s) with
// the highest sum are the most preferred.
preferredDuringSchedulingIgnoredDuringExecution?: [...{
// Required. A pod affinity term, associated with the
// corresponding weight.
podAffinityTerm: {
// A label query over a set of resources, in this case pods.
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
}
}
// A label query over the set of namespaces that the term applies
// to. The term is applied to the union of the namespaces
// selected by this field and the ones listed in the namespaces
// field. null selector and null or empty namespaces list means
// "this pod's namespace". An empty selector ({}) matches all
// namespaces.
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
}
}
// namespaces specifies a static list of namespace names that the
// term applies to. The term is applied to the union of the
// namespaces listed in this field and the ones selected by
// namespaceSelector. null or empty namespaces list and null
// namespaceSelector means "this pod's namespace".
namespaces?: [...string]
// This pod should be co-located (affinity) or not co-located
// (anti-affinity) with the pods matching the labelSelector in
// the specified namespaces, where co-located is defined as
// running on a node whose value of the label with key
// topologyKey matches that of any node on which any of the
// selected pods is running. Empty topologyKey is not allowed.
topologyKey: string
}
// weight associated with matching the corresponding
// podAffinityTerm, in the range 1-100.
weight: int
}]
// If the anti-affinity requirements specified by this field are
// not met at scheduling time, the pod will not be scheduled onto
// the node. If the anti-affinity requirements specified by this
// field cease to be met at some point during pod execution (e.g.
// due to a pod label update), the system may or may not try to
// eventually evict the pod from its node. When there are
// multiple elements, the lists of nodes corresponding to each
// podAffinityTerm are intersected, i.e. all terms must be
// satisfied.
requiredDuringSchedulingIgnoredDuringExecution?: [...{
// A label query over a set of resources, in this case pods.
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
}
}
// A label query over the set of namespaces that the term applies
// to. The term is applied to the union of the namespaces
// selected by this field and the ones listed in the namespaces
// field. null selector and null or empty namespaces list means
// "this pod's namespace". An empty selector ({}) matches all
// namespaces.
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
}
}
// namespaces specifies a static list of namespace names that the
// term applies to. The term is applied to the union of the
// namespaces listed in this field and the ones selected by
// namespaceSelector. null or empty namespaces list and null
// namespaceSelector means "this pod's namespace".
namespaces?: [...string]
// This pod should be co-located (affinity) or not co-located
// (anti-affinity) with the pods matching the labelSelector in
// the specified namespaces, where co-located is defined as
// running on a node whose value of the label with key
// topologyKey matches that of any node on which any of the
// selected pods is running. Empty topologyKey is not allowed.
topologyKey: string
}]
}
}
// The major version of PostgreSQL before the upgrade.
fromPostgresVersion: uint & >=10 & <=16
// The image name to use for major PostgreSQL upgrades.
image?: string
// ImagePullPolicy is used to determine when Kubernetes will
// attempt to pull (download) container images. More info:
// https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy
imagePullPolicy?: "Always" | "Never" | "IfNotPresent"
// The image pull secrets used to pull from a private registry.
// Changing this value causes all running PGUpgrade pods to
// restart.
// https://k8s.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets?: [...{
// Name of the referent. More info:
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
name?: string
}]
// Metadata contains metadata for custom resources
metadata?: {
annotations?: {
[string]: string
}
labels?: {
[string]: string
}
}
// The name of the cluster to be updated
postgresClusterName: strings.MinRunes(1)
// Priority class name for the PGUpgrade pod. Changing this value
// causes PGUpgrade pod to restart. More info:
// https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/
priorityClassName?: string
// Resource requirements for the PGUpgrade container.
resources?: {
// Limits describes the maximum amount of compute resources
// allowed. More info:
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
limits?: {
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
}
// Requests describes the minimum amount of compute resources
// required. If Requests is omitted for a container, it defaults
// to Limits if that is explicitly specified, otherwise to an
// implementation-defined value. More info:
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
requests?: {
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
}
}
// The image name to use for PostgreSQL containers after upgrade.
// When omitted, the value comes from an operator environment
// variable.
toPostgresImage?: string
// The major version of PostgreSQL to be upgraded to.
toPostgresVersion: uint & >=10 & <=16
// Tolerations of the PGUpgrade pod. More info:
// https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
tolerations?: [...{
// Effect indicates the taint effect to match. Empty means match
// all taint effects. When specified, allowed values are
// NoSchedule, PreferNoSchedule and NoExecute.
effect?: string
// Key is the taint key that the toleration applies to. Empty
// means match all taint keys. If the key is empty, operator must
// be Exists; this combination means to match all values and all
// keys.
key?: string
// Operator represents a key's relationship to the value. Valid
// operators are Exists and Equal. Defaults to Equal. Exists is
// equivalent to wildcard for value, so that a pod can tolerate
// all taints of a particular category.
operator?: string
// TolerationSeconds represents the period of time the toleration
// (which must be of effect NoExecute, otherwise this field is
// ignored) tolerates the taint. By default, it is not set, which
// means tolerate the taint forever (do not evict). Zero and
// negative values will be treated as 0 (evict immediately) by
// the system.
tolerationSeconds?: int
// Value is the taint value the toleration matches to. If the
// operator is Exists, the value should be empty, otherwise just
// a regular string.
value?: string
}]
}

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
_#_BuiltinPluginLoadingOptions_name: "BploUndefinedBploUseStaticallyLinkedBploLoadFromFileSys"

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// ConfigMapArgs contains the metadata of how to generate a configmap.
#ConfigMapArgs: {
#GeneratorArgs
}

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
// Package types holds the definition of the kustomization struct and
// supporting structs. It's the k8s API conformant object that describes
// a set of generation and transformation operations to create and/or
// modify k8s resources.
// A kustomization file is a serialization of this struct.
package types

View File

@@ -0,0 +1,29 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// FieldSpec completely specifies a kustomizable field in a k8s API object.
// It helps define the operands of transformations.
//
// For example, a directive to add a common label to objects
// will need to know that a 'Deployment' object (in API group
// 'apps', any version) can have labels at field path
// 'spec/template/metadata/labels', and further that it is OK
// (or not OK) to add that field path to the object if the
// field path doesn't exist already.
//
// This would look like
// {
// group: apps
// kind: Deployment
// path: spec/template/metadata/labels
// create: true
// }
#FieldSpec: {
path?: string @go(Path)
create?: bool @go(CreateIfNotPresent)
}
#FsSlice: [...#FieldSpec]

View File

@@ -0,0 +1,33 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// GenerationBehavior specifies generation behavior of configmaps, secrets and maybe other resources.
#GenerationBehavior: int // #enumGenerationBehavior
#enumGenerationBehavior:
#BehaviorUnspecified |
#BehaviorCreate |
#BehaviorReplace |
#BehaviorMerge
#values_GenerationBehavior: {
BehaviorUnspecified: #BehaviorUnspecified
BehaviorCreate: #BehaviorCreate
BehaviorReplace: #BehaviorReplace
BehaviorMerge: #BehaviorMerge
}
// BehaviorUnspecified is an Unspecified behavior; typically treated as a Create.
#BehaviorUnspecified: #GenerationBehavior & 0
// BehaviorCreate makes a new resource.
#BehaviorCreate: #GenerationBehavior & 1
// BehaviorReplace replaces a resource.
#BehaviorReplace: #GenerationBehavior & 2
// BehaviorMerge attempts to merge a new resource with an existing resource.
#BehaviorMerge: #GenerationBehavior & 3

View File

@@ -0,0 +1,27 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// GeneratorArgs contains arguments common to ConfigMap and Secret generators.
#GeneratorArgs: {
// Namespace for the resource, optional
namespace?: string @go(Namespace)
// Name - actually the partial name - of the generated resource.
// The full name ends up being something like
// NamePrefix + this.Name + hash(content of generated resource).
name?: string @go(Name)
// Behavior of generated resource, must be one of:
// 'create': create a new one
// 'replace': replace the existing one
// 'merge': merge with the existing one
behavior?: string @go(Behavior)
#KvPairSources
// Local overrides to global generatorOptions field.
options?: null | #GeneratorOptions @go(Options,*GeneratorOptions)
}

View File

@@ -0,0 +1,22 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// GeneratorOptions modify behavior of all ConfigMap and Secret generators.
#GeneratorOptions: {
// Labels to add to all generated resources.
labels?: {[string]: string} @go(Labels,map[string]string)
// Annotations to add to all generated resources.
annotations?: {[string]: string} @go(Annotations,map[string]string)
// DisableNameSuffixHash if true disables the default behavior of adding a
// suffix to the names of generated resources that is a hash of the
// resource contents.
disableNameSuffixHash?: bool @go(DisableNameSuffixHash)
// Immutable if true add to all generated resources.
immutable?: bool @go(Immutable)
}

View File

@@ -0,0 +1,116 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
#HelmDefaultHome: "charts"
#HelmGlobals: {
// ChartHome is a file path, relative to the kustomization root,
// to a directory containing a subdirectory for each chart to be
// included in the kustomization.
// The default value of this field is "charts".
// So, for example, kustomize looks for the minecraft chart
// at {kustomizationRoot}/{ChartHome}/minecraft.
// If the chart is there at build time, kustomize will use it as found,
// and not check version numbers or dates.
// If the chart is not there, kustomize will attempt to pull it
// using the version number specified in the kustomization file,
// and put it there. To suppress the pull attempt, simply assure
// that the chart is already there.
chartHome?: string @go(ChartHome)
// ConfigHome defines a value that kustomize should pass to helm via
// the HELM_CONFIG_HOME environment variable. kustomize doesn't attempt
// to read or write this directory.
// If omitted, {tmpDir}/helm is used, where {tmpDir} is some temporary
// directory created by kustomize for the benefit of helm.
// Likewise, kustomize sets
// HELM_CACHE_HOME={ConfigHome}/.cache
// HELM_DATA_HOME={ConfigHome}/.data
// for the helm subprocess.
configHome?: string @go(ConfigHome)
}
#HelmChart: {
// Name is the name of the chart, e.g. 'minecraft'.
name?: string @go(Name)
// Version is the version of the chart, e.g. '3.1.3'
version?: string @go(Version)
// Repo is a URL locating the chart on the internet.
// This is the argument to helm's `--repo` flag, e.g.
// `https://itzg.github.io/minecraft-server-charts`.
repo?: string @go(Repo)
// ReleaseName replaces RELEASE-NAME in chart template output,
// making a particular inflation of a chart unique with respect to
// other inflations of the same chart in a cluster. It's the first
// argument to the helm `install` and `template` commands, i.e.
// helm install {RELEASE-NAME} {chartName}
// helm template {RELEASE-NAME} {chartName}
// If omitted, the flag --generate-name is passed to 'helm template'.
releaseName?: string @go(ReleaseName)
// Namespace set the target namespace for a release. It is .Release.Namespace
// in the helm template
namespace?: string @go(Namespace)
// AdditionalValuesFiles are local file paths to values files to be used in
// addition to either the default values file or the values specified in ValuesFile.
additionalValuesFiles?: [...string] @go(AdditionalValuesFiles,[]string)
// ValuesFile is a local file path to a values file to use _instead of_
// the default values that accompanied the chart.
// The default values are in '{ChartHome}/{Name}/values.yaml'.
valuesFile?: string @go(ValuesFile)
// ValuesInline holds value mappings specified directly,
// rather than in a separate file.
valuesInline?: {...} @go(ValuesInline,map[string]interface{})
// ValuesMerge specifies how to treat ValuesInline with respect to Values.
// Legal values: 'merge', 'override', 'replace'.
// Defaults to 'override'.
valuesMerge?: string @go(ValuesMerge)
// IncludeCRDs specifies if Helm should also generate CustomResourceDefinitions.
// Defaults to 'false'.
includeCRDs?: bool @go(IncludeCRDs)
// SkipHooks sets the --no-hooks flag when calling helm template. This prevents
// helm from erroneously rendering test templates.
skipHooks?: bool @go(SkipHooks)
// ApiVersions is the kubernetes apiversions used for Capabilities.APIVersions
apiVersions?: [...string] @go(ApiVersions,[]string)
// KubeVersion is the kubernetes version used by Helm for Capabilities.KubeVersion"
kubeVersion?: string @go(KubeVersion)
// NameTemplate is for specifying the name template used to name the release.
nameTemplate?: string @go(NameTemplate)
// SkipTests skips tests from templated output.
skipTests?: bool @go(SkipTests)
}
// HelmChartArgs contains arguments to helm.
// Deprecated. Use HelmGlobals and HelmChart instead.
#HelmChartArgs: {
chartName?: string @go(ChartName)
chartVersion?: string @go(ChartVersion)
chartRepoUrl?: string @go(ChartRepoURL)
chartHome?: string @go(ChartHome)
chartRepoName?: string @go(ChartRepoName)
helmBin?: string @go(HelmBin)
helmHome?: string @go(HelmHome)
values?: string @go(Values)
valuesLocal?: {...} @go(ValuesLocal,map[string]interface{})
valuesMerge?: string @go(ValuesMerge)
releaseName?: string @go(ReleaseName)
releaseNamespace?: string @go(ReleaseNamespace)
extraArgs?: [...string] @go(ExtraArgs,[]string)
}

View File

@@ -0,0 +1,40 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
#Cloud: string // #enumCloud
#enumCloud:
#GKE
#GKE: #Cloud & "gke"
// IAMPolicyGeneratorArgs contains arguments to generate a GKE service account resource.
#IAMPolicyGeneratorArgs: {
// which cloud provider to generate for (e.g. "gke")
cloud: #Cloud @go(Cloud)
// information about the kubernetes cluster for this object
kubernetesService: #KubernetesService @go(KubernetesService)
// information about the service account and project
serviceAccount: #ServiceAccount @go(ServiceAccount)
}
#KubernetesService: {
// the name used for the Kubernetes service account
name: string @go(Name)
// the name of the Kubernetes namespace for this object
namespace?: string @go(Namespace)
}
#ServiceAccount: {
// the name of the new cloud provider service account
name: string @go(Name)
// The ID of the project
projectId: string @go(ProjectId)
}

View File

@@ -0,0 +1,26 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// Image contains an image name, a new name, a new tag or digest,
// which will replace the original name and tag.
#Image: {
// Name is a tag-less image name.
name?: string @go(Name)
// NewName is the value used to replace the original name.
newName?: string @go(NewName)
// TagSuffix is the value used to suffix the original tag
// If Digest and NewTag is present an error is thrown
tagSuffix?: string @go(TagSuffix)
// NewTag is the value used to replace the original tag.
newTag?: string @go(NewTag)
// Digest is the value used to replace the original image tag.
// If digest is present NewTag value is ignored.
digest?: string @go(Digest)
}

View File

@@ -0,0 +1,163 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
#KustomizationVersion: "kustomize.config.k8s.io/v1beta1"
#KustomizationKind: "Kustomization"
#ComponentVersion: "kustomize.config.k8s.io/v1alpha1"
#ComponentKind: "Component"
#MetadataNamespacePath: "metadata/namespace"
#MetadataNamespaceApiVersion: "v1"
#MetadataNamePath: "metadata/name"
#OriginAnnotations: "originAnnotations"
#TransformerAnnotations: "transformerAnnotations"
#ManagedByLabelOption: "managedByLabel"
// Kustomization holds the information needed to generate customized k8s api resources.
#Kustomization: {
#TypeMeta
// MetaData is a pointer to avoid marshalling empty struct
metadata?: null | #ObjectMeta @go(MetaData,*ObjectMeta)
// OpenAPI contains information about what kubernetes schema to use.
openapi?: {[string]: string} @go(OpenAPI,map[string]string)
// NamePrefix will prefix the names of all resources mentioned in the kustomization
// file including generated configmaps and secrets.
namePrefix?: string @go(NamePrefix)
// NameSuffix will suffix the names of all resources mentioned in the kustomization
// file including generated configmaps and secrets.
nameSuffix?: string @go(NameSuffix)
// Namespace to add to all objects.
namespace?: string @go(Namespace)
// CommonLabels to add to all objects and selectors.
commonLabels?: {[string]: string} @go(CommonLabels,map[string]string)
// Labels to add to all objects but not selectors.
labels?: [...#Label] @go(Labels,[]Label)
// CommonAnnotations to add to all objects.
commonAnnotations?: {[string]: string} @go(CommonAnnotations,map[string]string)
// Deprecated: Use the Patches field instead, which provides a superset of the functionality of PatchesStrategicMerge.
// PatchesStrategicMerge specifies the relative path to a file
// containing a strategic merge patch. Format documented at
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md
// URLs and globs are not supported.
patchesStrategicMerge?: [...#PatchStrategicMerge] @go(PatchesStrategicMerge,[]PatchStrategicMerge)
// Deprecated: Use the Patches field instead, which provides a superset of the functionality of JSONPatches.
// JSONPatches is a list of JSONPatch for applying JSON patch.
// Format documented at https://tools.ietf.org/html/rfc6902
// and http://jsonpatch.com
patchesJson6902?: [...#Patch] @go(PatchesJson6902,[]Patch)
// Patches is a list of patches, where each one can be either a
// Strategic Merge Patch or a JSON patch.
// Each patch can be applied to multiple target objects.
patches?: [...#Patch] @go(Patches,[]Patch)
// 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?: [...#Image] @go(Images,[]Image)
// Deprecated: Use the Images field instead.
imageTags?: [...#Image] @go(ImageTags,[]Image)
// Replacements is a list of replacements, which will copy nodes from a
// specified source to N specified targets.
replacements?: [...#ReplacementField] @go(Replacements,[]ReplacementField)
// Replicas is a list of {resourcename, count} that allows for simpler replica
// specification. This can also be done with a patch.
replicas?: [...#Replica] @go(Replicas,[]Replica)
// Deprecated: Vars will be removed in future release. Migrate to Replacements instead.
// Vars allow things modified by kustomize to be injected into a
// kubernetes object specification. A var is a name (e.g. FOO) associated
// with a field in a specific resource instance. The field must
// contain a value of type string/bool/int/float, and defaults to the name field
// of the instance. Any appearance of "$(FOO)" in the object
// spec will be replaced at kustomize build time, after the final
// value of the specified field has been determined.
vars?: [...#Var] @go(Vars,[]Var)
// SortOptions change the order that kustomize outputs resources.
sortOptions?: null | #SortOptions @go(SortOptions,*SortOptions)
// Resources specifies relative paths to files holding YAML representations
// of kubernetes API objects, or specifications of other kustomizations
// via relative paths, absolute paths, or URLs.
resources?: [...string] @go(Resources,[]string)
// Components specifies relative paths to specifications of other Components
// via relative paths, absolute paths, or URLs.
components?: [...string] @go(Components,[]string)
// Crds specifies relative paths to Custom Resource Definition files.
// This allows custom resources to be recognized as operands, making
// it possible to add them to the Resources list.
// CRDs themselves are not modified.
crds?: [...string] @go(Crds,[]string)
// Deprecated: Anything that would have been specified here should be specified in the Resources field instead.
bases?: [...string] @go(Bases,[]string)
// ConfigMapGenerator is a list of configmaps to generate from
// local data (one configMap per list item).
// The resulting resource is a normal operand, subject to
// name prefixing, patching, etc. By default, the name of
// the map will have a suffix hash generated from its contents.
configMapGenerator?: [...#ConfigMapArgs] @go(ConfigMapGenerator,[]ConfigMapArgs)
// SecretGenerator is a list of secrets to generate from
// local data (one secret per list item).
// The resulting resource is a normal operand, subject to
// name prefixing, patching, etc. By default, the name of
// the map will have a suffix hash generated from its contents.
secretGenerator?: [...#SecretArgs] @go(SecretGenerator,[]SecretArgs)
// HelmGlobals contains helm configuration that isn't chart specific.
helmGlobals?: null | #HelmGlobals @go(HelmGlobals,*HelmGlobals)
// HelmCharts is a list of helm chart configuration instances.
helmCharts?: [...#HelmChart] @go(HelmCharts,[]HelmChart)
// HelmChartInflationGenerator is a list of helm chart configurations.
// Deprecated. Auto-converted to HelmGlobals and HelmCharts.
helmChartInflationGenerator?: [...#HelmChartArgs] @go(HelmChartInflationGenerator,[]HelmChartArgs)
// GeneratorOptions modify behavior of all ConfigMap and Secret generators.
generatorOptions?: null | #GeneratorOptions @go(GeneratorOptions,*GeneratorOptions)
// Configurations is a list of transformer configuration files
configurations?: [...string] @go(Configurations,[]string)
// Generators is a list of files containing custom generators
generators?: [...string] @go(Generators,[]string)
// Transformers is a list of files containing transformers
transformers?: [...string] @go(Transformers,[]string)
// Validators is a list of files containing validators
validators?: [...string] @go(Validators,[]string)
// BuildMetadata is a list of strings used to toggle different build options
buildMetadata?: [...string] @go(BuildMetadata,[]string)
}
_#deprecatedWarningToRunEditFix: "Run 'kustomize edit fix' to update your Kustomization automatically."
_#deprecatedWarningToRunEditFixExperimential: "[EXPERIMENTAL] Run 'kustomize edit fix' to update your Kustomization automatically."
_#deprecatedBaseWarningMessage: "# Warning: 'bases' is deprecated. Please use 'resources' instead. Run 'kustomize edit fix' to update your Kustomization automatically."
_#deprecatedImageTagsWarningMessage: "# Warning: 'imageTags' is deprecated. Please use 'images' instead. Run 'kustomize edit fix' to update your Kustomization automatically."
_#deprecatedPatchesJson6902Message: "# Warning: 'patchesJson6902' is deprecated. Please use 'patches' instead. Run 'kustomize edit fix' to update your Kustomization automatically."
_#deprecatedPatchesStrategicMergeMessage: "# Warning: 'patchesStrategicMerge' is deprecated. Please use 'patches' instead. Run 'kustomize edit fix' to update your Kustomization automatically."
_#deprecatedVarsMessage: "# Warning: 'vars' is deprecated. Please use 'replacements' instead. [EXPERIMENTAL] Run 'kustomize edit fix' to update your Kustomization automatically."
_#deprecatedCommonLabelsWarningMessage: "# Warning: 'commonLabels' is deprecated. Please use 'labels' instead. Run 'kustomize edit fix' to update your Kustomization automatically."

View File

@@ -0,0 +1,37 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// KvPairSources defines places to obtain key value pairs.
#KvPairSources: {
// LiteralSources is a list of literal
// pair sources. Each literal source should
// be a key and literal value, e.g. `key=value`
literals?: [...string] @go(LiteralSources,[]string)
// FileSources is a list of file "sources" to
// use in creating a list of key, value pairs.
// A source takes the form: [{key}=]{path}
// If the "key=" part is missing, the key is the
// path's basename. If they "key=" part is present,
// it becomes the key (replacing the basename).
// In either case, the value is the file contents.
// Specifying a directory will iterate each named
// file in the directory whose basename is a
// valid configmap key.
files?: [...string] @go(FileSources,[]string)
// EnvSources is a list of file paths.
// The contents of each file should be one
// key=value pair per line, e.g. a Docker
// or npm ".env" file or a ".ini" file
// (wikipedia.org/wiki/INI_file)
envs?: [...string] @go(EnvSources,[]string)
// Older, singular form of EnvSources.
// On edits (e.g. `kustomize fix`) this is merged into the plural form
// for consistency with LiteralSources and FileSources.
env?: string @go(EnvSource)
}

View File

@@ -0,0 +1,23 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
#Label: {
// Pairs contains the key-value pairs for labels to add
pairs?: {[string]: string} @go(Pairs,map[string]string)
// IncludeSelectors inidicates should transformer include the
// fieldSpecs for selectors. Custom fieldSpecs specified by
// FieldSpecs will be merged with builtin fieldSpecs if this
// is true.
includeSelectors?: bool @go(IncludeSelectors)
// IncludeTemplates inidicates should transformer include the
// spec/template/metadata fieldSpec. Custom fieldSpecs specified by
// FieldSpecs will be merged with spec/template/metadata fieldSpec if this
// is true. If IncludeSelectors is true, IncludeTemplates is not needed.
includeTemplates?: bool @go(IncludeTemplates)
fields?: [...#FieldSpec] @go(FieldSpecs,[]FieldSpec)
}

View File

@@ -0,0 +1,34 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// Restrictions on what things can be referred to
// in a kustomization file.
//
//go:generate stringer -type=LoadRestrictions
#LoadRestrictions: int // #enumLoadRestrictions
#enumLoadRestrictions:
#LoadRestrictionsUnknown |
#LoadRestrictionsRootOnly |
#LoadRestrictionsNone
#values_LoadRestrictions: {
LoadRestrictionsUnknown: #LoadRestrictionsUnknown
LoadRestrictionsRootOnly: #LoadRestrictionsRootOnly
LoadRestrictionsNone: #LoadRestrictionsNone
}
#LoadRestrictionsUnknown: #LoadRestrictions & 0
// Files referenced by a kustomization file must be in
// or under the directory holding the kustomization
// file itself.
#LoadRestrictionsRootOnly: #LoadRestrictions & 1
// The kustomization file may specify absolute or
// relative paths to patch or resources files outside
// its own tree.
#LoadRestrictionsNone: #LoadRestrictions & 2

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
_#_LoadRestrictions_name: "LoadRestrictionsUnknownLoadRestrictionsRootOnlyLoadRestrictionsNone"

View File

@@ -0,0 +1,14 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// ObjectMeta partially copies apimachinery/pkg/apis/meta/v1.ObjectMeta
// No need for a direct dependence; the fields are stable.
#ObjectMeta: {
name?: string @go(Name)
namespace?: string @go(Namespace)
labels?: {[string]: string} @go(Labels,map[string]string)
annotations?: {[string]: string} @go(Annotations,map[string]string)
}

View File

@@ -0,0 +1,11 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// Pair is a key value pair.
#Pair: {
Key: string
Value: string
}

View File

@@ -0,0 +1,23 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// Patch represent either a Strategic Merge Patch or a JSON patch
// and its targets.
// The content of the patch can either be from a file
// or from an inline string.
#Patch: {
// Path is a relative file path to the patch file.
path?: string @go(Path)
// Patch is the content of a patch.
patch?: string @go(Patch)
// Target points to the resources that the patch is applied to
target?: #Target | #Selector @go(Target,*Selector)
// Options is a list of options for the patch
options?: {[string]: bool} @go(Options,map[string]bool)
}

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// PatchStrategicMerge represents a relative path to a
// stategic merge patch with the format
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md
#PatchStrategicMerge: string

View File

@@ -0,0 +1,27 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
#HelmConfig: {
Enabled: bool
Command: string
ApiVersions: [...string] @go(,[]string)
KubeVersion: string
}
// PluginConfig holds plugin configuration.
#PluginConfig: {
// PluginRestrictions distinguishes plugin restrictions.
PluginRestrictions: #PluginRestrictions
// BpLoadingOptions distinguishes builtin plugin behaviors.
BpLoadingOptions: #BuiltinPluginLoadingOptions
// FnpLoadingOptions sets the way function-based plugin behaviors.
FnpLoadingOptions: #FnPluginLoadingOptions
// HelmConfig contains metadata needed for allowing and running helm.
HelmConfig: #HelmConfig
}

View File

@@ -0,0 +1,87 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// Some plugin classes
// - builtin: plugins defined in the kustomize repo.
// May be freely used and re-configured.
// - local: plugins that aren't builtin but are
// locally defined (presumably by the user), meaning
// the kustomization refers to them via a relative
// file path, not a URL.
// - remote: require a build-time download to obtain.
// Unadvised, unless one controls the
// serving site.
//
//go:generate stringer -type=PluginRestrictions
#PluginRestrictions: int // #enumPluginRestrictions
#enumPluginRestrictions:
#PluginRestrictionsUnknown |
#PluginRestrictionsBuiltinsOnly |
#PluginRestrictionsNone
#values_PluginRestrictions: {
PluginRestrictionsUnknown: #PluginRestrictionsUnknown
PluginRestrictionsBuiltinsOnly: #PluginRestrictionsBuiltinsOnly
PluginRestrictionsNone: #PluginRestrictionsNone
}
#PluginRestrictionsUnknown: #PluginRestrictions & 0
// Non-builtin plugins completely disabled.
#PluginRestrictionsBuiltinsOnly: #PluginRestrictions & 1
// No restrictions, do whatever you want.
#PluginRestrictionsNone: #PluginRestrictions & 2
// BuiltinPluginLoadingOptions distinguish ways in which builtin plugins are used.
//go:generate stringer -type=BuiltinPluginLoadingOptions
#BuiltinPluginLoadingOptions: int // #enumBuiltinPluginLoadingOptions
#enumBuiltinPluginLoadingOptions:
#BploUndefined |
#BploUseStaticallyLinked |
#BploLoadFromFileSys
#values_BuiltinPluginLoadingOptions: {
BploUndefined: #BploUndefined
BploUseStaticallyLinked: #BploUseStaticallyLinked
BploLoadFromFileSys: #BploLoadFromFileSys
}
#BploUndefined: #BuiltinPluginLoadingOptions & 0
// Desired in production use for performance.
#BploUseStaticallyLinked: #BuiltinPluginLoadingOptions & 1
// Desired in testing and development cycles where it's undesirable
// to generate static code.
#BploLoadFromFileSys: #BuiltinPluginLoadingOptions & 2
// FnPluginLoadingOptions set way functions-based plugins are restricted
#FnPluginLoadingOptions: {
// Allow to run executables
EnableExec: bool
// Allow to run starlark
EnableStar: bool
// Allow container access to network
Network: bool
NetworkName: string
// list of mounts
Mounts: [...string] @go(,[]string)
// list of env variables to pass to fn
Env: [...string] @go(,[]string)
// Run as uid and gid of the command executor
AsCurrentUser: bool
// Run in this working directory
WorkingDir: string
}

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
_#_PluginRestrictions_name: "PluginRestrictionsUnknownPluginRestrictionsBuiltinsOnlyPluginRestrictionsNone"

View File

@@ -0,0 +1,57 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
#DefaultReplacementFieldPath: "metadata.name"
// Replacement defines how to perform a substitution
// where it is from and where it is to.
#Replacement: {
// The source of the value.
source?: null | #SourceSelector @go(Source,*SourceSelector)
// The N fields to write the value to.
targets?: [...null | #TargetSelector] @go(Targets,[]*TargetSelector)
}
// SourceSelector is the source of the replacement transformer.
#SourceSelector: {
// Structured field path expected in the allowed object.
fieldPath?: string @go(FieldPath)
// Used to refine the interpretation of the field.
options?: null | #FieldOptions @go(Options,*FieldOptions)
}
// TargetSelector specifies fields in one or more objects.
#TargetSelector: {
// Include objects that match this.
select?: null | #Selector @go(Select,*Selector)
// From the allowed set, remove objects that match this.
reject?: [...null | #Selector] @go(Reject,[]*Selector)
// Structured field paths expected in each allowed object.
fieldPaths?: [...string] @go(FieldPaths,[]string)
// Used to refine the interpretation of the field.
options?: null | #FieldOptions @go(Options,*FieldOptions)
}
// FieldOptions refine the interpretation of FieldPaths.
#FieldOptions: {
// Used to split/join the field.
delimiter?: string @go(Delimiter)
// Which position in the split to consider.
index?: int @go(Index)
// TODO (#3492): Implement use of this option
// None, Base64, URL, Hex, etc
encoding?: string @go(Encoding)
// If field missing, add it.
create?: bool @go(Create)
}

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
#ReplacementField: {
#Replacement
path?: string @go(Path)
}

View File

@@ -0,0 +1,17 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// Replica specifies a modification to a replica config.
// The number of replicas of a resource whose name matches will be set to count.
// This struct is used by the ReplicaCountTransform, and is meant to supplement
// the existing patch functionality with a simpler syntax for replica configuration.
#Replica: {
// The name of the resource to change the replica count
name?: string @go(Name)
// The number of replicas required.
count: int64 @go(Count)
}

View File

@@ -0,0 +1,19 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// SecretArgs contains the metadata of how to generate a secret.
#SecretArgs: {
#GeneratorArgs
// Type of the secret.
//
// This is the same field as the secret type field in v1/Secret:
// It can be "Opaque" (default), or "kubernetes.io/tls".
//
// If type is "kubernetes.io/tls", then "literals" or "files" must have exactly two
// keys: "tls.key" and "tls.crt"
type?: string @go(Type)
}

View File

@@ -0,0 +1,20 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// Selector specifies a set of resources.
// Any resource that matches intersection of all conditions
// is included in this set.
#Selector: {
// 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 @go(AnnotationSelector)
// 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 @go(LabelSelector)
}

View File

@@ -0,0 +1,36 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// SortOptions defines the order that kustomize outputs resources.
#SortOptions: {
// Order selects the ordering strategy.
order?: #SortOrder @go(Order)
// LegacySortOptions tweaks the sorting for the "legacy" sort ordering
// strategy.
legacySortOptions?: null | #LegacySortOptions @go(LegacySortOptions,*LegacySortOptions)
}
// SortOrder defines different ordering strategies.
#SortOrder: string // #enumSortOrder
#enumSortOrder:
#LegacySortOrder |
#FIFOSortOrder
#LegacySortOrder: #SortOrder & "legacy"
#FIFOSortOrder: #SortOrder & "fifo"
// LegacySortOptions define various options for tweaking the "legacy" ordering
// strategy.
#LegacySortOptions: {
// OrderFirst selects the resource kinds to order first.
orderFirst: [...string] @go(OrderFirst,[]string)
// OrderLast selects the resource kinds to order last.
orderLast: [...string] @go(OrderLast,[]string)
}

View File

@@ -0,0 +1,12 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// TypeMeta partially copies apimachinery/pkg/apis/meta/v1.TypeMeta
// No need for a direct dependence; the fields are stable.
#TypeMeta: {
kind?: string @go(Kind)
apiVersion?: string @go(APIVersion)
}

View File

@@ -0,0 +1,45 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go sigs.k8s.io/kustomize/api/types
package types
// Var represents a variable whose value will be sourced
// from a field in a Kubernetes object.
#Var: {
// Value of identifier name e.g. FOO used in container args, annotations
// Appears in pod template as $(FOO)
name: string @go(Name)
// ObjRef must refer to a Kubernetes resource under the
// purview of this kustomization. ObjRef should use the
// raw name of the object (the name specified in its YAML,
// before addition of a namePrefix and a nameSuffix).
objref: #Target @go(ObjRef)
// FieldRef refers to the field of the object referred to by
// ObjRef whose value will be extracted for use in
// replacing $(FOO).
// If unspecified, this defaults to fieldPath: $defaultFieldPath
fieldref?: #FieldSelector @go(FieldRef)
}
// Target refers to a kubernetes object by Group, Version, Kind and Name
// gvk.Gvk contains Group, Version and Kind
// APIVersion is added to keep the backward compatibility of using ObjectReference
// for Var.ObjRef
#Target: {
apiVersion?: string @go(APIVersion)
name: string @go(Name)
namespace?: string @go(Namespace)
}
// FieldSelector contains the fieldPath to an object field.
// This struct is added to keep the backward compatibility of using ObjectFieldSelector
// for Var.FieldRef
#FieldSelector: {
fieldPath?: string @go(FieldPath)
}
// byName is a sort interface which sorts Vars by name alphabetically
_#byName: [...#Var]

View File

@@ -0,0 +1,8 @@
package v1alpha1
// #BuildPlan is the API contract between CUE and the Holos cli.
// Holos requires CUE to evaluate and provide a valid #BuildPlan.
#BuildPlan: {
kind: #BuildPlanKind
apiVersion: #APIVersion
}

View File

@@ -0,0 +1 @@
package v1alpha1

View File

@@ -0,0 +1,5 @@
package v1alpha1
#HolosComponent: Skip: true | *false
#HelmChart: enableHooks: true | *false

View File

@@ -1,6 +1,6 @@
package v1
#Deployment: {
apiVersion: "apps/v1"
kind: "Deployment"
apiVersion: "apps/v1"
kind: "Deployment"
}

View File

@@ -1,11 +1,11 @@
package v1
#CronJob: {
apiVersion: "batch/v1"
kind: "CronJob"
apiVersion: "batch/v1"
kind: "CronJob"
}
#Job: {
apiVersion: "batch/v1"
kind: "Job"
apiVersion: "batch/v1"
kind: "Job"
}

View File

@@ -1,21 +1,26 @@
package v1
#Namespace: {
apiVersion: "v1"
kind: "Namespace"
apiVersion: "v1"
kind: "Namespace"
}
#ConfigMap: {
apiVersion: "v1"
kind: "ConfigMap"
apiVersion: "v1"
kind: "ConfigMap"
}
#ServiceAccount: {
apiVersion: "v1"
kind: "ServiceAccount"
apiVersion: "v1"
kind: "ServiceAccount"
}
#Pod: {
apiVersion: "v1"
kind: "Pod"
apiVersion: "v1"
kind: "Pod"
}
#Service: {
apiVersion: "v1"
kind: "Service"
}

View File

@@ -0,0 +1,15 @@
package types
#Patch: {
// Path is a relative file path to the patch file.
path?: string @go(Path)
// Patch is the content of a patch.
patch?: string @go(Patch)
// Target points to the resources that the patch is applied to
target?: #Target | #Selector @go(Target,*Selector)
// Options is a list of options for the patch
options?: {[string]: bool} @go(Options,map[string]bool)
}

View File

@@ -0,0 +1,7 @@
package types
#Target: {
group?: string @go(Group)
version?: string @go(Version)
kind?: string @go(Kind)
}

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