mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 08:44:58 +00:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7845ce62e0 | ||
|
|
a1542752b7 | ||
|
|
7956475363 | ||
|
|
004ed56591 | ||
|
|
d497df3c27 | ||
|
|
3a8d46234f | ||
|
|
4d24dc5149 | ||
|
|
8eb7fbf7dc | ||
|
|
ffeeb7c553 | ||
|
|
c3c174155c | ||
|
|
2c2d2a9fd9 | ||
|
|
d692e2a6d5 | ||
|
|
e4cebddd0c | ||
|
|
0e48537d65 | ||
|
|
a461a96b9c | ||
|
|
9524c4f7c3 | ||
|
|
64b04d9cfd | ||
|
|
b419ad8caf | ||
|
|
8036c17916 | ||
|
|
220d498be0 | ||
|
|
0f5b6a2d6e | ||
|
|
36369d75c7 | ||
|
|
059b8283fd | ||
|
|
386eb2452a | ||
|
|
38e9a97fd2 | ||
|
|
ecca40e9d5 | ||
|
|
9d08e27e31 | ||
|
|
969bf5e867 | ||
|
|
3b5f28f4df | ||
|
|
df5619f988 | ||
|
|
a6d8383176 | ||
|
|
dbc7e374cd | ||
|
|
d81729857b | ||
|
|
d3d8a7b73c | ||
|
|
d9e6776b95 | ||
|
|
bde98faffa | ||
|
|
c2847554e0 | ||
|
|
9411a65dd8 | ||
|
|
9c1165e77e | ||
|
|
a02c7a4015 | ||
|
|
bdcde88e6f | ||
|
|
a32b100192 | ||
|
|
670d716403 | ||
|
|
bba3895f35 | ||
|
|
9e60ddbe85 | ||
|
|
44334fca52 | ||
|
|
2e2ed398c6 | ||
|
|
34f2a52cb7 | ||
|
|
d3888a884f | ||
|
|
3845871368 | ||
|
|
a3b2d19adb | ||
|
|
e4e7cd8c47 | ||
|
|
fb22e5521b | ||
|
|
d2ae766ae3 | ||
|
|
c0db949729 | ||
|
|
d2d4337ffd | ||
|
|
b0ca04635e | ||
|
|
198c66e6cd | ||
|
|
24346b9a38 |
4
Makefile
4
Makefile
@@ -16,10 +16,12 @@ $( shell mkdir -p bin)
|
||||
export PATH := $(PWD)/internal/frontend/holos/node_modules/.bin:$(PATH)
|
||||
|
||||
GIT_COMMIT=$(shell git rev-parse HEAD)
|
||||
GIT_SUFFIX=$(shell test -n "`git status --porcelain`" && echo "-dirty" || echo "")
|
||||
GIT_DETAIL=$(shell git describe --tags HEAD)
|
||||
GIT_TREE_STATE=$(shell test -n "`git status --porcelain`" && echo "dirty" || echo "clean")
|
||||
BUILD_DATE=$(shell date -Iseconds)
|
||||
|
||||
LD_FLAGS="-w -X ${ORG_PATH}/${PROJ}/version.GitCommit=${GIT_COMMIT} -X ${ORG_PATH}/${PROJ}/version.GitTreeState=${GIT_TREE_STATE} -X ${ORG_PATH}/${PROJ}/version.BuildDate=${BUILD_DATE}"
|
||||
LD_FLAGS="-w -X ${ORG_PATH}/${PROJ}/version.GitDescribe=${GIT_DETAIL}${GIT_SUFFIX} -X ${ORG_PATH}/${PROJ}/version.GitCommit=${GIT_COMMIT} -X ${ORG_PATH}/${PROJ}/version.GitTreeState=${GIT_TREE_STATE} -X ${ORG_PATH}/${PROJ}/version.BuildDate=${BUILD_DATE}"
|
||||
|
||||
.PHONY: default
|
||||
default: test
|
||||
|
||||
@@ -9,14 +9,17 @@ import (
|
||||
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"`
|
||||
Platform map[string]any `json:"platform,omitempty" yaml:"platform,omitempty"`
|
||||
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"`
|
||||
// DeployFiles keys represent file paths relative to the cluster deploy
|
||||
// directory. Map values represent the string encoded file contents. Used to
|
||||
// write the argocd Application, but may be used to render any file from CUE.
|
||||
DeployFiles FileContentMap `json:"deployFiles,omitempty" yaml:"deployFiles,omitempty"`
|
||||
}
|
||||
|
||||
type BuildPlanComponents struct {
|
||||
|
||||
@@ -20,3 +20,11 @@ type HolosComponent struct {
|
||||
func (hc *HolosComponent) NewResult() *Result {
|
||||
return &Result{HolosComponent: *hc}
|
||||
}
|
||||
|
||||
func (hc *HolosComponent) GetAPIVersion() string {
|
||||
return hc.APIVersion
|
||||
}
|
||||
|
||||
func (hc *HolosComponent) GetKind() string {
|
||||
return hc.Kind
|
||||
}
|
||||
|
||||
@@ -1,9 +1,32 @@
|
||||
package v1alpha1
|
||||
|
||||
// Platform represents a platform to manage. A Platform resource tells holos
|
||||
// which components to build. The primary use case is to specify the cluster
|
||||
// names, cluster types, and holos components to build.
|
||||
import "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
// Platform represents a platform to manage. A Platform resource informs holos
|
||||
// which components to build. The platform resource also acts as a container
|
||||
// for the platform model form values provided by the PlatformService. The
|
||||
// primary use case is to collect the cluster names, cluster types, platform
|
||||
// model, and holos components to build into one resource.
|
||||
type Platform struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
Metadata ObjectMeta `json:"metadata" yaml:"metadata"`
|
||||
Spec PlatformSpec `json:"spec" yaml:"spec"`
|
||||
}
|
||||
|
||||
// PlatformSpec represents the platform build plan specification.
|
||||
type PlatformSpec struct {
|
||||
// Model represents the platform model holos gets from from the
|
||||
// holos.platform.v1alpha1.PlatformService.GetPlatform method and provides to
|
||||
// CUE using a tag.
|
||||
Model structpb.Struct `json:"model" yaml:"model"`
|
||||
Components []PlatformSpecComponent `json:"components" yaml:"components"`
|
||||
}
|
||||
|
||||
// PlatformSpecComponent represents a component to build or render with flags to
|
||||
// pass, for example the cluster name.
|
||||
type PlatformSpecComponent struct {
|
||||
// Path is the path of the component relative to the platform root.
|
||||
Path string `json:"path" yaml:"path"`
|
||||
// Cluster is the cluster name to use when building the component.
|
||||
Cluster string `json:"cluster" yaml:"cluster"`
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ type Result struct {
|
||||
HolosComponent
|
||||
// accumulatedOutput accumulates rendered api objects.
|
||||
accumulatedOutput string
|
||||
// DeployFiles keys represent file paths relative to the cluster deploy
|
||||
// directory. Map values represent the string encoded file contents. Used to
|
||||
// write the argocd Application, but may be used to render any file from CUE.
|
||||
DeployFiles FileContentMap `json:"deployFiles,omitempty" yaml:"deployFiles,omitempty"`
|
||||
}
|
||||
|
||||
// Continue returns true if Skip is true indicating the result is to be skipped over.
|
||||
@@ -133,6 +137,21 @@ func (r *Result) kustomize(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Result) WriteDeployFiles(ctx context.Context, path string) error {
|
||||
log := logger.FromContext(ctx)
|
||||
if len(r.DeployFiles) == 0 {
|
||||
return nil
|
||||
}
|
||||
for k, content := range r.DeployFiles {
|
||||
path := filepath.Join(path, k)
|
||||
if err := r.Save(ctx, path, content); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.InfoContext(ctx, "wrote deploy file", "path", path, "bytes", len(content))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save writes the content to the filesystem for git ops.
|
||||
func (r *Result) Save(ctx context.Context, path string, content string) error {
|
||||
log := logger.FromContext(ctx)
|
||||
@@ -141,7 +160,7 @@ func (r *Result) Save(ctx context.Context, path string, content string) error {
|
||||
log.WarnContext(ctx, "could not mkdir", "path", dir, "err", err)
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Write the kube api objects
|
||||
// Write the file content
|
||||
if err := os.WriteFile(path, []byte(content), os.FileMode(0644)); err != nil {
|
||||
log.WarnContext(ctx, "could not write", "path", path, "err", err)
|
||||
return errors.Wrap(err)
|
||||
|
||||
3
cmd/holos/testdata/constraints.txt
vendored
3
cmd/holos/testdata/constraints.txt
vendored
@@ -2,6 +2,8 @@
|
||||
exec holos build ./foo/... --log-level debug
|
||||
stdout '^bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b$'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- foo/constraints.cue --
|
||||
@@ -20,6 +22,7 @@ spec: components: KubernetesObjectsList: [
|
||||
package holos
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
#KubernetesObjects: {
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
|
||||
3
cmd/holos/testdata/issue15_cue_errors.txt
vendored
3
cmd/holos/testdata/issue15_cue_errors.txt
vendored
@@ -3,12 +3,15 @@
|
||||
stderr 'apiObjectMap.foo.bar: cannot convert incomplete value'
|
||||
stderr '/component.cue:\d+:\d+$'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
|
||||
@@ -3,6 +3,8 @@ exec holos build .
|
||||
stdout '^kind: SecretStore$'
|
||||
stdout '# Source: CUE apiObjects.SecretStore.default'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
@@ -13,6 +15,7 @@ kind: "BuildPlan"
|
||||
spec: components: KubernetesObjectsList: [{apiObjectMap: #APIObjects.apiObjectMap}]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
#SecretStore: {
|
||||
kind: string
|
||||
|
||||
@@ -4,6 +4,8 @@ stdout '^kind: SecretStore$'
|
||||
stdout '# Source: CUE apiObjects.SecretStore.default'
|
||||
stderr 'skipping helm: no chart name specified'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
@@ -14,6 +16,7 @@ kind: "BuildPlan"
|
||||
spec: components: HelmChartList: [{apiObjectMap: #APIObjects.apiObjectMap}]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
#SecretStore: {
|
||||
kind: string
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
! exec holos build .
|
||||
stderr 'apiObjects.secretstore.default.foo: field not allowed'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
@@ -10,6 +12,7 @@ package holos
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "KubernetesObjects"
|
||||
cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
#SecretStore: {
|
||||
metadata: name: string
|
||||
|
||||
3
cmd/holos/testdata/issue33_helm_stderr.txt
vendored
3
cmd/holos/testdata/issue33_helm_stderr.txt
vendored
@@ -2,6 +2,8 @@
|
||||
! 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'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- zitadel.cue --
|
||||
@@ -12,6 +14,7 @@ kind: "BuildPlan"
|
||||
spec: components: HelmChartList: [_HelmChart]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
_HelmChart: {
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
# Kustomize is a supported holos component kind
|
||||
exec holos render --cluster-name=mycluster . --log-level=debug
|
||||
exec holos render component --cluster-name=mycluster . --log-level=debug
|
||||
|
||||
# Want generated output
|
||||
cmp want.yaml deploy/clusters/mycluster/components/kstest/kstest.gen.yaml
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
! exec holos build .
|
||||
stderr 'unknown field \\"TypoKubernetesObjectsList\\"'
|
||||
|
||||
-- platform.config.json --
|
||||
{}
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
_cluster: string @tag(cluster, string)
|
||||
_platform_config: string @tag(platform_config, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
|
||||
2
cmd/holos/testdata/version.txt
vendored
2
cmd/holos/testdata/version.txt
vendored
@@ -1,5 +1,3 @@
|
||||
exec holos --version
|
||||
# want version with no v on stdout
|
||||
stdout -count=1 '^\d+\.\d+\.\d+$'
|
||||
# want nothing on stderr
|
||||
! stderr .
|
||||
|
||||
3
docs/examples/platform.config.cue
Normal file
3
docs/examples/platform.config.cue
Normal file
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
_platform_config: string @tag(platform_config, type=string)
|
||||
1
docs/examples/platform.config.json
Normal file
1
docs/examples/platform.config.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -34,7 +34,7 @@ let OBJECTS = #APIObjects & {
|
||||
containers: [
|
||||
{
|
||||
name: Holos
|
||||
image: "271053619184.dkr.ecr.us-east-2.amazonaws.com/holos-run/holos-server/holos:v0.76.0"
|
||||
image: "271053619184.dkr.ecr.us-east-2.amazonaws.com/holos-run/holos-server/holos:v0.79.0"
|
||||
imagePullPolicy: "Always"
|
||||
env: [
|
||||
{
|
||||
|
||||
14
docs/runbooks/argocd.md
Normal file
14
docs/runbooks/argocd.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# ArgoCD
|
||||
|
||||
Create the deploy key secret in the management cluster.
|
||||
|
||||
```bash
|
||||
tmp="$(mktemp -d)"
|
||||
(cd $tmp && ssh-keygen -t ed25519 -f sshPrivateKey -m pem -C argocd -N '')
|
||||
echo git@github.com:holos-run/holos-infra.git > "${tmp}/url"
|
||||
holos create secret -n argocd --append-hash=false creds-holos-infra --from-file $tmp
|
||||
rm -rf "$tmp"
|
||||
```
|
||||
|
||||
When syncing the secret, the ExternalSecret needs to set the label
|
||||
`argocd.argoproj.io/secret-type: repo-creds`.
|
||||
97
docs/runbooks/login/backups.md
Normal file
97
docs/runbooks/login/backups.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# PostgresCluster Backups
|
||||
|
||||
This document describes how the S3 bucket for `PostgresCluster` backups is configured. These buckets are configured both for ZITADEL and for Holos
|
||||
Server and are applicable to any service in Holos that stores data in a pgo `PostgresCluster` resource.
|
||||
|
||||
## Create the Bucket
|
||||
Name: `holos-zitadel-backups` for `zitadel`
|
||||
Name: `holos-server-backups` for `holos server`
|
||||
> [!NOTE]
|
||||
> The settings below match the default settings recommended by AWS.
|
||||
|
||||
Object Ownership: `ACLs disabled` (recommended) Checked.
|
||||
Block Public Access settings for this bucket: **`Block all public access`** Checked.
|
||||
Bucket Versioning: `Disable`
|
||||
Default encryption: `Server-side encryption with Amazon S3 managed keys (SSE-S3)`
|
||||
Bucket Key: `Enable`
|
||||
Object Lock: `Disable`
|
||||
|
||||
## Create an IAM Policy
|
||||
Create one IAM Policy for each bucket to grant full access to the bucket. Replace the resource with each bucket name.
|
||||
Name: `holos-zitadel-backups` for `zitadel`
|
||||
Name: `holos-server-backups` for `holos server`
|
||||
Description: `Read and write access to a specific bucket for pgrest operating within a pgo PostgresCluster.`
|
||||
|
||||
Policy JSON:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"s3:GetBucketLocation",
|
||||
"s3:ListAllMyBuckets"
|
||||
],
|
||||
"Resource": "arn:aws:s3:::*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:*",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::holos-zitadel-backups",
|
||||
"arn:aws:s3:::holos-zitadel-backups/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
## Create an IAM Group
|
||||
Create an IAM Group to attach the policy granting access to the bucket.
|
||||
Name: `holos-zitadel-backups` for `zitadel`
|
||||
Attach permission policies: `holos-zitadel-backups`
|
||||
|
||||
Name: `holos-server-backups` for `holos server`
|
||||
Attach permission policies: `holos-server-backups`
|
||||
## Create the IAM User
|
||||
Create an IAM User entity for each PostgresCluster. Do not provide user access to the AWS Management Console.
|
||||
Name: `holos-zitadel-backups` for `zitadel`
|
||||
Group: `holos-zitadel-backups`
|
||||
|
||||
Name: `holos-server-backups` for `holos server`
|
||||
Group: `holos-server-backups`
|
||||
|
||||
## Create an Access Key
|
||||
Create an access key for `pgbackrest` associated with the `PostgresCluster`.
|
||||
|
||||
Description:
|
||||
> Used by pgbackrest associated with the PostgresCluster resource. Refer to the PostgresCluster resource pgbackrest.cofiguration.secret.name for the stored location of the access key. Synced from the Management Cluster using an ExternalSecret.
|
||||
## Create the Secret
|
||||
Create a `Secret` in the holos management cluster usable by pgbackrest. This is a secret with a single key, `s3.conf` with the following format:
|
||||
```
|
||||
[global]
|
||||
repo2-cipher-pass=
|
||||
repo2-s3-key=
|
||||
repo2-s3-key-secret=
|
||||
repo3-cipher-pass=
|
||||
repo3-s3-key=
|
||||
repo3-s3-key-secret=
|
||||
```
|
||||
> [!NOTE]
|
||||
> Use the same values for repo2 and repo3. The purpose is to make space for migrating if need be in the future.
|
||||
|
||||
Generate the cipher pass using. This password is used to encrypt all backups using client side before the backup is written to the bucket.
|
||||
```
|
||||
tr -dc A-Za-z0-9 </dev/urandom | head -c 64
|
||||
```
|
||||
|
||||
Store the secret into the management cluster:
|
||||
```
|
||||
holos create secret --namespace zitadel holos-zitadel-backups \
|
||||
--append-hash=false --from-file .
|
||||
```
|
||||
|
||||
```
|
||||
holos create secret --namespace holos holos-server-backups \
|
||||
--append-hash=false --from-file .
|
||||
```
|
||||
25
docs/runbooks/namespace.md
Normal file
25
docs/runbooks/namespace.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Namespaces
|
||||
|
||||
Holos follows the [Namespace Sameness - Sig Multicluster Position][1]. A
|
||||
namespace is the same on all clusters within the scope of a platform.
|
||||
|
||||
Namespaces are also security boundaries for role based access control. As such,
|
||||
permission to read a secret in a namespace means the secret is readable on all
|
||||
clusters in the platform.
|
||||
|
||||
When adding a component to a platform, create a namespace using the following
|
||||
process. This ensures a namespace scoped `SecretStore` is created to sync
|
||||
`ExternalSecret` resources from the management cluster.
|
||||
|
||||
1. Add a new project to the `_Projects` struct in `platform.cue`.
|
||||
2. Add the namespace to the `spec.namespaces` field of the project.
|
||||
3. Render the platform
|
||||
4. Apply the `namespaces` component to the management cluster
|
||||
5. Apply the `eso-creds-manager` component to the management cluster to create the `eso-reader` ksa for the namespace `SecretStore`
|
||||
6. Apply the `namespaces` component to the workload clusters
|
||||
7. On the workload cluster, run the job to fetch the eso-reader creds: `kubectl create job -n holos-system --from=cronjob/eso-creds-refresher eso-creds-refresher-$(date +%s)`
|
||||
8. Apply the secretstores component to the workload cluster.
|
||||
|
||||
Your namespace is created and you have the ability to create secrets in the management cluster and pull them using ExternalSecret resources. (edited)
|
||||
|
||||
[1]: https://github.com/kubernetes/community/blob/dd4c8b704ef1c9c3bfd928c6fa9234276d61ad18/sig-multicluster/namespace-sameness-position-statement.md
|
||||
31
docs/runbooks/workload-identity.md
Normal file
31
docs/runbooks/workload-identity.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Workload Identity
|
||||
|
||||
When a new workload cluster is provisioned, allow it to access the Management
|
||||
Cluster using workload identity. This is necessary for the
|
||||
`eso-creds-refresher` component and `Job` that executes in each workload
|
||||
cluster, which in turn enables the `SecretStore` in each namespace to sync
|
||||
secrets.
|
||||
|
||||
Build the cluster with Cluster API.
|
||||
See https://github.com/holos-run/holos-infra/blob/main/hack/capi/eks/aws2/aws2-managedmachinepool.yaml#L81-L84
|
||||
|
||||
## Workload Identity Provider
|
||||
Add the Cluster as a workload identity provider to the `holos-ops` gcp project.
|
||||
|
||||
Pool: [holos](https://console.cloud.google.com/iam-admin/workload-identity-pools/pool/holos?organizationId=358674006047&project=holos-ops)
|
||||
Name: `k8s-aws1`, `k8s-aws2`, etc...
|
||||
### Issuer URL:
|
||||
```
|
||||
kubectl create -n default token default | cut -d. -f2 | base64 -d | jq -r .iss
|
||||
```
|
||||
|
||||
### Audience
|
||||
Use the default audience.
|
||||
### Attribute Mapping
|
||||
|
||||
| Google | OIDC |
|
||||
| -------------------------------- | ------------------------------------------------------ |
|
||||
| `google.subject` | `assertion.sub` |
|
||||
| `attribute.service_account_name` | `assertion['kubernetes.io']['serviceaccount']['name']` |
|
||||
| `attribute.uid` | `assertion['kubernetes.io']['serviceaccount']['uid']` |
|
||||
| `attribute.pod` | `assertion['kubernetes.io']['pod']['name']` |
|
||||
4
go.mod
4
go.mod
@@ -16,7 +16,6 @@ require (
|
||||
github.com/fullstorydev/grpcurl v1.9.1
|
||||
github.com/go-jose/go-jose/v3 v3.0.3
|
||||
github.com/gofrs/uuid v4.4.0+incompatible
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/int128/kubelogin v1.28.0
|
||||
github.com/jackc/pgx/v5 v5.5.5
|
||||
github.com/lmittmann/tint v1.0.4
|
||||
@@ -87,7 +86,7 @@ require (
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/cli v26.0.0+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker v26.0.0+incompatible // indirect
|
||||
github.com/docker/docker v26.0.2+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.8.1 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
@@ -115,6 +114,7 @@ require (
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.0.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -187,8 +187,8 @@ github.com/docker/cli v26.0.0+incompatible h1:90BKrx1a1HKYpSnnBFR6AgDq/FqkHxwlUy
|
||||
github.com/docker/cli v26.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v26.0.0+incompatible h1:Ng2qi+gdKADUa/VM+6b6YaY2nlZhk/lVJiKR/2bMudU=
|
||||
github.com/docker/docker v26.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v26.0.2+incompatible h1:yGVmKUFGgcxA6PXWAokO0sQL22BrQ67cgVjko8tGdXE=
|
||||
github.com/docker/docker v26.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
|
||||
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"cuelang.org/go/cue/build"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
"github.com/holos-run/holos"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
)
|
||||
@@ -70,7 +72,7 @@ func (b *Builder) Cluster() string {
|
||||
}
|
||||
|
||||
// Instances returns the cue build instances being built.
|
||||
func (b *Builder) Instances(ctx context.Context) ([]*build.Instance, error) {
|
||||
func (b *Builder) Instances(ctx context.Context, cfg *client.Config) ([]*build.Instance, error) {
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
mod, err := b.findCueMod()
|
||||
@@ -79,7 +81,29 @@ func (b *Builder) Instances(ctx context.Context) ([]*build.Instance, error) {
|
||||
}
|
||||
dir := string(mod)
|
||||
|
||||
cfg := load.Config{Dir: dir}
|
||||
cueConfig := load.Config{Dir: dir}
|
||||
|
||||
// Get the platform model from the PlatformConfig
|
||||
pc, err := client.LoadPlatformConfig(ctx, dir)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
data, err := json.Marshal(pc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
|
||||
cueConfig.Tags = append(cueConfig.Tags, "platform_config="+string(data))
|
||||
if b.Cluster() != "" {
|
||||
cueConfig.Tags = append(cueConfig.Tags, "cluster="+b.Cluster())
|
||||
}
|
||||
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cueConfig.Tags))
|
||||
|
||||
prefix := []string{"cue", "export", "--out", "yaml"}
|
||||
for _, tag := range cueConfig.Tags {
|
||||
prefix = append(prefix, "-t", fmt.Sprintf("'%s'", tag))
|
||||
}
|
||||
|
||||
// Make args relative to the module directory
|
||||
args := make([]string, len(b.cfg.args))
|
||||
@@ -94,21 +118,20 @@ func (b *Builder) Instances(ctx context.Context) ([]*build.Instance, error) {
|
||||
}
|
||||
relPath = "./" + relPath
|
||||
args[idx] = relPath
|
||||
equiv := fmt.Sprintf("cue export --out yaml -t cluster=%v %v", b.Cluster(), relPath)
|
||||
log.Debug("cue: equivalent command: " + equiv)
|
||||
|
||||
equiv := make([]string, len(prefix), 1+len(prefix))
|
||||
copy(equiv, prefix)
|
||||
equiv = append(equiv, relPath)
|
||||
log.Debug(strings.Join(equiv, " "), "comment", "cue equivalent command")
|
||||
}
|
||||
|
||||
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
|
||||
cfg.Tags = append(cfg.Tags, "cluster="+b.Cluster())
|
||||
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cfg.Tags))
|
||||
|
||||
return load.Instances(args, &cfg), nil
|
||||
return load.Instances(args, &cueConfig), nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context) (results []*v1alpha1.Result, err error) {
|
||||
func (b *Builder) Run(ctx context.Context, cfg *client.Config) (results []*v1alpha1.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "cue: building instances")
|
||||
instances, err := b.Instances(ctx)
|
||||
instances, err := b.Instances(ctx, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -161,9 +184,14 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
|
||||
|
||||
// New decoder for the full object
|
||||
decoder = json.NewDecoder(bytes.NewReader(jsonBytes))
|
||||
|
||||
// TODO: When we release v1, explicitly allow unknown fields so we can add
|
||||
// fields without needing to bump the major version. Disallow until we reach
|
||||
// v1 for clear error reporting.
|
||||
decoder.DisallowUnknownFields()
|
||||
|
||||
switch tm.Kind {
|
||||
// TODO(jeff) Process a v1alpha1.Result here, the result is tightly coupled to a BuildPlan.
|
||||
case "BuildPlan":
|
||||
var bp v1alpha1.BuildPlan
|
||||
if err = decoder.Decode(&bp); err != nil {
|
||||
@@ -171,24 +199,14 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
|
||||
return
|
||||
}
|
||||
results, err = b.buildPlan(ctx, &bp, path)
|
||||
case "Platform":
|
||||
var pf v1alpha1.Platform
|
||||
if err = decoder.Decode(&pf); err != nil {
|
||||
err = errors.Wrap(fmt.Errorf("could not decode Platform %s: %w", instance.Dir, err))
|
||||
return
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
results, err = b.buildPlatform(ctx, &pf)
|
||||
default:
|
||||
err = errors.Wrap(fmt.Errorf("unknown kind: %v", tm.Kind))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (b *Builder) buildPlatform(ctx context.Context, pf *v1alpha1.Platform) (results []*v1alpha1.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.ErrorContext(ctx, "not implemented", "platform", pf)
|
||||
return nil, errors.Wrap(fmt.Errorf("not implemeneted"))
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha1.BuildPlan, path holos.InstancePath) (results []*v1alpha1.Result, err error) {
|
||||
@@ -237,6 +255,17 @@ func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha1.BuildPlan,
|
||||
}
|
||||
}
|
||||
|
||||
// Add a separate Result if there are DeployFiles from the BuildPlan.
|
||||
if len(buildPlan.Spec.DeployFiles) > 0 {
|
||||
results = append(results, &v1alpha1.Result{
|
||||
HolosComponent: v1alpha1.HolosComponent{
|
||||
TypeMeta: buildPlan.TypeMeta,
|
||||
Metadata: buildPlan.Metadata,
|
||||
},
|
||||
DeployFiles: buildPlan.Spec.DeployFiles,
|
||||
})
|
||||
}
|
||||
|
||||
log.DebugContext(ctx, "returning results", "len", len(results))
|
||||
|
||||
return results, nil
|
||||
|
||||
90
internal/builder/platform.go
Normal file
90
internal/builder/platform.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"cuelang.org/go/cue/build"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"github.com/holos-run/holos"
|
||||
"github.com/holos-run/holos/api/v1alpha1"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
)
|
||||
|
||||
// Platform builds a platform
|
||||
func (b *Builder) Platform(ctx context.Context, cfg *client.Config) (*v1alpha1.Platform, error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "cue: building platform instance")
|
||||
instances, err := b.Instances(ctx, cfg)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
if len(instances) != 1 {
|
||||
return nil, errors.Wrap(errors.New(fmt.Sprintf("instances length %d must be exactly 1", len(instances))))
|
||||
}
|
||||
|
||||
// We only process the first instance, assume the render platform subcommand enforces this.
|
||||
instance := instances[0]
|
||||
log.DebugContext(ctx, "cue: building instance", "dir", instance.Dir)
|
||||
p, err := b.runPlatform(ctx, instance)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not build platform: %w", err))
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*v1alpha1.Platform, error) {
|
||||
path := holos.InstancePath(instance.Dir)
|
||||
log := logger.FromContext(ctx).With("dir", path)
|
||||
|
||||
if err := instance.Err; err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not load: %w", err))
|
||||
}
|
||||
cueCtx := cuecontext.New()
|
||||
value := cueCtx.BuildInstance(instance)
|
||||
if err := value.Err(); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not build %s: %w", instance.Dir, err))
|
||||
}
|
||||
log.DebugContext(ctx, "cue: validating instance")
|
||||
if err := value.Validate(); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not validate: %w", err))
|
||||
}
|
||||
|
||||
log.DebugContext(ctx, "cue: decoding holos platform")
|
||||
jsonBytes, err := value.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not marshal cue instance %s: %w", instance.Dir, err))
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(jsonBytes))
|
||||
// Discriminate the type of build plan.
|
||||
tm := &v1alpha1.TypeMeta{}
|
||||
err = decoder.Decode(tm)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("invalid platform: %s: %w", instance.Dir, err))
|
||||
}
|
||||
|
||||
log.DebugContext(ctx, "cue: discriminated build kind: "+tm.Kind, "kind", tm.Kind, "apiVersion", tm.APIVersion)
|
||||
|
||||
// New decoder for the full object
|
||||
decoder = json.NewDecoder(bytes.NewReader(jsonBytes))
|
||||
decoder.DisallowUnknownFields()
|
||||
|
||||
var pf v1alpha1.Platform
|
||||
switch tm.Kind {
|
||||
case "Platform":
|
||||
if err = decoder.Decode(&pf); err != nil {
|
||||
err = errors.Wrap(fmt.Errorf("could not decode platform %s: %w", instance.Dir, err))
|
||||
return nil, err
|
||||
}
|
||||
return &pf, nil
|
||||
default:
|
||||
err = errors.Wrap(fmt.Errorf("unknown kind: %v", tm.Kind))
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
@@ -7,16 +7,20 @@ import (
|
||||
|
||||
"github.com/holos-run/holos/internal/builder"
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// makeBuildRunFunc returns the internal implementation of the build cli command
|
||||
func makeBuildRunFunc(cfg *holos.Config) command.RunFunc {
|
||||
func makeBuildRunFunc(cfg *client.Config) command.RunFunc {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
|
||||
results, err := build.Run(cmd.Context())
|
||||
ctx := cmd.Root().Context()
|
||||
logger.FromContext(ctx).DebugContext(ctx, "RunE", "args", args)
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.Holos().ClusterName()))
|
||||
results, err := build.Run(ctx, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -42,7 +46,12 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("build [directory...]")
|
||||
cmd.Args = cobra.MinimumNArgs(1)
|
||||
cmd.Short = "build kubernetes api objects from a directory"
|
||||
cmd.RunE = makeBuildRunFunc(cfg)
|
||||
|
||||
cmd.Flags().AddGoFlagSet(cfg.ClusterFlagSet())
|
||||
config := client.NewConfig(cfg)
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
cmd.RunE = makeBuildRunFunc(config)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/version"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -20,9 +17,6 @@ func New(name string) *cobra.Command {
|
||||
CompletionOptions: cobra.CompletionOptions{
|
||||
HiddenDefaultCmd: true,
|
||||
},
|
||||
RunE: func(c *cobra.Command, args []string) error {
|
||||
return errors.Wrap(fmt.Errorf("could not run %v: not implemented", c.Name()))
|
||||
},
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
}
|
||||
|
||||
@@ -3,21 +3,52 @@ package create
|
||||
import (
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/cli/secret"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// New returns the create command for the cli
|
||||
func New(hc *holos.Config) *cobra.Command {
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("create")
|
||||
cmd.Short = "create resources"
|
||||
cmd.Flags().SortFlags = false
|
||||
cmd.RunE = func(c *cobra.Command, args []string) error {
|
||||
return c.Usage()
|
||||
}
|
||||
|
||||
// api client config
|
||||
config := client.NewConfig(cfg)
|
||||
|
||||
// flags
|
||||
cmd.PersistentFlags().SortFlags = false
|
||||
// commands
|
||||
cmd.AddCommand(secret.NewCreateCmd(hc))
|
||||
cmd.AddCommand(secret.NewCreateCmd(cfg))
|
||||
cmd.AddCommand(NewPlatform(config))
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewPlatform(cfg *client.Config) *cobra.Command {
|
||||
cmd := command.New("platform")
|
||||
|
||||
cmd.Short = "create a platform"
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
pm := client.PlatformMutation{}
|
||||
cmd.Flags().AddGoFlagSet(pm.FlagSet())
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
client := client.New(cfg)
|
||||
pf, err := client.CreatePlatform(ctx, pm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log := logger.FromContext(ctx)
|
||||
log.InfoContext(ctx, "created platform", "name", pf.GetName(), "id", pf.GetId(), "org", pf.GetOwner().GetOrgId())
|
||||
return nil
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
@@ -20,6 +22,7 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
cmd.AddCommand(NewPlatform(cfg))
|
||||
cmd.AddCommand(NewComponent())
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -40,6 +43,62 @@ func NewPlatform(cfg *holos.Config) *cobra.Command {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewComponent returns a command to generate a holos component
|
||||
func NewComponent() *cobra.Command {
|
||||
cmd := command.New("component")
|
||||
cmd.Short = "generate a component from an embedded schematic"
|
||||
|
||||
cmd.AddCommand(NewCueComponent())
|
||||
cmd.AddCommand(NewHelmComponent())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewHelmComponent() *cobra.Command {
|
||||
cmd := command.New("helm")
|
||||
cmd.Short = "generate a helm component from a schematic"
|
||||
|
||||
for _, name := range generate.HelmComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("helm", name))
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCueComponent() *cobra.Command {
|
||||
cmd := command.New("cue")
|
||||
cmd.Short = "generate a cue component from a schematic"
|
||||
|
||||
for _, name := range generate.CueComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("cue", name))
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func makeSchematicCommand(kind, name string) *cobra.Command {
|
||||
cmd := command.New(name)
|
||||
cfg, err := generate.NewSchematic(filepath.Join("components", kind), name)
|
||||
if err != nil {
|
||||
slog.Error("could not get schematic", "err", err)
|
||||
return nil
|
||||
}
|
||||
cmd.Short = cfg.Short
|
||||
cmd.Long = cfg.Long
|
||||
cmd.Args = cobra.NoArgs
|
||||
cmd.Flags().AddGoFlagSet(cfg.FlagSet())
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
if err := generate.GenerateComponent(ctx, kind, name, cfg); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
81
internal/cli/pull/pull.go
Normal file
81
internal/cli/pull/pull.go
Normal file
@@ -0,0 +1,81 @@
|
||||
// Package pull pulls resources from the PlatformService and caches them in the
|
||||
// local filesystem.
|
||||
package pull
|
||||
|
||||
import (
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
object "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("pull")
|
||||
cmd.Short = "pull resources from holos server"
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
config := client.NewConfig(cfg)
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
cmd.AddCommand(NewPlatform(config))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewPlatform(cfg *client.Config) *cobra.Command {
|
||||
cmd := command.New("platform")
|
||||
|
||||
cmd.Short = "pull platform resources"
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
cmd.AddCommand(NewPlatformConfig(cfg))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewPlatformConfig(cfg *client.Config) *cobra.Command {
|
||||
cmd := command.New("config")
|
||||
cmd.Short = "pull platform config"
|
||||
cmd.Args = cobra.MinimumNArgs(1)
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
if ctx == nil {
|
||||
return errors.Wrap(errors.New("cannot execute: no context"))
|
||||
}
|
||||
ctx = logger.NewContext(ctx, logger.FromContext(ctx).With("server", cfg.Client().Server()))
|
||||
rpc := client.New(cfg)
|
||||
for _, name := range args {
|
||||
// Get the platform metadata for the platform id.
|
||||
pmd, err := client.LoadPlatform(ctx, name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log := logger.FromContext(ctx).With("platform_id", pmd.GetId())
|
||||
// Get the platform model
|
||||
model, err := rpc.PlatformModel(ctx, pmd.GetId())
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.Info("pulled platform model")
|
||||
// Build the PlatformConfig
|
||||
pc := &object.PlatformConfig{
|
||||
PlatformId: pmd.GetId(),
|
||||
PlatformModel: model,
|
||||
}
|
||||
// Save the PlatformConfig
|
||||
path, err := client.SavePlatformConfig(ctx, name, pc)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.Info("saved platform config", "path", path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -2,11 +2,15 @@
|
||||
package push
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/push"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -46,10 +50,11 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
|
||||
if ctx == nil {
|
||||
return errors.Wrap(errors.New("cannot execute: no context"))
|
||||
}
|
||||
ctx = logger.NewContext(ctx, logger.FromContext(ctx).With("server", cfg.Client().Server()))
|
||||
rpc := client.New(cfg)
|
||||
for _, name := range args {
|
||||
// Get the platform metadata for the platform id.
|
||||
p, err := push.LoadPlatform(ctx, name)
|
||||
p, err := client.LoadPlatform(ctx, name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
@@ -62,6 +67,7 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
|
||||
if err := rpc.UpdateForm(ctx, p.GetId(), form); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
slog.Default().InfoContext(ctx, fmt.Sprintf("pushed: %s/ui/platform/%s", cfg.Client().Server(), p.GetId()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,37 +7,46 @@ import (
|
||||
|
||||
"github.com/holos-run/holos/internal/builder"
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/holos-run/holos/internal/render"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// New returns the render subcommand for the root command
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("render [directory...]")
|
||||
cmd := command.New("render")
|
||||
cmd.Args = cobra.NoArgs
|
||||
cmd.Short = "render platform configuration"
|
||||
cmd.AddCommand(NewComponent(cfg))
|
||||
cmd.AddCommand(NewPlatform(cfg))
|
||||
return cmd
|
||||
}
|
||||
|
||||
// New returns the component subcommand for the render command
|
||||
func NewComponent(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("component [directory...]")
|
||||
cmd.Args = cobra.MinimumNArgs(1)
|
||||
cmd.Short = "write kubernetes api objects to the filesystem"
|
||||
cmd.Flags().SortFlags = false
|
||||
cmd.Flags().AddGoFlagSet(cfg.WriteFlagSet())
|
||||
cmd.Flags().AddGoFlagSet(cfg.ClusterFlagSet())
|
||||
|
||||
config := client.NewConfig(cfg)
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
var printInstances bool
|
||||
flagSet := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
flagSet.BoolVar(&printInstances, "print-instances", false, "expand /... paths for xargs")
|
||||
cmd.Flags().AddGoFlagSet(flagSet)
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
if cfg.ClusterName() == "" {
|
||||
return errors.Wrap(fmt.Errorf("missing cluster name"))
|
||||
}
|
||||
|
||||
ctx := cmd.Context()
|
||||
log := logger.FromContext(ctx).With("cluster", cfg.ClusterName())
|
||||
ctx := cmd.Root().Context()
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
|
||||
|
||||
if printInstances {
|
||||
instances, err := build.Instances(ctx)
|
||||
instances, err := build.Instances(ctx, config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
@@ -47,35 +56,78 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
return nil
|
||||
}
|
||||
|
||||
results, err := build.Run(cmd.Context())
|
||||
results, err := build.Run(ctx, config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// TODO: Avoid accidental over-writes if to holos component instances result in
|
||||
// the same file path. Write files into a blank temporary directory, error if a
|
||||
// file exists, then move the directory into place.
|
||||
// TODO: Avoid accidental over-writes if two or more holos component
|
||||
// instances result in the same file path. Write files into a blank
|
||||
// temporary directory, error if a file exists, then move the directory into
|
||||
// place.
|
||||
var result Result
|
||||
for _, result = range results {
|
||||
log := logger.FromContext(ctx).With(
|
||||
"cluster", cfg.ClusterName(),
|
||||
"name", result.Name(),
|
||||
)
|
||||
if result.Continue() {
|
||||
continue
|
||||
}
|
||||
// DeployFiles from the BuildPlan
|
||||
if err := result.WriteDeployFiles(ctx, cfg.WriteTo()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Build plans don't have anything but DeployFiles to write.
|
||||
if result.GetKind() == "BuildPlan" {
|
||||
continue
|
||||
}
|
||||
|
||||
// API Objects
|
||||
path := result.Filename(cfg.WriteTo(), cfg.ClusterName())
|
||||
if err := result.Save(ctx, path, result.AccumulatedOutput()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Kustomization
|
||||
path = result.KustomizationFilename(cfg.WriteTo(), cfg.ClusterName())
|
||||
if err := result.Save(ctx, path, result.KustomizationContent()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
if result.KustomizationContent() == "" {
|
||||
log.DebugContext(ctx, "flux kustomization: skipped "+result.Name(), "status", "ok", "action", "skipped")
|
||||
} else {
|
||||
path = result.KustomizationFilename(cfg.WriteTo(), cfg.ClusterName())
|
||||
if err := result.Save(ctx, path, result.KustomizationContent()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
}
|
||||
log.InfoContext(ctx, "rendered "+result.Name(), "status", "ok", "action", "rendered", "name", result.Name())
|
||||
|
||||
log.InfoContext(ctx, "rendered "+result.Name(), "status", "ok", "action", "rendered")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewPlatform(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("platform [directory]")
|
||||
cmd.Args = cobra.ExactArgs(1)
|
||||
cmd.Short = "render all platform components"
|
||||
|
||||
config := client.NewConfig(cfg)
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
build := builder.New(builder.Entrypoints(args))
|
||||
|
||||
platform, err := build.Platform(ctx, config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
return render.Platform(ctx, platform, cmd.ErrOrStderr())
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
type Result interface {
|
||||
Continue() bool
|
||||
Name() string
|
||||
@@ -84,4 +136,7 @@ type Result interface {
|
||||
Save(ctx context.Context, path string, content string) error
|
||||
AccumulatedOutput() string
|
||||
KustomizationContent() string
|
||||
WriteDeployFiles(ctx context.Context, writeTo string) error
|
||||
GetKind() string
|
||||
GetAPIVersion() string
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/holos-run/holos/internal/cli/login"
|
||||
"github.com/holos-run/holos/internal/cli/logout"
|
||||
"github.com/holos-run/holos/internal/cli/preflight"
|
||||
"github.com/holos-run/holos/internal/cli/pull"
|
||||
"github.com/holos-run/holos/internal/cli/push"
|
||||
"github.com/holos-run/holos/internal/cli/register"
|
||||
"github.com/holos-run/holos/internal/cli/render"
|
||||
@@ -35,7 +36,7 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "holos",
|
||||
Short: "holos manages a holistic integrated software development platform",
|
||||
Version: version.Version,
|
||||
Version: version.GetVersion(),
|
||||
Args: cobra.NoArgs,
|
||||
CompletionOptions: cobra.CompletionOptions{
|
||||
HiddenDefaultCmd: true, // Don't complete the complete subcommand itself
|
||||
@@ -73,6 +74,7 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
rootCmd.AddCommand(rpc.New(cfg))
|
||||
rootCmd.AddCommand(generate.New(cfg))
|
||||
rootCmd.AddCommand(register.New(cfg))
|
||||
rootCmd.AddCommand(pull.New(cfg))
|
||||
rootCmd.AddCommand(push.New(cfg))
|
||||
rootCmd.AddCommand(newOrgCmd())
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Want no hash appended
|
||||
holos create secret test --namespace holos-system --from-file $WORK/test --append-hash=false
|
||||
stderr ' created: test '
|
||||
stderr ' secret=test '
|
||||
|
||||
-- test --
|
||||
sekret
|
||||
@@ -3,6 +3,7 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"time"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
@@ -15,8 +16,29 @@ import (
|
||||
"github.com/holos-run/holos/service/gen/holos/platform/v1alpha1/platformconnect"
|
||||
"github.com/holos-run/holos/service/gen/holos/user/v1alpha1/userconnect"
|
||||
"google.golang.org/protobuf/types/known/fieldmaskpb"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
type PlatformMutation struct {
|
||||
Name string
|
||||
DisplayName string
|
||||
flagSet *flag.FlagSet
|
||||
}
|
||||
|
||||
func (pm *PlatformMutation) FlagSet() *flag.FlagSet {
|
||||
if pm == nil {
|
||||
return nil
|
||||
}
|
||||
if pm.flagSet != nil {
|
||||
return pm.flagSet
|
||||
}
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fs.StringVar(&pm.Name, "name", "example", "platform name")
|
||||
fs.StringVar(&pm.DisplayName, "display-name", "Example Platform", "platform display name")
|
||||
pm.flagSet = fs
|
||||
return fs
|
||||
}
|
||||
|
||||
func New(cfg *Config) *Client {
|
||||
t := token.NewClient(cfg.Token())
|
||||
s := cfg.Client().Server()
|
||||
@@ -56,7 +78,8 @@ func (c *Client) Platforms(ctx context.Context, orgID string) ([]*platform.Platf
|
||||
func (c *Client) UpdateForm(ctx context.Context, platformID string, form *object.Form) error {
|
||||
start := time.Now()
|
||||
req := &platform.UpdatePlatformRequest{
|
||||
Update: &platform.UpdatePlatformOperation{PlatformId: platformID, Form: form},
|
||||
PlatformId: platformID,
|
||||
Update: &platform.PlatformMutation{Form: form},
|
||||
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"form"}},
|
||||
}
|
||||
_, err := c.pltSvc.UpdatePlatform(ctx, connect.NewRequest(req))
|
||||
@@ -64,6 +87,41 @@ func (c *Client) UpdateForm(ctx context.Context, platformID string, form *object
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log := logger.FromContext(ctx)
|
||||
log.InfoContext(ctx, "updated platform", "platform_id", platformID, "duration", time.Since(start))
|
||||
log.DebugContext(ctx, "updated platform", "platform_id", platformID, "duration", time.Since(start))
|
||||
return nil
|
||||
}
|
||||
|
||||
// PlatformModel gets the platform model from the PlatformService.
|
||||
func (c *Client) PlatformModel(ctx context.Context, platformID string) (*structpb.Struct, error) {
|
||||
start := time.Now()
|
||||
req := &platform.GetPlatformRequest{
|
||||
PlatformId: platformID,
|
||||
FieldMask: &fieldmaskpb.FieldMask{Paths: []string{"spec.model"}},
|
||||
}
|
||||
pf, err := c.pltSvc.GetPlatform(ctx, connect.NewRequest(req))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "get platform", "platform_id", platformID, "duration", time.Since(start))
|
||||
return pf.Msg.GetPlatform().GetSpec().GetModel(), nil
|
||||
}
|
||||
|
||||
func (c *Client) CreatePlatform(ctx context.Context, pm PlatformMutation) (*platform.Platform, error) {
|
||||
log := logger.FromContext(ctx).With("platform", pm.Name)
|
||||
start := time.Now()
|
||||
req := &platform.CreatePlatformRequest{
|
||||
OrgId: c.cfg.context.OrgID,
|
||||
Create: &platform.PlatformMutation{
|
||||
Name: &pm.Name,
|
||||
DisplayName: &pm.DisplayName,
|
||||
},
|
||||
}
|
||||
pf, err := c.pltSvc.CreatePlatform(ctx, connect.NewRequest(req))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
log = log.With("platform_id", pf.Msg.GetPlatform().GetId())
|
||||
log.DebugContext(ctx, "create platform", "duration", time.Since(start))
|
||||
return pf.Msg.GetPlatform(), nil
|
||||
}
|
||||
|
||||
@@ -61,3 +61,11 @@ func (c *Config) Context() *holos.ClientContext {
|
||||
}
|
||||
return c.context
|
||||
}
|
||||
|
||||
// Holos returns the *holos.Config
|
||||
func (c *Config) Holos() *holos.Config {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.holos
|
||||
}
|
||||
|
||||
69
internal/client/platform.go
Normal file
69
internal/client/platform.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
object "github.com/holos-run/holos/service/gen/holos/object/v1alpha1"
|
||||
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
)
|
||||
|
||||
// PlatformMetadataFile is the platform metadata json file name located in the root
|
||||
// of a platform directory.
|
||||
const PlatformMetadataFile = "platform.metadata.json"
|
||||
|
||||
// PlatformConfigFile is the marshaled json representation of the PlatformConfig
|
||||
// DTO used to cache the data holos passes from the PlatformService to CUE when
|
||||
// rendering platform components.
|
||||
const PlatformConfigFile = "platform.config.json"
|
||||
|
||||
// LoadPlatform loads the platform.metadata.json file from a named path. Useful
|
||||
// to obtain a platform id for PlatformService rpc methods.
|
||||
func LoadPlatform(ctx context.Context, name string) (*platform.Platform, error) {
|
||||
data, err := os.ReadFile(filepath.Join(name, PlatformMetadataFile))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not load platform metadata: %w", err)
|
||||
}
|
||||
p := &platform.Platform{}
|
||||
if err := protojson.Unmarshal(data, p); err != nil {
|
||||
return nil, fmt.Errorf("could not load platform metadata: %w", err)
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// LoadPlatformConfig loads the PlatformConfig DTO from the platform.config.json
|
||||
// file. Useful to provide all values necessary to render cue config without an
|
||||
// rpc to the HolosService.
|
||||
func LoadPlatformConfig(ctx context.Context, name string) (*object.PlatformConfig, error) {
|
||||
data, err := os.ReadFile(filepath.Join(name, PlatformConfigFile))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not load platform config: %w", err)
|
||||
}
|
||||
pc := &object.PlatformConfig{}
|
||||
if err := protojson.Unmarshal(data, pc); err != nil {
|
||||
return nil, fmt.Errorf("could not load platform config: %w", err)
|
||||
}
|
||||
return pc, nil
|
||||
}
|
||||
|
||||
// SavePlatformConfig writes pc to the platform root directory path identified by name.
|
||||
func SavePlatformConfig(ctx context.Context, name string, pc *object.PlatformConfig) (string, error) {
|
||||
encoder := protojson.MarshalOptions{Multiline: true}
|
||||
data, err := encoder.Marshal(pc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(data) > 0 {
|
||||
data = append(data, '\n')
|
||||
}
|
||||
path := filepath.Join(name, PlatformConfigFile)
|
||||
if err := os.WriteFile(path, data, 0644); err != nil {
|
||||
return "", fmt.Errorf("could not write platform config: %w", err)
|
||||
}
|
||||
logger.FromContext(ctx).DebugContext(ctx, "wrote", "path", path)
|
||||
return path, nil
|
||||
}
|
||||
525
internal/frontend/holos/package-lock.json
generated
525
internal/frontend/holos/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -21,9 +21,9 @@
|
||||
"@angular/platform-browser": "^17.3.0",
|
||||
"@angular/platform-browser-dynamic": "^17.3.0",
|
||||
"@angular/router": "^17.3.0",
|
||||
"@bufbuild/protobuf": "^1.9.0",
|
||||
"@bufbuild/protobuf": "^1.10.0",
|
||||
"@connectrpc/connect": "^1.4.0",
|
||||
"@connectrpc/connect-query": "^1.4.0",
|
||||
"@connectrpc/connect-query": "^1.4.1",
|
||||
"@connectrpc/connect-web": "^1.4.0",
|
||||
"@ngx-formly/core": "^6.3.0",
|
||||
"@ngx-formly/material": "^6.3.0",
|
||||
@@ -40,10 +40,10 @@
|
||||
"@angular-eslint/template-parser": "17.3.0",
|
||||
"@angular/cli": "^17.3.4",
|
||||
"@angular/compiler-cli": "^17.3.0",
|
||||
"@bufbuild/buf": "^1.32.0",
|
||||
"@bufbuild/protoc-gen-es": "^1.9.0",
|
||||
"@bufbuild/buf": "^1.32.2",
|
||||
"@bufbuild/protoc-gen-es": "^1.10.0",
|
||||
"@connectrpc/protoc-gen-connect-es": "^1.4.0",
|
||||
"@connectrpc/protoc-gen-connect-query": "^1.4.0",
|
||||
"@connectrpc/protoc-gen-connect-query": "^1.4.1",
|
||||
"@ngx-formly/schematics": "^6.3.0",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "7.2.0",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/object/v1alpha1/object.proto (package holos.object.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
@@ -367,3 +367,53 @@ export class Form extends Message<Form> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PlatformConfig represents the data passed from the holos cli to CUE when
|
||||
* rendering configuration.
|
||||
*
|
||||
* @generated from message holos.object.v1alpha1.PlatformConfig
|
||||
*/
|
||||
export class PlatformConfig extends Message<PlatformConfig> {
|
||||
/**
|
||||
* Platform UUID.
|
||||
*
|
||||
* @generated from field: string platform_id = 1;
|
||||
*/
|
||||
platformId = "";
|
||||
|
||||
/**
|
||||
* Platform Model.
|
||||
*
|
||||
* @generated from field: google.protobuf.Struct platform_model = 2;
|
||||
*/
|
||||
platformModel?: Struct;
|
||||
|
||||
constructor(data?: PartialMessage<PlatformConfig>) {
|
||||
super();
|
||||
proto3.util.initPartial(data, this);
|
||||
}
|
||||
|
||||
static readonly runtime: typeof proto3 = proto3;
|
||||
static readonly typeName = "holos.object.v1alpha1.PlatformConfig";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "platform_model", kind: "message", T: Struct },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PlatformConfig {
|
||||
return new PlatformConfig().fromBinary(bytes, options);
|
||||
}
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PlatformConfig {
|
||||
return new PlatformConfig().fromJson(jsonValue, options);
|
||||
}
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PlatformConfig {
|
||||
return new PlatformConfig().fromJsonString(jsonString, options);
|
||||
}
|
||||
|
||||
static equals(a: PlatformConfig | PlainMessage<PlatformConfig> | undefined, b: PlatformConfig | PlainMessage<PlatformConfig> | undefined): boolean {
|
||||
return proto3.util.equals(PlatformConfig, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/organization/v1alpha1/organization.proto (package holos.organization.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/organization/v1alpha1/organization_service.proto (package holos.organization.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/platform/v1alpha1/platform.proto (package holos.platform.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/platform/v1alpha1/platform_service.proto (package holos.platform.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
@@ -13,9 +13,14 @@ import { Form } from "../../object/v1alpha1/object_pb.js";
|
||||
*/
|
||||
export class CreatePlatformRequest extends Message<CreatePlatformRequest> {
|
||||
/**
|
||||
* @generated from field: holos.platform.v1alpha1.Platform platform = 1;
|
||||
* @generated from field: string org_id = 1;
|
||||
*/
|
||||
platform?: Platform;
|
||||
orgId = "";
|
||||
|
||||
/**
|
||||
* @generated from field: holos.platform.v1alpha1.PlatformMutation create = 2;
|
||||
*/
|
||||
create?: PlatformMutation;
|
||||
|
||||
constructor(data?: PartialMessage<CreatePlatformRequest>) {
|
||||
super();
|
||||
@@ -25,7 +30,8 @@ export class CreatePlatformRequest extends Message<CreatePlatformRequest> {
|
||||
static readonly runtime: typeof proto3 = proto3;
|
||||
static readonly typeName = "holos.platform.v1alpha1.CreatePlatformRequest";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 1, name: "platform", kind: "message", T: Platform },
|
||||
{ no: 1, name: "org_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "create", kind: "message", T: PlatformMutation },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreatePlatformRequest {
|
||||
@@ -168,20 +174,27 @@ export class GetPlatformResponse extends Message<GetPlatformResponse> {
|
||||
* @generated from message holos.platform.v1alpha1.UpdatePlatformRequest
|
||||
*/
|
||||
export class UpdatePlatformRequest extends Message<UpdatePlatformRequest> {
|
||||
/**
|
||||
* Platform UUID to update.
|
||||
*
|
||||
* @generated from field: string platform_id = 1;
|
||||
*/
|
||||
platformId = "";
|
||||
|
||||
/**
|
||||
* Update operations to perform. Fields are set to the provided value if
|
||||
* selected by the mask. Absent fields are cleared if they are selected by
|
||||
* the mask.
|
||||
*
|
||||
* @generated from field: holos.platform.v1alpha1.UpdatePlatformOperation update = 1;
|
||||
* @generated from field: holos.platform.v1alpha1.PlatformMutation update = 2;
|
||||
*/
|
||||
update?: UpdatePlatformOperation;
|
||||
update?: PlatformMutation;
|
||||
|
||||
/**
|
||||
* FieldMask represents the mutation operations to perform. Marked optional
|
||||
* for the nil guard check. Required.
|
||||
*
|
||||
* @generated from field: optional google.protobuf.FieldMask update_mask = 2;
|
||||
* @generated from field: optional google.protobuf.FieldMask update_mask = 3;
|
||||
*/
|
||||
updateMask?: FieldMask;
|
||||
|
||||
@@ -193,8 +206,9 @@ export class UpdatePlatformRequest extends Message<UpdatePlatformRequest> {
|
||||
static readonly runtime: typeof proto3 = proto3;
|
||||
static readonly typeName = "holos.platform.v1alpha1.UpdatePlatformRequest";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 1, name: "update", kind: "message", T: UpdatePlatformOperation },
|
||||
{ no: 2, name: "update_mask", kind: "message", T: FieldMask, opt: true },
|
||||
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "update", kind: "message", T: PlatformMutation },
|
||||
{ no: 3, name: "update_mask", kind: "message", T: FieldMask, opt: true },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UpdatePlatformRequest {
|
||||
@@ -334,16 +348,11 @@ export class ListPlatformsResponse extends Message<ListPlatformsResponse> {
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message holos.platform.v1alpha1.UpdatePlatformOperation
|
||||
* PlatformMutation represents the fields to create or update.
|
||||
*
|
||||
* @generated from message holos.platform.v1alpha1.PlatformMutation
|
||||
*/
|
||||
export class UpdatePlatformOperation extends Message<UpdatePlatformOperation> {
|
||||
/**
|
||||
* Platform UUID to update.
|
||||
*
|
||||
* @generated from field: string platform_id = 1;
|
||||
*/
|
||||
platformId = "";
|
||||
|
||||
export class PlatformMutation extends Message<PlatformMutation> {
|
||||
/**
|
||||
* Update the platform name.
|
||||
*
|
||||
@@ -372,35 +381,34 @@ export class UpdatePlatformOperation extends Message<UpdatePlatformOperation> {
|
||||
*/
|
||||
form?: Form;
|
||||
|
||||
constructor(data?: PartialMessage<UpdatePlatformOperation>) {
|
||||
constructor(data?: PartialMessage<PlatformMutation>) {
|
||||
super();
|
||||
proto3.util.initPartial(data, this);
|
||||
}
|
||||
|
||||
static readonly runtime: typeof proto3 = proto3;
|
||||
static readonly typeName = "holos.platform.v1alpha1.UpdatePlatformOperation";
|
||||
static readonly typeName = "holos.platform.v1alpha1.PlatformMutation";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
||||
{ no: 3, name: "display_name", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
||||
{ no: 4, name: "model", kind: "message", T: Struct, opt: true },
|
||||
{ no: 5, name: "form", kind: "message", T: Form, opt: true },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UpdatePlatformOperation {
|
||||
return new UpdatePlatformOperation().fromBinary(bytes, options);
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PlatformMutation {
|
||||
return new PlatformMutation().fromBinary(bytes, options);
|
||||
}
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): UpdatePlatformOperation {
|
||||
return new UpdatePlatformOperation().fromJson(jsonValue, options);
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PlatformMutation {
|
||||
return new PlatformMutation().fromJson(jsonValue, options);
|
||||
}
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): UpdatePlatformOperation {
|
||||
return new UpdatePlatformOperation().fromJsonString(jsonString, options);
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PlatformMutation {
|
||||
return new PlatformMutation().fromJsonString(jsonString, options);
|
||||
}
|
||||
|
||||
static equals(a: UpdatePlatformOperation | PlainMessage<UpdatePlatformOperation> | undefined, b: UpdatePlatformOperation | PlainMessage<UpdatePlatformOperation> | undefined): boolean {
|
||||
return proto3.util.equals(UpdatePlatformOperation, a, b);
|
||||
static equals(a: PlatformMutation | PlainMessage<PlatformMutation> | undefined, b: PlatformMutation | PlainMessage<PlatformMutation> | undefined): boolean {
|
||||
return proto3.util.equals(PlatformMutation, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/storage/v1alpha1/storage.proto (package holos.storage.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/system/v1alpha1/system.proto (package holos.system.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/system/v1alpha1/system_service.proto (package holos.system.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/user/v1alpha1/user.proto (package holos.user.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
|
||||
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
|
||||
// @generated from file holos/user/v1alpha1/user_service.proto (package holos.user.v1alpha1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ObservableClient } from '../../connect/observable-client';
|
||||
import { Organization } from '../gen/holos/organization/v1alpha1/organization_pb';
|
||||
import { Platform } from '../gen/holos/platform/v1alpha1/platform_pb';
|
||||
import { PlatformService as ConnectPlatformService } from '../gen/holos/platform/v1alpha1/platform_service_connect';
|
||||
import { GetPlatformRequest, ListPlatformsRequest, UpdatePlatformOperation, UpdatePlatformRequest } from '../gen/holos/platform/v1alpha1/platform_service_pb';
|
||||
import { GetPlatformRequest, ListPlatformsRequest, PlatformMutation, UpdatePlatformRequest } from '../gen/holos/platform/v1alpha1/platform_service_pb';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -26,9 +26,9 @@ export class PlatformService {
|
||||
}
|
||||
|
||||
updateModel(platformId: string, model: JsonValue): Observable<Platform | undefined> {
|
||||
const update = new UpdatePlatformOperation({ platformId: platformId, model: Struct.fromJson(model) })
|
||||
const update = new PlatformMutation({ model: Struct.fromJson(model) })
|
||||
const updateMask = new FieldMask({ paths: ["model"] })
|
||||
const req = new UpdatePlatformRequest({ update: update, updateMask: updateMask })
|
||||
const req = new UpdatePlatformRequest({ platformId: platformId, update: update, updateMask: updateMask })
|
||||
return this.client.updatePlatform(req).pipe(
|
||||
switchMap(resp => { return of(resp.platform) })
|
||||
)
|
||||
|
||||
149
internal/generate/component.go
Normal file
149
internal/generate/component.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
)
|
||||
|
||||
//go:embed all:components
|
||||
var components embed.FS
|
||||
|
||||
// componentsRoot is the root path to copy component cue code from.
|
||||
const componentsRoot = "components"
|
||||
|
||||
func NewSchematic(root string, name string) (*Schematic, error) {
|
||||
data, err := components.ReadFile(filepath.Join(root, name, "schematic.json"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
schematic := Schematic{Name: name}
|
||||
if err := json.Unmarshal(data, &schematic); err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
return &schematic, nil
|
||||
}
|
||||
|
||||
// Schematic represents the flags and command metadata stored in the
|
||||
// schematic.yaml file along side each schematic.
|
||||
type Schematic struct {
|
||||
// Name represents the name of the resource the schematic generates.
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
|
||||
Short string `json:"short,omitempty" yaml:"short,omitempty"`
|
||||
Long string `json:"long,omitempty" yaml:"long,omitempty"`
|
||||
|
||||
Chart *string `json:"chart,omitempty" yaml:"chart,omitempty"`
|
||||
Version *string `json:"version,omitempty" yaml:"version,omitempty"`
|
||||
Namespace *string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
|
||||
RepoName *string `json:"reponame,omitempty" yaml:"reponame,omitempty"`
|
||||
RepoURL *string `json:"repourl,omitempty" yaml:"repourl,omitempty"`
|
||||
|
||||
flagSet *flag.FlagSet
|
||||
}
|
||||
|
||||
func (s *Schematic) FlagSet() *flag.FlagSet {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
if s.flagSet != nil {
|
||||
return s.flagSet
|
||||
}
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fs.StringVar(&s.Name, "name", s.Name, "component name")
|
||||
if s.Chart != nil {
|
||||
fs.StringVar(s.Chart, "chart", *s.Chart, "chart name")
|
||||
}
|
||||
if s.Version != nil {
|
||||
fs.StringVar(s.Version, "component-version", *s.Version, "component version")
|
||||
}
|
||||
if s.Namespace != nil {
|
||||
fs.StringVar(s.Namespace, "namespace", *s.Namespace, "namespace")
|
||||
}
|
||||
if s.RepoName != nil {
|
||||
fs.StringVar(s.RepoName, "repo-name", *s.RepoName, "chart repository name")
|
||||
}
|
||||
if s.RepoURL != nil {
|
||||
fs.StringVar(s.RepoURL, "repo-url", *s.RepoURL, "chart repository url")
|
||||
}
|
||||
s.flagSet = fs
|
||||
return fs
|
||||
}
|
||||
|
||||
// CueComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func CueComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "cue"))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// HelmComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func HelmComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "helm"))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// makeRenderFunc makes a template rendering function for embedded files.
|
||||
func makeRenderFunc[T any](log *slog.Logger, path string, cfg T) func([]byte) *bytes.Buffer {
|
||||
return func(content []byte) *bytes.Buffer {
|
||||
tmpl, err := template.New(filepath.Base(path)).Parse(string(content))
|
||||
if err != nil {
|
||||
log.Error("could not load template", "err", err)
|
||||
return bytes.NewBuffer(content)
|
||||
}
|
||||
|
||||
var rendered bytes.Buffer
|
||||
if err := tmpl.Execute(&rendered, cfg); err != nil {
|
||||
log.Error("could not execute template", "err", err)
|
||||
return bytes.NewBuffer(content)
|
||||
}
|
||||
|
||||
return &rendered
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateComponent writes the cue code for a component to the local working
|
||||
// directory.
|
||||
func GenerateComponent(ctx context.Context, kind string, name string, cfg *Schematic) error {
|
||||
// use name from args to build the source path
|
||||
path := filepath.Join(componentsRoot, kind, name)
|
||||
// use cfg.Name from flags to build the destination path
|
||||
dstPath := filepath.Join(getCwd(ctx), cfg.Name)
|
||||
log := logger.FromContext(ctx).With("name", cfg.Name, "path", dstPath)
|
||||
log.DebugContext(ctx, "mkdir")
|
||||
if err := os.MkdirAll(dstPath, os.ModePerm); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
mapper := makeRenderFunc(log, path, cfg)
|
||||
if err := copyEmbedFS(ctx, components, path, dstPath, mapper); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
log.InfoContext(ctx, "generated component")
|
||||
return nil
|
||||
}
|
||||
4
internal/generate/components/cue/argocd/argocd.cue
Executable file
4
internal/generate/components/cue/argocd/argocd.cue
Executable file
@@ -0,0 +1,4 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubectl kustomize build plan.
|
||||
(#Kustomize & {Name: "{{ .Name }}"}).Output
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
namespace: "{{ .Namespace }}"
|
||||
resources:
|
||||
- "https://raw.githubusercontent.com/argoproj/argo-cd/v{{ .Version }}/manifests/install.yaml"
|
||||
7
internal/generate/components/cue/argocd/schematic.json
Normal file
7
internal/generate/components/cue/argocd/schematic.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "argocd",
|
||||
"namespace": "argocd",
|
||||
"short": "argocd kustomize",
|
||||
"long": "Manage argocd using a kustomization.yaml build plan.",
|
||||
"version": "2.11.2"
|
||||
}
|
||||
21
internal/generate/components/cue/configmap/configmap.cue
Normal file
21
internal/generate/components/cue/configmap/configmap.cue
Normal file
@@ -0,0 +1,21 @@
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
|
||||
let Objects = {
|
||||
Name: "{{ .Name }}"
|
||||
Namespace: "{{ .Namespace }}"
|
||||
|
||||
Resources: {
|
||||
ConfigMap: {
|
||||
example: {
|
||||
metadata: namespace: "{{ .Namespace }}"
|
||||
// _Platform.Model represents the web form model
|
||||
data: platform: yaml.Marshal({model: _Platform.Model})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).Output
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "configmap",
|
||||
"namespace": "default",
|
||||
"short": "simple configmap example",
|
||||
"long": "End-to-end demonstration of data flowing from the web ui to a cluster resource"
|
||||
}
|
||||
11
internal/generate/components/cue/namespaces/namespaces.cue
Normal file
11
internal/generate/components/cue/namespaces/namespaces.cue
Normal file
@@ -0,0 +1,11 @@
|
||||
package holos
|
||||
|
||||
let Objects = {
|
||||
Name: "{{ .Name }}"
|
||||
Namespace: "{{ .Namespace }}"
|
||||
|
||||
Resources: Namespace: _Namespaces
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).Output
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "namespaces",
|
||||
"namespace": "default",
|
||||
"short": "manage namespaces on multiple clusters",
|
||||
"long": "Manage namespaces across all clusters in the platform following sig-multicluster namespace sameness position."
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package holos
|
||||
|
||||
let Chart = {
|
||||
Name: "{{ .Name }}"
|
||||
Version: "{{ .Version }}"
|
||||
Namespace: "{{ .Namespace }}"
|
||||
|
||||
Repo: name: "{{ .RepoName }}"
|
||||
Repo: url: "{{ .RepoURL }}"
|
||||
|
||||
Values: {
|
||||
installCRDs: true
|
||||
startupapicheck: enabled: false
|
||||
// Must not use kube-system on gke autopilot. GKE Warden blocks access.
|
||||
global: leaderElection: namespace: Namespace
|
||||
}
|
||||
}
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "cert-manager",
|
||||
"short": "cloud native certificate management",
|
||||
"long": "Automatically provision and manage TLS certificates in Kubernetes",
|
||||
"chart": "cert-manager",
|
||||
"version": "1.14.5",
|
||||
"namespace": "cert-manager",
|
||||
"reponame": "jetstack",
|
||||
"repourl": "https://charts.jetstack.io"
|
||||
}
|
||||
15
internal/generate/components/helm/podinfo-oci/podinfo.cue
Normal file
15
internal/generate/components/helm/podinfo-oci/podinfo.cue
Normal file
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
let Chart = {
|
||||
Name: "{{ .Name }}"
|
||||
Version: "{{ .Version }}"
|
||||
Namespace: "{{ .Namespace }}"
|
||||
|
||||
// OCI helm charts use the image url as the chart name
|
||||
Chart: chart: name: "{{ .Chart }}"
|
||||
|
||||
Values: {}
|
||||
}
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "podinfo-oci",
|
||||
"short": "oci helm chart example",
|
||||
"long": "Podinfo is a tiny web application made with Go that showcases best practices of running microservices in Kubernetes.",
|
||||
"chart": "oci://ghcr.io/stefanprodan/charts/podinfo",
|
||||
"version": "6.6.2",
|
||||
"namespace": "default"
|
||||
}
|
||||
15
internal/generate/components/helm/podinfo/podinfo.cue
Normal file
15
internal/generate/components/helm/podinfo/podinfo.cue
Normal file
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
let Chart = {
|
||||
Name: "{{ .Name }}"
|
||||
Version: "{{ .Version }}"
|
||||
Namespace: "{{ .Namespace }}"
|
||||
|
||||
Repo: name: "{{ .RepoName }}"
|
||||
Repo: url: "{{ .RepoURL }}"
|
||||
|
||||
Values: {}
|
||||
}
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
10
internal/generate/components/helm/podinfo/schematic.json
Normal file
10
internal/generate/components/helm/podinfo/schematic.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "podinfo",
|
||||
"short": "simple helm chart example",
|
||||
"long": "Podinfo is a tiny web application made with Go that showcases best practices of running microservices in Kubernetes.",
|
||||
"chart": "podinfo",
|
||||
"reponame": "podinfo",
|
||||
"repourl": "https://stefanprodan.github.io/podinfo",
|
||||
"version": "6.6.2",
|
||||
"namespace": "default"
|
||||
}
|
||||
@@ -1,98 +1,17 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
|
||||
)
|
||||
|
||||
//go:embed all:platforms
|
||||
var platforms embed.FS
|
||||
|
||||
// root is the root path to copy platform cue code from.
|
||||
const root = "platforms"
|
||||
|
||||
// Platforms returns a slice of embedded platforms or nil if there are none.
|
||||
func Platforms() []string {
|
||||
entries, err := fs.ReadDir(platforms, root)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() && entry.Name() != "cue.mod" {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// GeneratePlatform writes the cue code for a platform to the local working
|
||||
// directory.
|
||||
func GeneratePlatform(ctx context.Context, rpc *client.Client, orgID string, name string) error {
|
||||
log := logger.FromContext(ctx)
|
||||
// Check for a valid platform
|
||||
platformPath := filepath.Join(root, name)
|
||||
if !dirExists(platforms, platformPath) {
|
||||
return errors.Wrap(fmt.Errorf("cannot generate: have: [%s] want: %+v", name, Platforms()))
|
||||
}
|
||||
|
||||
// Link the local platform the SaaS platform ID.
|
||||
rpcPlatforms, err := rpc.Platforms(ctx, orgID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
var rpcPlatform *platform.Platform
|
||||
for _, p := range rpcPlatforms {
|
||||
if p.GetName() == name {
|
||||
rpcPlatform = p
|
||||
break
|
||||
}
|
||||
}
|
||||
if rpcPlatform == nil {
|
||||
return errors.Wrap(errors.New("cannot generate: platform not found in the holos server"))
|
||||
}
|
||||
|
||||
// Write the platform data.
|
||||
data, err := json.MarshalIndent(rpcPlatform, "", " ")
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if len(data) > 0 {
|
||||
data = append(data, '\n')
|
||||
}
|
||||
log = log.With("platform_id", rpcPlatform.GetId())
|
||||
path := "platform.metadata.json"
|
||||
if err := os.WriteFile(path, data, 0644); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not write platform metadata: %w", err))
|
||||
}
|
||||
log.InfoContext(ctx, "wrote "+path, "path", filepath.Join(getCwd(ctx), path))
|
||||
|
||||
// Copy the cue.mod directory
|
||||
if err := copyEmbedFS(ctx, platforms, filepath.Join(root, "cue.mod"), "cue.mod"); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// Copy the named platform
|
||||
if err := copyEmbedFS(ctx, platforms, platformPath, "."); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
log.InfoContext(ctx, "generated platform "+name, "path", getCwd(ctx))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dirExists(srcFS embed.FS, path string) bool {
|
||||
entries, err := fs.ReadDir(srcFS, path)
|
||||
if err != nil {
|
||||
@@ -101,7 +20,9 @@ func dirExists(srcFS embed.FS, path string) bool {
|
||||
return len(entries) > 0
|
||||
}
|
||||
|
||||
func copyEmbedFS(ctx context.Context, srcFS embed.FS, srcPath, dstPath string) error {
|
||||
// copyEmbedFS copies embedded files from srcPath to dstPath passing the
|
||||
// contents through mapFunc.
|
||||
func copyEmbedFS(ctx context.Context, srcFS embed.FS, srcPath, dstPath string, mapFunc func([]byte) *bytes.Buffer) error {
|
||||
log := logger.FromContext(ctx)
|
||||
return fs.WalkDir(srcFS, srcPath, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
@@ -120,16 +41,25 @@ func copyEmbedFS(ctx context.Context, srcFS embed.FS, srcPath, dstPath string) e
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.DebugContext(ctx, "created", "directory", dstFullPath)
|
||||
} else {
|
||||
data, err := srcFS.ReadFile(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if err := os.WriteFile(dstFullPath, data, os.ModePerm); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.DebugContext(ctx, "wrote", "file", dstFullPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
if filepath.Base(path) == "schematic.json" {
|
||||
log.DebugContext(ctx, "skipped", "file", dstFullPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := srcFS.ReadFile(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
buf := mapFunc(data)
|
||||
if err := os.WriteFile(dstFullPath, buf.Bytes(), 0666); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
log.DebugContext(ctx, "wrote", "file", dstFullPath)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
94
internal/generate/platform.go
Normal file
94
internal/generate/platform.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
|
||||
)
|
||||
|
||||
//go:embed all:platforms
|
||||
var platforms embed.FS
|
||||
|
||||
// platformsRoot is the root path to copy platform cue code from.
|
||||
const platformsRoot = "platforms"
|
||||
|
||||
// Platforms returns a slice of embedded platforms or nil if there are none.
|
||||
func Platforms() []string {
|
||||
entries, err := fs.ReadDir(platforms, platformsRoot)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() && entry.Name() != "cue.mod" {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// GeneratePlatform writes the cue code for a platform to the local working
|
||||
// directory.
|
||||
func GeneratePlatform(ctx context.Context, rpc *client.Client, orgID string, name string) error {
|
||||
log := logger.FromContext(ctx)
|
||||
// Check for a valid platform
|
||||
platformPath := filepath.Join(platformsRoot, name)
|
||||
if !dirExists(platforms, platformPath) {
|
||||
return errors.Wrap(fmt.Errorf("cannot generate: have: [%s] want: %+v", name, Platforms()))
|
||||
}
|
||||
|
||||
// Link the local platform the SaaS platform ID.
|
||||
rpcPlatforms, err := rpc.Platforms(ctx, orgID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
var rpcPlatform *platform.Platform
|
||||
for _, p := range rpcPlatforms {
|
||||
if p.GetName() == name {
|
||||
rpcPlatform = p
|
||||
break
|
||||
}
|
||||
}
|
||||
if rpcPlatform == nil {
|
||||
return errors.Wrap(errors.New("cannot generate: platform not found in the holos server"))
|
||||
}
|
||||
|
||||
// Write the platform data.
|
||||
data, err := json.MarshalIndent(rpcPlatform, "", " ")
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if len(data) > 0 {
|
||||
data = append(data, '\n')
|
||||
}
|
||||
log = log.With("platform_id", rpcPlatform.GetId())
|
||||
if err := os.WriteFile(client.PlatformMetadataFile, data, 0644); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not write platform metadata: %w", err))
|
||||
}
|
||||
log.InfoContext(ctx, "wrote "+client.PlatformMetadataFile, "path", filepath.Join(getCwd(ctx), client.PlatformMetadataFile))
|
||||
|
||||
// Copy the cue.mod directory
|
||||
if err := copyEmbedFS(ctx, platforms, filepath.Join(platformsRoot, "cue.mod"), "cue.mod", bytes.NewBuffer); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// Copy the named platform
|
||||
if err := copyEmbedFS(ctx, platforms, platformPath, ".", bytes.NewBuffer); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
log.InfoContext(ctx, "generated platform "+name, "path", getCwd(ctx))
|
||||
|
||||
return nil
|
||||
}
|
||||
33
internal/generate/platforms/bare/buildplan.cue
Normal file
33
internal/generate/platforms/bare/buildplan.cue
Normal file
@@ -0,0 +1,33 @@
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
import v1 "github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
// #Helm represents a holos build plan composed of one or more helm charts.
|
||||
#Helm: {
|
||||
Name: string
|
||||
Version: string
|
||||
Namespace: string
|
||||
|
||||
Repo: {
|
||||
name: string | *""
|
||||
url: string | *""
|
||||
}
|
||||
|
||||
Values: {...}
|
||||
|
||||
Chart: v1.#HelmChart & {
|
||||
metadata: name: string | *Name
|
||||
namespace: string | *Namespace
|
||||
chart: name: string | *Name
|
||||
chart: version: string | *Version
|
||||
chart: repository: Repo
|
||||
// Render the values to yaml for holos to provide to helm.
|
||||
valuesContent: yaml.Marshal(Values)
|
||||
}
|
||||
|
||||
// output represents the build plan provided to the holos cli.
|
||||
Output: v1.#BuildPlan & {
|
||||
spec: components: helmChartList: [Chart]
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
import v1 "github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
let PLATFORM = {message: "TODO: Load the platform from the API."}
|
||||
import v1 "github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
// Provide a BuildPlan to the holos cli to render k8s api objects.
|
||||
v1.#BuildPlan & {
|
||||
@@ -20,6 +19,12 @@ let OBJECTS = v1.#APIObjects & {
|
||||
name: "platform"
|
||||
namespace: "default"
|
||||
}
|
||||
// Output the platform model which is derived from the web app form the
|
||||
// platform engineer provides and the form values the end user provides.
|
||||
data: platform: yaml.Marshal(PLATFORM)
|
||||
}
|
||||
}
|
||||
|
||||
let PLATFORM = {
|
||||
spec: model: _Platform.spec.model
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ let FormBuilder = v1.#FormBuilder & {
|
||||
required: true
|
||||
}
|
||||
validation: messages: {
|
||||
pattern: "It must be \(props.minLength) to \(props.maxLength) lowercase letters, digits, or hyphens. It must start with a letter. Trailing hyphens are prohibited."
|
||||
pattern: "It must be \(props.minLength) to \(props.maxLength) lowercase letters, digits, or hyphens. It must start with a letter. Trailing hyphens are prohibited."
|
||||
minLength: "Must be at least \(props.minLength) characters."
|
||||
maxLength: "Must be at most \(props.maxLength) characters."
|
||||
}
|
||||
|
||||
47
internal/generate/platforms/bare/platform.cue
Normal file
47
internal/generate/platforms/bare/platform.cue
Normal file
@@ -0,0 +1,47 @@
|
||||
package holos
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
import v1 "github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
import dto "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
|
||||
|
||||
// _PlatformConfig represents all of the data passed from holos to cue.
|
||||
// Intended to carry the platform model and project models.
|
||||
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
|
||||
_PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
|
||||
|
||||
// _Platform provides a platform resource to the holos cli for rendering. The
|
||||
// field is hidden because most components need to refer to platform data,
|
||||
// specifically the platform model and the project models. The platform
|
||||
// resource itself is output once when rendering the entire platform, see the
|
||||
// platform/ subdirectory.
|
||||
_Platform: v1.#Platform & {
|
||||
metadata: {
|
||||
name: string | *"bare" @tag(platform_name, type=string)
|
||||
}
|
||||
|
||||
// spec is the platform specification
|
||||
spec: {
|
||||
// model represents the web form values provided by the user.
|
||||
model: _PlatformConfig.platform_model
|
||||
components: [for c in _components {c}]
|
||||
|
||||
_components: [string]: v1.#PlatformSpecComponent
|
||||
_components: {
|
||||
for WorkloadCluster in _Clusters.Workload {
|
||||
"\(WorkloadCluster)-configmap": {
|
||||
path: "components/configmap"
|
||||
cluster: WorkloadCluster
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _Clusters represents the clusters in the platform. The default values are
|
||||
// intended to be provided by the user in a file which is not written over by
|
||||
// `holos generate`.
|
||||
_Clusters: {
|
||||
Workload: [...string] | *["mycluster"]
|
||||
}
|
||||
4
internal/generate/platforms/bare/platform/platform.cue
Normal file
4
internal/generate/platforms/bare/platform/platform.cue
Normal file
@@ -0,0 +1,4 @@
|
||||
package holos
|
||||
|
||||
// Output the Platform resource for holos to render the entire platform.
|
||||
{} & _Platform
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,189 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f deploy/clusters/aws2/components/argocd-crds/argocd-crds.gen.yaml
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import "strings"
|
||||
|
||||
// AppProject provides a logical grouping of applications,
|
||||
// providing controls for: * where the apps may deploy to
|
||||
// (cluster whitelist) * what may be deployed (repository
|
||||
// whitelist, resource whitelist/blacklist) * who can access
|
||||
// these applications (roles, OIDC group claims bindings) * and
|
||||
// what they can do (RBAC policies) * automation access to these
|
||||
// roles (JWT tokens)
|
||||
#AppProject: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "argoproj.io/v1alpha1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "AppProject"
|
||||
metadata: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// AppProjectSpec is the specification of an AppProject
|
||||
spec!: #AppProjectSpec
|
||||
}
|
||||
|
||||
// AppProjectSpec is the specification of an AppProject
|
||||
#AppProjectSpec: {
|
||||
// ClusterResourceBlacklist contains list of blacklisted cluster
|
||||
// level resources
|
||||
clusterResourceBlacklist?: [...{
|
||||
group: string
|
||||
kind: string
|
||||
}]
|
||||
|
||||
// ClusterResourceWhitelist contains list of whitelisted cluster
|
||||
// level resources
|
||||
clusterResourceWhitelist?: [...{
|
||||
group: string
|
||||
kind: string
|
||||
}]
|
||||
|
||||
// Description contains optional project description
|
||||
description?: string
|
||||
|
||||
// Destinations contains list of destinations available for
|
||||
// deployment
|
||||
destinations?: [...{
|
||||
// Name is an alternate way of specifying the target cluster by
|
||||
// its symbolic name. This must be set if Server is not set.
|
||||
name?: string
|
||||
|
||||
// Namespace specifies the target namespace for the application's
|
||||
// resources. The namespace will only be set for namespace-scoped
|
||||
// resources that have not set a value for .metadata.namespace
|
||||
namespace?: string
|
||||
|
||||
// Server specifies the URL of the target cluster's Kubernetes
|
||||
// control plane API. This must be set if Name is not set.
|
||||
server?: string
|
||||
}]
|
||||
|
||||
// NamespaceResourceBlacklist contains list of blacklisted
|
||||
// namespace level resources
|
||||
namespaceResourceBlacklist?: [...{
|
||||
group: string
|
||||
kind: string
|
||||
}]
|
||||
|
||||
// NamespaceResourceWhitelist contains list of whitelisted
|
||||
// namespace level resources
|
||||
namespaceResourceWhitelist?: [...{
|
||||
group: string
|
||||
kind: string
|
||||
}]
|
||||
|
||||
// OrphanedResources specifies if controller should monitor
|
||||
// orphaned resources of apps in this project
|
||||
orphanedResources?: {
|
||||
// Ignore contains a list of resources that are to be excluded
|
||||
// from orphaned resources monitoring
|
||||
ignore?: [...{
|
||||
group?: string
|
||||
kind?: string
|
||||
name?: string
|
||||
}]
|
||||
|
||||
// Warn indicates if warning condition should be created for apps
|
||||
// which have orphaned resources
|
||||
warn?: bool
|
||||
}
|
||||
|
||||
// PermitOnlyProjectScopedClusters determines whether destinations
|
||||
// can only reference clusters which are project-scoped
|
||||
permitOnlyProjectScopedClusters?: bool
|
||||
|
||||
// Roles are user defined RBAC roles associated with this project
|
||||
roles?: [...{
|
||||
// Description is a description of the role
|
||||
description?: string
|
||||
|
||||
// Groups are a list of OIDC group claims bound to this role
|
||||
groups?: [...string]
|
||||
|
||||
// JWTTokens are a list of generated JWT tokens bound to this role
|
||||
jwtTokens?: [...{
|
||||
exp?: int
|
||||
iat: int
|
||||
id?: string
|
||||
}]
|
||||
|
||||
// Name is a name for this role
|
||||
name: string
|
||||
|
||||
// Policies Stores a list of casbin formatted strings that define
|
||||
// access policies for the role in the project
|
||||
policies?: [...string]
|
||||
}]
|
||||
|
||||
// SignatureKeys contains a list of PGP key IDs that commits in
|
||||
// Git must be signed with in order to be allowed for sync
|
||||
signatureKeys?: [...{
|
||||
// The ID of the key in hexadecimal notation
|
||||
keyID: string
|
||||
}]
|
||||
|
||||
// SourceNamespaces defines the namespaces application resources
|
||||
// are allowed to be created in
|
||||
sourceNamespaces?: [...string]
|
||||
|
||||
// SourceRepos contains list of repository URLs which can be used
|
||||
// for deployment
|
||||
sourceRepos?: [...string]
|
||||
|
||||
// SyncWindows controls when syncs can be run for apps in this
|
||||
// project
|
||||
syncWindows?: [...{
|
||||
// Applications contains a list of applications that the window
|
||||
// will apply to
|
||||
applications?: [...string]
|
||||
|
||||
// Clusters contains a list of clusters that the window will apply
|
||||
// to
|
||||
clusters?: [...string]
|
||||
|
||||
// Duration is the amount of time the sync window will be open
|
||||
duration?: string
|
||||
|
||||
// Kind defines if the window allows or blocks syncs
|
||||
kind?: string
|
||||
|
||||
// ManualSync enables manual syncs when they would otherwise be
|
||||
// blocked
|
||||
manualSync?: bool
|
||||
|
||||
// Namespaces contains a list of namespaces that the window will
|
||||
// apply to
|
||||
namespaces?: [...string]
|
||||
|
||||
// Schedule is the time the window will begin, specified in cron
|
||||
// format
|
||||
schedule?: string
|
||||
|
||||
// TimeZone of the sync that will be applied to the schedule
|
||||
timeZone?: string
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-mesh-certmanager/prod-mesh-certmanager.gen.yaml
|
||||
|
||||
package v1
|
||||
|
||||
import "strings"
|
||||
|
||||
// A Certificate resource should be created to ensure an up to
|
||||
// date and signed X.509 certificate is stored in the Kubernetes
|
||||
// Secret resource named in `spec.secretName`.
|
||||
// The stored certificate will be renewed before it expires (as
|
||||
// configured by `spec.renewBefore`).
|
||||
#Certificate: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "cert-manager.io/v1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "Certificate"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Specification of the desired state of the Certificate resource.
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
spec!: #CertificateSpec
|
||||
}
|
||||
|
||||
// Specification of the desired state of the Certificate resource.
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
#CertificateSpec: {
|
||||
// Defines extra output formats of the private key and signed
|
||||
// certificate chain to be written to this Certificate's target
|
||||
// Secret.
|
||||
// This is an Alpha Feature and is only enabled with the
|
||||
// `--feature-gates=AdditionalCertificateOutputFormats=true`
|
||||
// option set on both the controller and webhook components.
|
||||
additionalOutputFormats?: [...{
|
||||
// Type is the name of the format type that should be written to
|
||||
// the Certificate's target Secret.
|
||||
type: "DER" | "CombinedPEM"
|
||||
}]
|
||||
|
||||
// Requested common name X509 certificate subject attribute. More
|
||||
// info:
|
||||
// https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
|
||||
// NOTE: TLS clients will ignore this value when any subject
|
||||
// alternative name is set (see
|
||||
// https://tools.ietf.org/html/rfc6125#section-6.4.4).
|
||||
// Should have a length of 64 characters or fewer to avoid
|
||||
// generating invalid CSRs. Cannot be set if the `literalSubject`
|
||||
// field is set.
|
||||
commonName?: string
|
||||
|
||||
// Requested DNS subject alternative names.
|
||||
dnsNames?: [...string]
|
||||
|
||||
// Requested 'duration' (i.e. lifetime) of the Certificate. Note
|
||||
// that the issuer may choose to ignore the requested duration,
|
||||
// just like any other requested attribute.
|
||||
// If unset, this defaults to 90 days. Minimum accepted duration
|
||||
// is 1 hour. Value must be in units accepted by Go
|
||||
// time.ParseDuration https://golang.org/pkg/time/#ParseDuration.
|
||||
duration?: string
|
||||
|
||||
// Requested email subject alternative names.
|
||||
emailAddresses?: [...string]
|
||||
|
||||
// Whether the KeyUsage and ExtKeyUsage extensions should be set
|
||||
// in the encoded CSR.
|
||||
// This option defaults to true, and should only be disabled if
|
||||
// the target issuer does not support CSRs with these X509
|
||||
// KeyUsage/ ExtKeyUsage extensions.
|
||||
encodeUsagesInRequest?: bool
|
||||
|
||||
// Requested IP address subject alternative names.
|
||||
ipAddresses?: [...string]
|
||||
|
||||
// Requested basic constraints isCA value. The isCA value is used
|
||||
// to set the `isCA` field on the created CertificateRequest
|
||||
// resources. Note that the issuer may choose to ignore the
|
||||
// requested isCA value, just like any other requested attribute.
|
||||
// If true, this will automatically add the `cert sign` usage to
|
||||
// the list of requested `usages`.
|
||||
isCA?: bool
|
||||
|
||||
// Reference to the issuer responsible for issuing the
|
||||
// certificate. If the issuer is namespace-scoped, it must be in
|
||||
// the same namespace as the Certificate. If the issuer is
|
||||
// cluster-scoped, it can be used from any namespace.
|
||||
// The `name` field of the reference must always be specified.
|
||||
issuerRef: {
|
||||
// Group of the resource being referred to.
|
||||
group?: string
|
||||
|
||||
// Kind of the resource being referred to.
|
||||
kind?: string
|
||||
|
||||
// Name of the resource being referred to.
|
||||
name: string
|
||||
}
|
||||
|
||||
// Additional keystore output formats to be stored in the
|
||||
// Certificate's Secret.
|
||||
keystores?: {
|
||||
// JKS configures options for storing a JKS keystore in the
|
||||
// `spec.secretName` Secret resource.
|
||||
jks?: {
|
||||
// Create enables JKS keystore creation for the Certificate. If
|
||||
// true, a file named `keystore.jks` will be created in the
|
||||
// target Secret resource, encrypted using the password stored in
|
||||
// `passwordSecretRef`. The keystore file will be updated
|
||||
// immediately. If the issuer provided a CA certificate, a file
|
||||
// named `truststore.jks` will also be created in the target
|
||||
// Secret resource, encrypted using the password stored in
|
||||
// `passwordSecretRef` containing the issuing Certificate
|
||||
// Authority
|
||||
create: bool
|
||||
|
||||
// PasswordSecretRef is a reference to a key in a Secret resource
|
||||
// containing the password used to encrypt the JKS keystore.
|
||||
passwordSecretRef: {
|
||||
// The key of the entry in the Secret resource's `data` field to
|
||||
// be used. Some instances of this field may be defaulted, in
|
||||
// others it may be required.
|
||||
key?: string
|
||||
|
||||
// Name of the resource being referred to. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
name: string
|
||||
}
|
||||
}
|
||||
|
||||
// PKCS12 configures options for storing a PKCS12 keystore in the
|
||||
// `spec.secretName` Secret resource.
|
||||
pkcs12?: {
|
||||
// Create enables PKCS12 keystore creation for the Certificate. If
|
||||
// true, a file named `keystore.p12` will be created in the
|
||||
// target Secret resource, encrypted using the password stored in
|
||||
// `passwordSecretRef`. The keystore file will be updated
|
||||
// immediately. If the issuer provided a CA certificate, a file
|
||||
// named `truststore.p12` will also be created in the target
|
||||
// Secret resource, encrypted using the password stored in
|
||||
// `passwordSecretRef` containing the issuing Certificate
|
||||
// Authority
|
||||
create: bool
|
||||
|
||||
// PasswordSecretRef is a reference to a key in a Secret resource
|
||||
// containing the password used to encrypt the PKCS12 keystore.
|
||||
passwordSecretRef: {
|
||||
// The key of the entry in the Secret resource's `data` field to
|
||||
// be used. Some instances of this field may be defaulted, in
|
||||
// others it may be required.
|
||||
key?: string
|
||||
|
||||
// Name of the resource being referred to. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
name: string
|
||||
}
|
||||
|
||||
// Profile specifies the key and certificate encryption algorithms
|
||||
// and the HMAC algorithm used to create the PKCS12 keystore.
|
||||
// Default value is `LegacyRC2` for backward compatibility.
|
||||
// If provided, allowed values are: `LegacyRC2`: Deprecated. Not
|
||||
// supported by default in OpenSSL 3 or Java 20. `LegacyDES`:
|
||||
// Less secure algorithm. Use this option for maximal
|
||||
// compatibility. `Modern2023`: Secure algorithm. Use this option
|
||||
// in case you have to always use secure algorithms (eg. because
|
||||
// of company policy). Please note that the security of the
|
||||
// algorithm is not that important in reality, because the
|
||||
// unencrypted certificate and private key are also stored in the
|
||||
// Secret.
|
||||
profile?: "LegacyRC2" | "LegacyDES" | "Modern2023"
|
||||
}
|
||||
}
|
||||
|
||||
// Requested X.509 certificate subject, represented using the LDAP
|
||||
// "String Representation of a Distinguished Name" [1].
|
||||
// Important: the LDAP string format also specifies the order of
|
||||
// the attributes in the subject, this is important when issuing
|
||||
// certs for LDAP authentication. Example:
|
||||
// `CN=foo,DC=corp,DC=example,DC=com` More info [1]:
|
||||
// https://datatracker.ietf.org/doc/html/rfc4514 More info:
|
||||
// https://github.com/cert-manager/cert-manager/issues/3203 More
|
||||
// info: https://github.com/cert-manager/cert-manager/issues/4424
|
||||
// Cannot be set if the `subject` or `commonName` field is set.
|
||||
// This is an Alpha Feature and is only enabled with the
|
||||
// `--feature-gates=LiteralCertificateSubject=true` option set on
|
||||
// both the controller and webhook components.
|
||||
literalSubject?: string
|
||||
|
||||
// x.509 certificate NameConstraint extension which MUST NOT be
|
||||
// used in a non-CA certificate. More Info:
|
||||
// https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10
|
||||
// This is an Alpha Feature and is only enabled with the
|
||||
// `--feature-gates=NameConstraints=true` option set on both the
|
||||
// controller and webhook components.
|
||||
nameConstraints?: {
|
||||
// if true then the name constraints are marked critical.
|
||||
critical?: bool
|
||||
|
||||
// Excluded contains the constraints which must be disallowed. Any
|
||||
// name matching a restriction in the excluded field is invalid
|
||||
// regardless of information appearing in the permitted
|
||||
excluded?: {
|
||||
// DNSDomains is a list of DNS domains that are permitted or
|
||||
// excluded.
|
||||
dnsDomains?: [...string]
|
||||
|
||||
// EmailAddresses is a list of Email Addresses that are permitted
|
||||
// or excluded.
|
||||
emailAddresses?: [...string]
|
||||
|
||||
// IPRanges is a list of IP Ranges that are permitted or excluded.
|
||||
// This should be a valid CIDR notation.
|
||||
ipRanges?: [...string]
|
||||
|
||||
// URIDomains is a list of URI domains that are permitted or
|
||||
// excluded.
|
||||
uriDomains?: [...string]
|
||||
}
|
||||
|
||||
// Permitted contains the constraints in which the names must be
|
||||
// located.
|
||||
permitted?: {
|
||||
// DNSDomains is a list of DNS domains that are permitted or
|
||||
// excluded.
|
||||
dnsDomains?: [...string]
|
||||
|
||||
// EmailAddresses is a list of Email Addresses that are permitted
|
||||
// or excluded.
|
||||
emailAddresses?: [...string]
|
||||
|
||||
// IPRanges is a list of IP Ranges that are permitted or excluded.
|
||||
// This should be a valid CIDR notation.
|
||||
ipRanges?: [...string]
|
||||
|
||||
// URIDomains is a list of URI domains that are permitted or
|
||||
// excluded.
|
||||
uriDomains?: [...string]
|
||||
}
|
||||
}
|
||||
|
||||
// `otherNames` is an escape hatch for SAN that allows any type.
|
||||
// We currently restrict the support to string like otherNames,
|
||||
// cf RFC 5280 p 37 Any UTF8 String valued otherName can be
|
||||
// passed with by setting the keys oid: x.x.x.x and UTF8Value:
|
||||
// somevalue for `otherName`. Most commonly this would be UPN set
|
||||
// with oid: 1.3.6.1.4.1.311.20.2.3 You should ensure that any
|
||||
// OID passed is valid for the UTF8String type as we do not
|
||||
// explicitly validate this.
|
||||
otherNames?: [...{
|
||||
// OID is the object identifier for the otherName SAN. The object
|
||||
// identifier must be expressed as a dotted string, for example,
|
||||
// "1.2.840.113556.1.4.221".
|
||||
oid?: string
|
||||
|
||||
// utf8Value is the string value of the otherName SAN. The
|
||||
// utf8Value accepts any valid UTF8 string to set as value for
|
||||
// the otherName SAN.
|
||||
utf8Value?: string
|
||||
}]
|
||||
|
||||
// Private key options. These include the key algorithm and size,
|
||||
// the used encoding and the rotation policy.
|
||||
privateKey?: {
|
||||
// Algorithm is the private key algorithm of the corresponding
|
||||
// private key for this certificate.
|
||||
// If provided, allowed values are either `RSA`, `ECDSA` or
|
||||
// `Ed25519`. If `algorithm` is specified and `size` is not
|
||||
// provided, key size of 2048 will be used for `RSA` key
|
||||
// algorithm and key size of 256 will be used for `ECDSA` key
|
||||
// algorithm. key size is ignored when using the `Ed25519` key
|
||||
// algorithm.
|
||||
algorithm?: "RSA" | "ECDSA" | "Ed25519"
|
||||
|
||||
// The private key cryptography standards (PKCS) encoding for this
|
||||
// certificate's private key to be encoded in.
|
||||
// If provided, allowed values are `PKCS1` and `PKCS8` standing
|
||||
// for PKCS#1 and PKCS#8, respectively. Defaults to `PKCS1` if
|
||||
// not specified.
|
||||
encoding?: "PKCS1" | "PKCS8"
|
||||
|
||||
// RotationPolicy controls how private keys should be regenerated
|
||||
// when a re-issuance is being processed.
|
||||
// If set to `Never`, a private key will only be generated if one
|
||||
// does not already exist in the target `spec.secretName`. If one
|
||||
// does exists but it does not have the correct algorithm or
|
||||
// size, a warning will be raised to await user intervention. If
|
||||
// set to `Always`, a private key matching the specified
|
||||
// requirements will be generated whenever a re-issuance occurs.
|
||||
// Default is `Never` for backward compatibility.
|
||||
rotationPolicy?: "Never" | "Always"
|
||||
|
||||
// Size is the key bit size of the corresponding private key for
|
||||
// this certificate.
|
||||
// If `algorithm` is set to `RSA`, valid values are `2048`, `4096`
|
||||
// or `8192`, and will default to `2048` if not specified. If
|
||||
// `algorithm` is set to `ECDSA`, valid values are `256`, `384`
|
||||
// or `521`, and will default to `256` if not specified. If
|
||||
// `algorithm` is set to `Ed25519`, Size is ignored. No other
|
||||
// values are allowed.
|
||||
size?: int
|
||||
}
|
||||
|
||||
// How long before the currently issued certificate's expiry
|
||||
// cert-manager should renew the certificate. For example, if a
|
||||
// certificate is valid for 60 minutes, and `renewBefore=10m`,
|
||||
// cert-manager will begin to attempt to renew the certificate 50
|
||||
// minutes after it was issued (i.e. when there are 10 minutes
|
||||
// remaining until the certificate is no longer valid).
|
||||
// NOTE: The actual lifetime of the issued certificate is used to
|
||||
// determine the renewal time. If an issuer returns a certificate
|
||||
// with a different lifetime than the one requested, cert-manager
|
||||
// will use the lifetime of the issued certificate.
|
||||
// If unset, this defaults to 1/3 of the issued certificate's
|
||||
// lifetime. Minimum accepted value is 5 minutes. Value must be
|
||||
// in units accepted by Go time.ParseDuration
|
||||
// https://golang.org/pkg/time/#ParseDuration.
|
||||
renewBefore?: string
|
||||
|
||||
// The maximum number of CertificateRequest revisions that are
|
||||
// maintained in the Certificate's history. Each revision
|
||||
// represents a single `CertificateRequest` created by this
|
||||
// Certificate, either when it was created, renewed, or Spec was
|
||||
// changed. Revisions will be removed by oldest first if the
|
||||
// number of revisions exceeds this number.
|
||||
// If set, revisionHistoryLimit must be a value of `1` or greater.
|
||||
// If unset (`nil`), revisions will not be garbage collected.
|
||||
// Default value is `nil`.
|
||||
revisionHistoryLimit?: int
|
||||
|
||||
// Name of the Secret resource that will be automatically created
|
||||
// and managed by this Certificate resource. It will be populated
|
||||
// with a private key and certificate, signed by the denoted
|
||||
// issuer. The Secret resource lives in the same namespace as the
|
||||
// Certificate resource.
|
||||
secretName: string
|
||||
|
||||
// Defines annotations and labels to be copied to the
|
||||
// Certificate's Secret. Labels and annotations on the Secret
|
||||
// will be changed as they appear on the SecretTemplate when
|
||||
// added or removed. SecretTemplate annotations are added in
|
||||
// conjunction with, and cannot overwrite, the base set of
|
||||
// annotations cert-manager sets on the Certificate's Secret.
|
||||
secretTemplate?: {
|
||||
// Annotations is a key value map to be copied to the target
|
||||
// Kubernetes Secret.
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// Labels is a key value map to be copied to the target Kubernetes
|
||||
// Secret.
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Requested set of X509 certificate subject attributes. More
|
||||
// info:
|
||||
// https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
|
||||
// The common name attribute is specified separately in the
|
||||
// `commonName` field. Cannot be set if the `literalSubject`
|
||||
// field is set.
|
||||
subject?: {
|
||||
// Countries to be used on the Certificate.
|
||||
countries?: [...string]
|
||||
|
||||
// Cities to be used on the Certificate.
|
||||
localities?: [...string]
|
||||
|
||||
// Organizational Units to be used on the Certificate.
|
||||
organizationalUnits?: [...string]
|
||||
|
||||
// Organizations to be used on the Certificate.
|
||||
organizations?: [...string]
|
||||
|
||||
// Postal codes to be used on the Certificate.
|
||||
postalCodes?: [...string]
|
||||
|
||||
// State/Provinces to be used on the Certificate.
|
||||
provinces?: [...string]
|
||||
|
||||
// Serial number to be used on the Certificate.
|
||||
serialNumber?: string
|
||||
|
||||
// Street addresses to be used on the Certificate.
|
||||
streetAddresses?: [...string]
|
||||
}
|
||||
|
||||
// Requested URI subject alternative names.
|
||||
uris?: [...string]
|
||||
|
||||
// Requested key usages and extended key usages. These usages are
|
||||
// used to set the `usages` field on the created
|
||||
// CertificateRequest resources. If `encodeUsagesInRequest` is
|
||||
// unset or set to `true`, the usages will additionally be
|
||||
// encoded in the `request` field which contains the CSR blob.
|
||||
// If unset, defaults to `digital signature` and `key
|
||||
// encipherment`.
|
||||
usages?: [..."signing" | "digital signature" | "content commitment" | "key encipherment" | "key agreement" | "data encipherment" | "cert sign" | "crl sign" | "encipher only" | "decipher only" | "any" | "server auth" | "client auth" | "code signing" | "email protection" | "s/mime" | "ipsec end system" | "ipsec tunnel" | "ipsec user" | "timestamping" | "ocsp signing" | "microsoft sgc" | "netscape sgc"]
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-mesh-certmanager/prod-mesh-certmanager.gen.yaml
|
||||
|
||||
package v1
|
||||
|
||||
import "strings"
|
||||
|
||||
// A CertificateRequest is used to request a signed certificate
|
||||
// from one of the configured issuers.
|
||||
// All fields within the CertificateRequest's `spec` are immutable
|
||||
// after creation. A CertificateRequest will either succeed or
|
||||
// fail, as denoted by its `Ready` status condition and its
|
||||
// `status.failureTime` field.
|
||||
// A CertificateRequest is a one-shot resource, meaning it
|
||||
// represents a single point in time request for a certificate
|
||||
// and cannot be re-used.
|
||||
#CertificateRequest: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "cert-manager.io/v1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "CertificateRequest"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Specification of the desired state of the CertificateRequest
|
||||
// resource.
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
spec!: #CertificateRequestSpec
|
||||
}
|
||||
|
||||
// Specification of the desired state of the CertificateRequest
|
||||
// resource.
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
#CertificateRequestSpec: {
|
||||
// Requested 'duration' (i.e. lifetime) of the Certificate. Note
|
||||
// that the issuer may choose to ignore the requested duration,
|
||||
// just like any other requested attribute.
|
||||
duration?: string
|
||||
|
||||
// Extra contains extra attributes of the user that created the
|
||||
// CertificateRequest. Populated by the cert-manager webhook on
|
||||
// creation and immutable.
|
||||
extra?: {
|
||||
[string]: [...string]
|
||||
}
|
||||
|
||||
// Groups contains group membership of the user that created the
|
||||
// CertificateRequest. Populated by the cert-manager webhook on
|
||||
// creation and immutable.
|
||||
groups?: [...string]
|
||||
|
||||
// Requested basic constraints isCA value. Note that the issuer
|
||||
// may choose to ignore the requested isCA value, just like any
|
||||
// other requested attribute.
|
||||
// NOTE: If the CSR in the `Request` field has a BasicConstraints
|
||||
// extension, it must have the same isCA value as specified here.
|
||||
// If true, this will automatically add the `cert sign` usage to
|
||||
// the list of requested `usages`.
|
||||
isCA?: bool
|
||||
|
||||
// Reference to the issuer responsible for issuing the
|
||||
// certificate. If the issuer is namespace-scoped, it must be in
|
||||
// the same namespace as the Certificate. If the issuer is
|
||||
// cluster-scoped, it can be used from any namespace.
|
||||
// The `name` field of the reference must always be specified.
|
||||
issuerRef: {
|
||||
// Group of the resource being referred to.
|
||||
group?: string
|
||||
|
||||
// Kind of the resource being referred to.
|
||||
kind?: string
|
||||
|
||||
// Name of the resource being referred to.
|
||||
name: string
|
||||
}
|
||||
|
||||
// The PEM-encoded X.509 certificate signing request to be
|
||||
// submitted to the issuer for signing.
|
||||
// If the CSR has a BasicConstraints extension, its isCA attribute
|
||||
// must match the `isCA` value of this CertificateRequest. If the
|
||||
// CSR has a KeyUsage extension, its key usages must match the
|
||||
// key usages in the `usages` field of this CertificateRequest.
|
||||
// If the CSR has a ExtKeyUsage extension, its extended key
|
||||
// usages must match the extended key usages in the `usages`
|
||||
// field of this CertificateRequest.
|
||||
request: string
|
||||
|
||||
// UID contains the uid of the user that created the
|
||||
// CertificateRequest. Populated by the cert-manager webhook on
|
||||
// creation and immutable.
|
||||
uid?: string
|
||||
|
||||
// Requested key usages and extended key usages.
|
||||
// NOTE: If the CSR in the `Request` field has uses the KeyUsage
|
||||
// or ExtKeyUsage extension, these extensions must have the same
|
||||
// values as specified here without any additional values.
|
||||
// If unset, defaults to `digital signature` and `key
|
||||
// encipherment`.
|
||||
usages?: [..."signing" | "digital signature" | "content commitment" | "key encipherment" | "key agreement" | "data encipherment" | "cert sign" | "crl sign" | "encipher only" | "decipher only" | "any" | "server auth" | "client auth" | "code signing" | "email protection" | "s/mime" | "ipsec end system" | "ipsec tunnel" | "ipsec user" | "timestamping" | "ocsp signing" | "microsoft sgc" | "netscape sgc"]
|
||||
|
||||
// Username contains the name of the user that created the
|
||||
// CertificateRequest. Populated by the cert-manager webhook on
|
||||
// creation and immutable.
|
||||
username?: string
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,148 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f deploy/clusters/aws2/components/istio-base/istio-base.gen.yaml
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"list"
|
||||
)
|
||||
|
||||
#WasmPlugin: {
|
||||
// Extend the functionality provided by the Istio proxy through
|
||||
// WebAssembly filters. See more details at:
|
||||
// https://istio.io/docs/reference/config/proxy_extensions/wasm-plugin.html
|
||||
spec!: #WasmPluginSpec
|
||||
apiVersion: "extensions.istio.io/v1alpha1"
|
||||
kind: "WasmPlugin"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extend the functionality provided by the Istio proxy through
|
||||
// WebAssembly filters. See more details at:
|
||||
// https://istio.io/docs/reference/config/proxy_extensions/wasm-plugin.html
|
||||
#WasmPluginSpec: {
|
||||
// Specifies the failure behavior for the plugin due to fatal
|
||||
// errors.
|
||||
//
|
||||
// Valid Options: FAIL_CLOSE, FAIL_OPEN
|
||||
failStrategy?: "FAIL_CLOSE" | "FAIL_OPEN"
|
||||
|
||||
// The pull behaviour to be applied when fetching Wasm module by
|
||||
// either OCI image or `http/https`.
|
||||
//
|
||||
// Valid Options: IfNotPresent, Always
|
||||
imagePullPolicy?: "UNSPECIFIED_POLICY" | "IfNotPresent" | "Always"
|
||||
|
||||
// Credentials to use for OCI image pulling.
|
||||
imagePullSecret?: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
|
||||
// Specifies the criteria to determine which traffic is passed to
|
||||
// WasmPlugin.
|
||||
match?: [...{
|
||||
// Criteria for selecting traffic by their direction.
|
||||
//
|
||||
// Valid Options: CLIENT, SERVER, CLIENT_AND_SERVER
|
||||
mode?: "UNDEFINED" | "CLIENT" | "SERVER" | "CLIENT_AND_SERVER"
|
||||
|
||||
// Criteria for selecting traffic by their destination port.
|
||||
ports?: [...{
|
||||
number: uint16 & >=1
|
||||
}]
|
||||
}]
|
||||
|
||||
// Determines where in the filter chain this `WasmPlugin` is to be
|
||||
// injected.
|
||||
//
|
||||
// Valid Options: AUTHN, AUTHZ, STATS
|
||||
phase?: "UNSPECIFIED_PHASE" | "AUTHN" | "AUTHZ" | "STATS"
|
||||
|
||||
// The configuration that will be passed on to the plugin.
|
||||
pluginConfig?: {
|
||||
...
|
||||
}
|
||||
|
||||
// The plugin name to be used in the Envoy configuration (used to
|
||||
// be called `rootID`).
|
||||
pluginName?: strings.MaxRunes(256) & strings.MinRunes(1)
|
||||
|
||||
// Determines ordering of `WasmPlugins` in the same `phase`.
|
||||
priority?: null | int
|
||||
selector?: {
|
||||
// One or more labels that indicate a specific set of pods/VMs on
|
||||
// which a policy should be applied.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// SHA256 checksum that will be used to verify Wasm module or OCI
|
||||
// container.
|
||||
sha256?: =~"(^$|^[a-f0-9]{64}$)"
|
||||
targetRef?: {
|
||||
// group is the group of the target resource.
|
||||
group?: string
|
||||
|
||||
// kind is kind of the target resource.
|
||||
kind?: string
|
||||
|
||||
// name is the name of the target resource.
|
||||
name?: string
|
||||
|
||||
// namespace is the namespace of the referent.
|
||||
namespace?: string
|
||||
}
|
||||
|
||||
// Optional.
|
||||
targetRefs?: [...{
|
||||
// group is the group of the target resource.
|
||||
group?: string
|
||||
|
||||
// kind is kind of the target resource.
|
||||
kind?: string
|
||||
|
||||
// name is the name of the target resource.
|
||||
name?: string
|
||||
|
||||
// namespace is the namespace of the referent.
|
||||
namespace?: string
|
||||
}]
|
||||
|
||||
// Specifies the type of Wasm Extension to be used.
|
||||
//
|
||||
// Valid Options: HTTP, NETWORK
|
||||
type?: "UNSPECIFIED_PLUGIN_TYPE" | "HTTP" | "NETWORK"
|
||||
|
||||
// URL of a Wasm module or OCI container.
|
||||
url: strings.MinRunes(1)
|
||||
verificationKey?: string
|
||||
vmConfig?: {
|
||||
// Specifies environment variables to be injected to this VM.
|
||||
env?: list.MaxItems(256) & [...{
|
||||
// Name of the environment variable.
|
||||
name: strings.MaxRunes(256) & strings.MinRunes(1)
|
||||
|
||||
// Value for the environment variable.
|
||||
value?: strings.MaxRunes(2048)
|
||||
|
||||
// Source for the environment variable's value.
|
||||
//
|
||||
// Valid Options: INLINE, HOST
|
||||
valueFrom?: "INLINE" | "HOST"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-secrets-eso/prod-secrets-eso.gen.yaml
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"struct"
|
||||
)
|
||||
|
||||
// ClusterExternalSecret is the Schema for the
|
||||
// clusterexternalsecrets API.
|
||||
#ClusterExternalSecret: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "external-secrets.io/v1beta1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "ClusterExternalSecret"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// ClusterExternalSecretSpec defines the desired state of
|
||||
// ClusterExternalSecret.
|
||||
spec!: #ClusterExternalSecretSpec
|
||||
}
|
||||
|
||||
// ClusterExternalSecretSpec defines the desired state of
|
||||
// ClusterExternalSecret.
|
||||
#ClusterExternalSecretSpec: {
|
||||
// The metadata of the external secrets to be created
|
||||
externalSecretMetadata?: {
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// The name of the external secrets to be created defaults to the
|
||||
// name of the ClusterExternalSecret
|
||||
externalSecretName?: string
|
||||
|
||||
// The spec for the ExternalSecrets to be created
|
||||
externalSecretSpec: {
|
||||
// Data defines the connection between the Kubernetes Secret keys
|
||||
// and the Provider data
|
||||
data?: [...{
|
||||
// RemoteRef points to the remote secret and defines
|
||||
// which secret (version/property/..) to fetch.
|
||||
remoteRef: {
|
||||
// Used to define a conversion Strategy
|
||||
conversionStrategy?: "Default" | "Unicode" | *"Default"
|
||||
|
||||
// Used to define a decoding Strategy
|
||||
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
|
||||
|
||||
// Key is the key used in the Provider, mandatory
|
||||
key: string
|
||||
|
||||
// Policy for fetching tags/labels from provider secrets, possible
|
||||
// options are Fetch, None. Defaults to None
|
||||
metadataPolicy?: "None" | "Fetch" | *"None"
|
||||
|
||||
// Used to select a specific property of the Provider value (if a
|
||||
// map), if supported
|
||||
property?: string
|
||||
|
||||
// Used to select a specific version of the Provider value, if
|
||||
// supported
|
||||
version?: string
|
||||
}
|
||||
|
||||
// SecretKey defines the key in which the controller stores
|
||||
// the value. This is the key in the Kind=Secret
|
||||
secretKey: string
|
||||
|
||||
// SourceRef allows you to override the source
|
||||
// from which the value will pulled from.
|
||||
sourceRef?: struct.MaxFields(1) & {
|
||||
// GeneratorRef points to a generator custom resource.
|
||||
//
|
||||
//
|
||||
// Deprecated: The generatorRef is not implemented in .data[].
|
||||
// this will be removed with v1.
|
||||
generatorRef?: {
|
||||
// Specify the apiVersion of the generator resource
|
||||
apiVersion?: string | *"generators.external-secrets.io/v1alpha1"
|
||||
|
||||
// Specify the Kind of the resource, e.g. Password, ACRAccessToken
|
||||
// etc.
|
||||
kind: string
|
||||
|
||||
// Specify the name of the generator resource
|
||||
name: string
|
||||
}
|
||||
|
||||
// SecretStoreRef defines which SecretStore to fetch the
|
||||
// ExternalSecret data.
|
||||
storeRef?: {
|
||||
// Kind of the SecretStore resource (SecretStore or
|
||||
// ClusterSecretStore)
|
||||
// Defaults to `SecretStore`
|
||||
kind?: string
|
||||
|
||||
// Name of the SecretStore resource
|
||||
name: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// DataFrom is used to fetch all properties from a specific
|
||||
// Provider data
|
||||
// If multiple entries are specified, the Secret keys are merged
|
||||
// in the specified order
|
||||
dataFrom?: [...{
|
||||
// Used to extract multiple key/value pairs from one secret
|
||||
// Note: Extract does not support sourceRef.Generator or
|
||||
// sourceRef.GeneratorRef.
|
||||
extract?: {
|
||||
// Used to define a conversion Strategy
|
||||
conversionStrategy?: "Default" | "Unicode" | *"Default"
|
||||
|
||||
// Used to define a decoding Strategy
|
||||
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
|
||||
|
||||
// Key is the key used in the Provider, mandatory
|
||||
key: string
|
||||
|
||||
// Policy for fetching tags/labels from provider secrets, possible
|
||||
// options are Fetch, None. Defaults to None
|
||||
metadataPolicy?: "None" | "Fetch" | *"None"
|
||||
|
||||
// Used to select a specific property of the Provider value (if a
|
||||
// map), if supported
|
||||
property?: string
|
||||
|
||||
// Used to select a specific version of the Provider value, if
|
||||
// supported
|
||||
version?: string
|
||||
}
|
||||
|
||||
// Used to find secrets based on tags or regular expressions
|
||||
// Note: Find does not support sourceRef.Generator or
|
||||
// sourceRef.GeneratorRef.
|
||||
find?: {
|
||||
// Used to define a conversion Strategy
|
||||
conversionStrategy?: "Default" | "Unicode" | *"Default"
|
||||
|
||||
// Used to define a decoding Strategy
|
||||
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
|
||||
name?: {
|
||||
// Finds secrets base
|
||||
regexp?: string
|
||||
}
|
||||
|
||||
// A root path to start the find operations.
|
||||
path?: string
|
||||
|
||||
// Find secrets based on tags.
|
||||
tags?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Used to rewrite secret Keys after getting them from the secret
|
||||
// Provider
|
||||
// Multiple Rewrite operations can be provided. They are applied
|
||||
// in a layered order (first to last)
|
||||
rewrite?: [...{
|
||||
// Used to rewrite with regular expressions.
|
||||
// The resulting key will be the output of a regexp.ReplaceAll
|
||||
// operation.
|
||||
regexp?: {
|
||||
// Used to define the regular expression of a re.Compiler.
|
||||
source: string
|
||||
|
||||
// Used to define the target pattern of a ReplaceAll operation.
|
||||
target: string
|
||||
}
|
||||
transform?: {
|
||||
// Used to define the template to apply on the secret name.
|
||||
// `.value ` will specify the secret name in the template.
|
||||
template: string
|
||||
}
|
||||
}]
|
||||
|
||||
// SourceRef points to a store or generator
|
||||
// which contains secret values ready to use.
|
||||
// Use this in combination with Extract or Find pull values out of
|
||||
// a specific SecretStore.
|
||||
// When sourceRef points to a generator Extract or Find is not
|
||||
// supported.
|
||||
// The generator returns a static map of values
|
||||
sourceRef?: struct.MaxFields(1) & {
|
||||
// GeneratorRef points to a generator custom resource.
|
||||
generatorRef?: {
|
||||
// Specify the apiVersion of the generator resource
|
||||
apiVersion?: string | *"generators.external-secrets.io/v1alpha1"
|
||||
|
||||
// Specify the Kind of the resource, e.g. Password, ACRAccessToken
|
||||
// etc.
|
||||
kind: string
|
||||
|
||||
// Specify the name of the generator resource
|
||||
name: string
|
||||
}
|
||||
|
||||
// SecretStoreRef defines which SecretStore to fetch the
|
||||
// ExternalSecret data.
|
||||
storeRef?: {
|
||||
// Kind of the SecretStore resource (SecretStore or
|
||||
// ClusterSecretStore)
|
||||
// Defaults to `SecretStore`
|
||||
kind?: string
|
||||
|
||||
// Name of the SecretStore resource
|
||||
name: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// RefreshInterval is the amount of time before the values are
|
||||
// read again from the SecretStore provider
|
||||
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
|
||||
// May be set to zero to fetch and create it once. Defaults to 1h.
|
||||
refreshInterval?: string | *"1h"
|
||||
|
||||
// SecretStoreRef defines which SecretStore to fetch the
|
||||
// ExternalSecret data.
|
||||
secretStoreRef?: {
|
||||
// Kind of the SecretStore resource (SecretStore or
|
||||
// ClusterSecretStore)
|
||||
// Defaults to `SecretStore`
|
||||
kind?: string
|
||||
|
||||
// Name of the SecretStore resource
|
||||
name: string
|
||||
}
|
||||
|
||||
// ExternalSecretTarget defines the Kubernetes Secret to be
|
||||
// created
|
||||
// There can be only one target per ExternalSecret.
|
||||
target?: {
|
||||
// CreationPolicy defines rules on how to create the resulting
|
||||
// Secret
|
||||
// Defaults to 'Owner'
|
||||
creationPolicy?: "Owner" | "Orphan" | "Merge" | "None" | *"Owner"
|
||||
|
||||
// DeletionPolicy defines rules on how to delete the resulting
|
||||
// Secret
|
||||
// Defaults to 'Retain'
|
||||
deletionPolicy?: "Delete" | "Merge" | "Retain" | *"Retain"
|
||||
|
||||
// Immutable defines if the final secret will be immutable
|
||||
immutable?: bool
|
||||
|
||||
// Name defines the name of the Secret resource to be managed
|
||||
// This field is immutable
|
||||
// Defaults to the .metadata.name of the ExternalSecret resource
|
||||
name?: string
|
||||
|
||||
// Template defines a blueprint for the created Secret resource.
|
||||
template?: {
|
||||
data?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// EngineVersion specifies the template engine version
|
||||
// that should be used to compile/execute the
|
||||
// template specified in .data and .templateFrom[].
|
||||
engineVersion?: "v1" | "v2" | *"v2"
|
||||
mergePolicy?: "Replace" | "Merge" | *"Replace"
|
||||
|
||||
// ExternalSecretTemplateMetadata defines metadata fields for the
|
||||
// Secret blueprint.
|
||||
metadata?: {
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
templateFrom?: [...{
|
||||
configMap?: {
|
||||
items: [...{
|
||||
key: string
|
||||
templateAs?: "Values" | "KeysAndValues" | *"Values"
|
||||
}]
|
||||
name: string
|
||||
}
|
||||
literal?: string
|
||||
secret?: {
|
||||
items: [...{
|
||||
key: string
|
||||
templateAs?: "Values" | "KeysAndValues" | *"Values"
|
||||
}]
|
||||
name: string
|
||||
}
|
||||
target?: "Data" | "Annotations" | "Labels" | *"Data"
|
||||
}]
|
||||
type?: string
|
||||
}
|
||||
} | *{
|
||||
creationPolicy: "Owner"
|
||||
deletionPolicy: "Retain"
|
||||
}
|
||||
}
|
||||
|
||||
// The labels to select by to find the Namespaces to create the
|
||||
// ExternalSecrets in.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn,
|
||||
// the values array must be non-empty. If the operator is Exists
|
||||
// or DoesNotExist,
|
||||
// the values array must be empty. This array is replaced during a
|
||||
// strategic
|
||||
// merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels
|
||||
// map is equivalent to an element of matchExpressions, whose key
|
||||
// field is "key", the
|
||||
// operator is "In", and the values array contains only "value".
|
||||
// The requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Choose namespaces by name. This field is ORed with anything
|
||||
// that NamespaceSelector ends up choosing.
|
||||
namespaces?: [...string]
|
||||
|
||||
// The time in which the controller should reconcile its objects
|
||||
// and recheck namespaces for labels.
|
||||
refreshTime?: string
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,168 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-secrets-eso/prod-secrets-eso.gen.yaml
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"struct"
|
||||
)
|
||||
|
||||
// ExternalSecret is the Schema for the external-secrets API.
|
||||
#ExternalSecret: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "external-secrets.io/v1alpha1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "ExternalSecret"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// ExternalSecretSpec defines the desired state of ExternalSecret.
|
||||
spec!: #ExternalSecretSpec
|
||||
}
|
||||
|
||||
// ExternalSecretSpec defines the desired state of ExternalSecret.
|
||||
#ExternalSecretSpec: {
|
||||
// Data defines the connection between the Kubernetes Secret keys
|
||||
// and the Provider data
|
||||
data?: [...{
|
||||
// ExternalSecretDataRemoteRef defines Provider data location.
|
||||
remoteRef: {
|
||||
// Used to define a conversion Strategy
|
||||
conversionStrategy?: "Default" | "Unicode" | *"Default"
|
||||
|
||||
// Key is the key used in the Provider, mandatory
|
||||
key: string
|
||||
|
||||
// Used to select a specific property of the Provider value (if a
|
||||
// map), if supported
|
||||
property?: string
|
||||
|
||||
// Used to select a specific version of the Provider value, if
|
||||
// supported
|
||||
version?: string
|
||||
}
|
||||
secretKey: string
|
||||
}]
|
||||
|
||||
// DataFrom is used to fetch all properties from a specific
|
||||
// Provider data
|
||||
// If multiple entries are specified, the Secret keys are merged
|
||||
// in the specified order
|
||||
dataFrom?: [...{
|
||||
// Used to define a conversion Strategy
|
||||
conversionStrategy?: "Default" | "Unicode" | *"Default"
|
||||
|
||||
// Key is the key used in the Provider, mandatory
|
||||
key: string
|
||||
|
||||
// Used to select a specific property of the Provider value (if a
|
||||
// map), if supported
|
||||
property?: string
|
||||
|
||||
// Used to select a specific version of the Provider value, if
|
||||
// supported
|
||||
version?: string
|
||||
}]
|
||||
|
||||
// RefreshInterval is the amount of time before the values are
|
||||
// read again from the SecretStore provider
|
||||
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
|
||||
// May be set to zero to fetch and create it once. Defaults to 1h.
|
||||
refreshInterval?: string | *"1h"
|
||||
|
||||
// SecretStoreRef defines which SecretStore to fetch the
|
||||
// ExternalSecret data.
|
||||
secretStoreRef: {
|
||||
// Kind of the SecretStore resource (SecretStore or
|
||||
// ClusterSecretStore)
|
||||
// Defaults to `SecretStore`
|
||||
kind?: string
|
||||
|
||||
// Name of the SecretStore resource
|
||||
name: string
|
||||
}
|
||||
|
||||
// ExternalSecretTarget defines the Kubernetes Secret to be
|
||||
// created
|
||||
// There can be only one target per ExternalSecret.
|
||||
target: {
|
||||
// CreationPolicy defines rules on how to create the resulting
|
||||
// Secret
|
||||
// Defaults to 'Owner'
|
||||
creationPolicy?: "Owner" | "Merge" | "None" | *"Owner"
|
||||
|
||||
// Immutable defines if the final secret will be immutable
|
||||
immutable?: bool
|
||||
|
||||
// Name defines the name of the Secret resource to be managed
|
||||
// This field is immutable
|
||||
// Defaults to the .metadata.name of the ExternalSecret resource
|
||||
name?: string
|
||||
|
||||
// Template defines a blueprint for the created Secret resource.
|
||||
template?: {
|
||||
data?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// EngineVersion specifies the template engine version
|
||||
// that should be used to compile/execute the
|
||||
// template specified in .data and .templateFrom[].
|
||||
engineVersion?: "v1" | "v2" | *"v1"
|
||||
|
||||
// ExternalSecretTemplateMetadata defines metadata fields for the
|
||||
// Secret blueprint.
|
||||
metadata?: {
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
templateFrom?: [...struct.MaxFields(1) & {
|
||||
configMap?: {
|
||||
items: [...{
|
||||
key: string
|
||||
}]
|
||||
name: string
|
||||
}
|
||||
secret?: {
|
||||
items: [...{
|
||||
key: string
|
||||
}]
|
||||
name: string
|
||||
}
|
||||
}]
|
||||
type?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-secrets-eso/prod-secrets-eso.gen.yaml
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"struct"
|
||||
)
|
||||
|
||||
// ExternalSecret is the Schema for the external-secrets API.
|
||||
#ExternalSecret: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "external-secrets.io/v1beta1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "ExternalSecret"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// ExternalSecretSpec defines the desired state of ExternalSecret.
|
||||
spec!: #ExternalSecretSpec
|
||||
}
|
||||
|
||||
// ExternalSecretSpec defines the desired state of ExternalSecret.
|
||||
#ExternalSecretSpec: {
|
||||
// Data defines the connection between the Kubernetes Secret keys
|
||||
// and the Provider data
|
||||
data?: [...{
|
||||
// RemoteRef points to the remote secret and defines
|
||||
// which secret (version/property/..) to fetch.
|
||||
remoteRef: {
|
||||
// Used to define a conversion Strategy
|
||||
conversionStrategy?: "Default" | "Unicode" | *"Default"
|
||||
|
||||
// Used to define a decoding Strategy
|
||||
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
|
||||
|
||||
// Key is the key used in the Provider, mandatory
|
||||
key: string
|
||||
|
||||
// Policy for fetching tags/labels from provider secrets, possible
|
||||
// options are Fetch, None. Defaults to None
|
||||
metadataPolicy?: "None" | "Fetch" | *"None"
|
||||
|
||||
// Used to select a specific property of the Provider value (if a
|
||||
// map), if supported
|
||||
property?: string
|
||||
|
||||
// Used to select a specific version of the Provider value, if
|
||||
// supported
|
||||
version?: string
|
||||
}
|
||||
|
||||
// SecretKey defines the key in which the controller stores
|
||||
// the value. This is the key in the Kind=Secret
|
||||
secretKey: string
|
||||
|
||||
// SourceRef allows you to override the source
|
||||
// from which the value will pulled from.
|
||||
sourceRef?: struct.MaxFields(1) & {
|
||||
// GeneratorRef points to a generator custom resource.
|
||||
//
|
||||
//
|
||||
// Deprecated: The generatorRef is not implemented in .data[].
|
||||
// this will be removed with v1.
|
||||
generatorRef?: {
|
||||
// Specify the apiVersion of the generator resource
|
||||
apiVersion?: string | *"generators.external-secrets.io/v1alpha1"
|
||||
|
||||
// Specify the Kind of the resource, e.g. Password, ACRAccessToken
|
||||
// etc.
|
||||
kind: string
|
||||
|
||||
// Specify the name of the generator resource
|
||||
name: string
|
||||
}
|
||||
|
||||
// SecretStoreRef defines which SecretStore to fetch the
|
||||
// ExternalSecret data.
|
||||
storeRef?: {
|
||||
// Kind of the SecretStore resource (SecretStore or
|
||||
// ClusterSecretStore)
|
||||
// Defaults to `SecretStore`
|
||||
kind?: string
|
||||
|
||||
// Name of the SecretStore resource
|
||||
name: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// DataFrom is used to fetch all properties from a specific
|
||||
// Provider data
|
||||
// If multiple entries are specified, the Secret keys are merged
|
||||
// in the specified order
|
||||
dataFrom?: [...{
|
||||
// Used to extract multiple key/value pairs from one secret
|
||||
// Note: Extract does not support sourceRef.Generator or
|
||||
// sourceRef.GeneratorRef.
|
||||
extract?: {
|
||||
// Used to define a conversion Strategy
|
||||
conversionStrategy?: "Default" | "Unicode" | *"Default"
|
||||
|
||||
// Used to define a decoding Strategy
|
||||
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
|
||||
|
||||
// Key is the key used in the Provider, mandatory
|
||||
key: string
|
||||
|
||||
// Policy for fetching tags/labels from provider secrets, possible
|
||||
// options are Fetch, None. Defaults to None
|
||||
metadataPolicy?: "None" | "Fetch" | *"None"
|
||||
|
||||
// Used to select a specific property of the Provider value (if a
|
||||
// map), if supported
|
||||
property?: string
|
||||
|
||||
// Used to select a specific version of the Provider value, if
|
||||
// supported
|
||||
version?: string
|
||||
}
|
||||
|
||||
// Used to find secrets based on tags or regular expressions
|
||||
// Note: Find does not support sourceRef.Generator or
|
||||
// sourceRef.GeneratorRef.
|
||||
find?: {
|
||||
// Used to define a conversion Strategy
|
||||
conversionStrategy?: "Default" | "Unicode" | *"Default"
|
||||
|
||||
// Used to define a decoding Strategy
|
||||
decodingStrategy?: "Auto" | "Base64" | "Base64URL" | "None" | *"None"
|
||||
name?: {
|
||||
// Finds secrets base
|
||||
regexp?: string
|
||||
}
|
||||
|
||||
// A root path to start the find operations.
|
||||
path?: string
|
||||
|
||||
// Find secrets based on tags.
|
||||
tags?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Used to rewrite secret Keys after getting them from the secret
|
||||
// Provider
|
||||
// Multiple Rewrite operations can be provided. They are applied
|
||||
// in a layered order (first to last)
|
||||
rewrite?: [...{
|
||||
// Used to rewrite with regular expressions.
|
||||
// The resulting key will be the output of a regexp.ReplaceAll
|
||||
// operation.
|
||||
regexp?: {
|
||||
// Used to define the regular expression of a re.Compiler.
|
||||
source: string
|
||||
|
||||
// Used to define the target pattern of a ReplaceAll operation.
|
||||
target: string
|
||||
}
|
||||
transform?: {
|
||||
// Used to define the template to apply on the secret name.
|
||||
// `.value ` will specify the secret name in the template.
|
||||
template: string
|
||||
}
|
||||
}]
|
||||
|
||||
// SourceRef points to a store or generator
|
||||
// which contains secret values ready to use.
|
||||
// Use this in combination with Extract or Find pull values out of
|
||||
// a specific SecretStore.
|
||||
// When sourceRef points to a generator Extract or Find is not
|
||||
// supported.
|
||||
// The generator returns a static map of values
|
||||
sourceRef?: struct.MaxFields(1) & {
|
||||
// GeneratorRef points to a generator custom resource.
|
||||
generatorRef?: {
|
||||
// Specify the apiVersion of the generator resource
|
||||
apiVersion?: string | *"generators.external-secrets.io/v1alpha1"
|
||||
|
||||
// Specify the Kind of the resource, e.g. Password, ACRAccessToken
|
||||
// etc.
|
||||
kind: string
|
||||
|
||||
// Specify the name of the generator resource
|
||||
name: string
|
||||
}
|
||||
|
||||
// SecretStoreRef defines which SecretStore to fetch the
|
||||
// ExternalSecret data.
|
||||
storeRef?: {
|
||||
// Kind of the SecretStore resource (SecretStore or
|
||||
// ClusterSecretStore)
|
||||
// Defaults to `SecretStore`
|
||||
kind?: string
|
||||
|
||||
// Name of the SecretStore resource
|
||||
name: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// RefreshInterval is the amount of time before the values are
|
||||
// read again from the SecretStore provider
|
||||
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
|
||||
// May be set to zero to fetch and create it once. Defaults to 1h.
|
||||
refreshInterval?: string | *"1h"
|
||||
|
||||
// SecretStoreRef defines which SecretStore to fetch the
|
||||
// ExternalSecret data.
|
||||
secretStoreRef?: {
|
||||
// Kind of the SecretStore resource (SecretStore or
|
||||
// ClusterSecretStore)
|
||||
// Defaults to `SecretStore`
|
||||
kind?: string
|
||||
|
||||
// Name of the SecretStore resource
|
||||
name: string
|
||||
}
|
||||
|
||||
// ExternalSecretTarget defines the Kubernetes Secret to be
|
||||
// created
|
||||
// There can be only one target per ExternalSecret.
|
||||
target?: {
|
||||
// CreationPolicy defines rules on how to create the resulting
|
||||
// Secret
|
||||
// Defaults to 'Owner'
|
||||
creationPolicy?: "Owner" | "Orphan" | "Merge" | "None" | *"Owner"
|
||||
|
||||
// DeletionPolicy defines rules on how to delete the resulting
|
||||
// Secret
|
||||
// Defaults to 'Retain'
|
||||
deletionPolicy?: "Delete" | "Merge" | "Retain" | *"Retain"
|
||||
|
||||
// Immutable defines if the final secret will be immutable
|
||||
immutable?: bool
|
||||
|
||||
// Name defines the name of the Secret resource to be managed
|
||||
// This field is immutable
|
||||
// Defaults to the .metadata.name of the ExternalSecret resource
|
||||
name?: string
|
||||
|
||||
// Template defines a blueprint for the created Secret resource.
|
||||
template?: {
|
||||
data?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// EngineVersion specifies the template engine version
|
||||
// that should be used to compile/execute the
|
||||
// template specified in .data and .templateFrom[].
|
||||
engineVersion?: "v1" | "v2" | *"v2"
|
||||
mergePolicy?: "Replace" | "Merge" | *"Replace"
|
||||
|
||||
// ExternalSecretTemplateMetadata defines metadata fields for the
|
||||
// Secret blueprint.
|
||||
metadata?: {
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
templateFrom?: [...{
|
||||
configMap?: {
|
||||
items: [...{
|
||||
key: string
|
||||
templateAs?: "Values" | "KeysAndValues" | *"Values"
|
||||
}]
|
||||
name: string
|
||||
}
|
||||
literal?: string
|
||||
secret?: {
|
||||
items: [...{
|
||||
key: string
|
||||
templateAs?: "Values" | "KeysAndValues" | *"Values"
|
||||
}]
|
||||
name: string
|
||||
}
|
||||
target?: "Data" | "Annotations" | "Labels" | *"Data"
|
||||
}]
|
||||
type?: string
|
||||
}
|
||||
} | *{
|
||||
creationPolicy: "Owner"
|
||||
deletionPolicy: "Retain"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-secrets-eso/prod-secrets-eso.gen.yaml
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import "strings"
|
||||
|
||||
#PushSecret: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "external-secrets.io/v1alpha1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "PushSecret"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// PushSecretSpec configures the behavior of the PushSecret.
|
||||
spec!: #PushSecretSpec
|
||||
}
|
||||
|
||||
// PushSecretSpec configures the behavior of the PushSecret.
|
||||
#PushSecretSpec: {
|
||||
// Secret Data that should be pushed to providers
|
||||
data?: [...{
|
||||
// Match a given Secret Key to be pushed to the provider.
|
||||
match: {
|
||||
// Remote Refs to push to providers.
|
||||
remoteRef: {
|
||||
// Name of the property in the resulting secret
|
||||
property?: string
|
||||
|
||||
// Name of the resulting provider secret.
|
||||
remoteKey: string
|
||||
}
|
||||
|
||||
// Secret Key to be pushed
|
||||
secretKey?: string
|
||||
}
|
||||
|
||||
// Metadata is metadata attached to the secret.
|
||||
// The structure of metadata is provider specific, please look it
|
||||
// up in the provider documentation.
|
||||
metadata?: _
|
||||
}]
|
||||
|
||||
// Deletion Policy to handle Secrets in the provider. Possible
|
||||
// Values: "Delete/None". Defaults to "None".
|
||||
deletionPolicy?: "Delete" | "None" | *"None"
|
||||
|
||||
// The Interval to which External Secrets will try to push a
|
||||
// secret definition
|
||||
refreshInterval?: string
|
||||
secretStoreRefs: [...{
|
||||
// Kind of the SecretStore resource (SecretStore or
|
||||
// ClusterSecretStore)
|
||||
// Defaults to `SecretStore`
|
||||
kind?: string | *"SecretStore"
|
||||
|
||||
// Optionally, sync to secret stores with label selector
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn,
|
||||
// the values array must be non-empty. If the operator is Exists
|
||||
// or DoesNotExist,
|
||||
// the values array must be empty. This array is replaced during a
|
||||
// strategic
|
||||
// merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels
|
||||
// map is equivalent to an element of matchExpressions, whose key
|
||||
// field is "key", the
|
||||
// operator is "In", and the values array contains only "value".
|
||||
// The requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Optionally, sync to the SecretStore of the given name
|
||||
name?: string
|
||||
}]
|
||||
selector: {
|
||||
secret: {
|
||||
// Name of the Secret. The Secret must exist in the same namespace
|
||||
// as the PushSecret manifest.
|
||||
name: string
|
||||
}
|
||||
}
|
||||
|
||||
// Template defines a blueprint for the created Secret resource.
|
||||
template?: {
|
||||
data?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// EngineVersion specifies the template engine version
|
||||
// that should be used to compile/execute the
|
||||
// template specified in .data and .templateFrom[].
|
||||
engineVersion?: "v1" | "v2" | *"v2"
|
||||
mergePolicy?: "Replace" | "Merge" | *"Replace"
|
||||
|
||||
// ExternalSecretTemplateMetadata defines metadata fields for the
|
||||
// Secret blueprint.
|
||||
metadata?: {
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
templateFrom?: [...{
|
||||
configMap?: {
|
||||
items: [...{
|
||||
key: string
|
||||
templateAs?: "Values" | "KeysAndValues" | *"Values"
|
||||
}]
|
||||
name: string
|
||||
}
|
||||
literal?: string
|
||||
secret?: {
|
||||
items: [...{
|
||||
key: string
|
||||
templateAs?: "Values" | "KeysAndValues" | *"Values"
|
||||
}]
|
||||
name: string
|
||||
}
|
||||
target?: "Data" | "Annotations" | "Labels" | *"Data"
|
||||
}]
|
||||
type?: string
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,672 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"list"
|
||||
"struct"
|
||||
)
|
||||
|
||||
// Gateway represents an instance of a service-traffic handling
|
||||
// infrastructure
|
||||
// by binding Listeners to a set of IP addresses.
|
||||
#Gateway: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "gateway.networking.k8s.io/v1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "Gateway"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Spec defines the desired state of Gateway.
|
||||
spec!: #GatewaySpec
|
||||
}
|
||||
|
||||
// Spec defines the desired state of Gateway.
|
||||
#GatewaySpec: {
|
||||
// Addresses requested for this Gateway. This is optional and
|
||||
// behavior can
|
||||
// depend on the implementation. If a value is set in the spec and
|
||||
// the
|
||||
// requested address is invalid or unavailable, the implementation
|
||||
// MUST
|
||||
// indicate this in the associated entry in
|
||||
// GatewayStatus.Addresses.
|
||||
//
|
||||
//
|
||||
// The Addresses field represents a request for the address(es) on
|
||||
// the
|
||||
// "outside of the Gateway", that traffic bound for this Gateway
|
||||
// will use.
|
||||
// This could be the IP address or hostname of an external load
|
||||
// balancer or
|
||||
// other networking infrastructure, or some other address that
|
||||
// traffic will
|
||||
// be sent to.
|
||||
//
|
||||
//
|
||||
// If no Addresses are specified, the implementation MAY schedule
|
||||
// the
|
||||
// Gateway in an implementation-specific manner, assigning an
|
||||
// appropriate
|
||||
// set of Addresses.
|
||||
//
|
||||
//
|
||||
// The implementation MUST bind all Listeners to every
|
||||
// GatewayAddress that
|
||||
// it assigns to the Gateway and add a corresponding entry in
|
||||
// GatewayStatus.Addresses.
|
||||
//
|
||||
//
|
||||
// Support: Extended
|
||||
addresses?: list.MaxItems(16) & [...({
|
||||
type?: "IPAddress"
|
||||
value?: (_ | _) & {
|
||||
_
|
||||
}
|
||||
} | {
|
||||
type?: _
|
||||
}) & {
|
||||
// Type of the address.
|
||||
type?: strings.MaxRunes(253) & strings.MinRunes(1) & =~"^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$" | *"IPAddress"
|
||||
|
||||
// Value of the address. The validity of the values will depend
|
||||
// on the type and support by the controller.
|
||||
//
|
||||
//
|
||||
// Examples: `1.2.3.4`, `128::1`, `my-ip-address`.
|
||||
value: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
}]
|
||||
|
||||
// GatewayClassName used for this Gateway. This is the name of a
|
||||
// GatewayClass resource.
|
||||
gatewayClassName: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
|
||||
// Listeners associated with this Gateway. Listeners define
|
||||
// logical endpoints that are bound on this Gateway's addresses.
|
||||
// At least one Listener MUST be specified.
|
||||
//
|
||||
//
|
||||
// Each Listener in a set of Listeners (for example, in a single
|
||||
// Gateway)
|
||||
// MUST be _distinct_, in that a traffic flow MUST be able to be
|
||||
// assigned to
|
||||
// exactly one listener. (This section uses "set of Listeners"
|
||||
// rather than
|
||||
// "Listeners in a single Gateway" because implementations MAY
|
||||
// merge configuration
|
||||
// from multiple Gateways onto a single data plane, and these
|
||||
// rules _also_
|
||||
// apply in that case).
|
||||
//
|
||||
//
|
||||
// Practically, this means that each listener in a set MUST have a
|
||||
// unique
|
||||
// combination of Port, Protocol, and, if supported by the
|
||||
// protocol, Hostname.
|
||||
//
|
||||
//
|
||||
// Some combinations of port, protocol, and TLS settings are
|
||||
// considered
|
||||
// Core support and MUST be supported by implementations based on
|
||||
// their
|
||||
// targeted conformance profile:
|
||||
//
|
||||
//
|
||||
// HTTP Profile
|
||||
//
|
||||
//
|
||||
// 1. HTTPRoute, Port: 80, Protocol: HTTP
|
||||
// 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate,
|
||||
// TLS keypair provided
|
||||
//
|
||||
//
|
||||
// TLS Profile
|
||||
//
|
||||
//
|
||||
// 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough
|
||||
//
|
||||
//
|
||||
// "Distinct" Listeners have the following property:
|
||||
//
|
||||
//
|
||||
// The implementation can match inbound requests to a single
|
||||
// distinct
|
||||
// Listener. When multiple Listeners share values for fields (for
|
||||
// example, two Listeners with the same Port value), the
|
||||
// implementation
|
||||
// can match requests to only one of the Listeners using other
|
||||
// Listener fields.
|
||||
//
|
||||
//
|
||||
// For example, the following Listener scenarios are distinct:
|
||||
//
|
||||
//
|
||||
// 1. Multiple Listeners with the same Port that all use the
|
||||
// "HTTP"
|
||||
// Protocol that all have unique Hostname values.
|
||||
// 2. Multiple Listeners with the same Port that use either the
|
||||
// "HTTPS" or
|
||||
// "TLS" Protocol that all have unique Hostname values.
|
||||
// 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no
|
||||
// Listener
|
||||
// with the same Protocol has the same Port value.
|
||||
//
|
||||
//
|
||||
// Some fields in the Listener struct have possible values that
|
||||
// affect
|
||||
// whether the Listener is distinct. Hostname is particularly
|
||||
// relevant
|
||||
// for HTTP or HTTPS protocols.
|
||||
//
|
||||
//
|
||||
// When using the Hostname value to select between same-Port,
|
||||
// same-Protocol
|
||||
// Listeners, the Hostname value must be different on each
|
||||
// Listener for the
|
||||
// Listener to be distinct.
|
||||
//
|
||||
//
|
||||
// When the Listeners are distinct based on Hostname, inbound
|
||||
// request
|
||||
// hostnames MUST match from the most specific to least specific
|
||||
// Hostname
|
||||
// values to choose the correct Listener and its associated set of
|
||||
// Routes.
|
||||
//
|
||||
//
|
||||
// Exact matches must be processed before wildcard matches, and
|
||||
// wildcard
|
||||
// matches must be processed before fallback (empty Hostname
|
||||
// value)
|
||||
// matches. For example, `"foo.example.com"` takes precedence over
|
||||
// `"*.example.com"`, and `"*.example.com"` takes precedence over
|
||||
// `""`.
|
||||
//
|
||||
//
|
||||
// Additionally, if there are multiple wildcard entries, more
|
||||
// specific
|
||||
// wildcard entries must be processed before less specific
|
||||
// wildcard entries.
|
||||
// For example, `"*.foo.example.com"` takes precedence over
|
||||
// `"*.example.com"`.
|
||||
// The precise definition here is that the higher the number of
|
||||
// dots in the
|
||||
// hostname to the right of the wildcard character, the higher the
|
||||
// precedence.
|
||||
//
|
||||
//
|
||||
// The wildcard character will match any number of characters _and
|
||||
// dots_ to
|
||||
// the left, however, so `"*.example.com"` will match both
|
||||
// `"foo.bar.example.com"` _and_ `"bar.example.com"`.
|
||||
//
|
||||
//
|
||||
// If a set of Listeners contains Listeners that are not distinct,
|
||||
// then those
|
||||
// Listeners are Conflicted, and the implementation MUST set the
|
||||
// "Conflicted"
|
||||
// condition in the Listener Status to "True".
|
||||
//
|
||||
//
|
||||
// Implementations MAY choose to accept a Gateway with some
|
||||
// Conflicted
|
||||
// Listeners only if they only accept the partial Listener set
|
||||
// that contains
|
||||
// no Conflicted Listeners. To put this another way,
|
||||
// implementations may
|
||||
// accept a partial Listener set only if they throw out *all* the
|
||||
// conflicting
|
||||
// Listeners. No picking one of the conflicting listeners as the
|
||||
// winner.
|
||||
// This also means that the Gateway must have at least one
|
||||
// non-conflicting
|
||||
// Listener in this case, otherwise it violates the requirement
|
||||
// that at
|
||||
// least one Listener must be present.
|
||||
//
|
||||
//
|
||||
// The implementation MUST set a "ListenersNotValid" condition on
|
||||
// the
|
||||
// Gateway Status when the Gateway contains Conflicted Listeners
|
||||
// whether or
|
||||
// not they accept the Gateway. That Condition SHOULD clearly
|
||||
// indicate in the Message which Listeners are conflicted, and
|
||||
// which are
|
||||
// Accepted. Additionally, the Listener status for those listeners
|
||||
// SHOULD
|
||||
// indicate which Listeners are conflicted and not Accepted.
|
||||
//
|
||||
//
|
||||
// A Gateway's Listeners are considered "compatible" if:
|
||||
//
|
||||
//
|
||||
// 1. They are distinct.
|
||||
// 2. The implementation can serve them in compliance with the
|
||||
// Addresses
|
||||
// requirement that all Listeners are available on all assigned
|
||||
// addresses.
|
||||
//
|
||||
//
|
||||
// Compatible combinations in Extended support are expected to
|
||||
// vary across
|
||||
// implementations. A combination that is compatible for one
|
||||
// implementation
|
||||
// may not be compatible for another.
|
||||
//
|
||||
//
|
||||
// For example, an implementation that cannot serve both TCP and
|
||||
// UDP listeners
|
||||
// on the same address, or cannot mix HTTPS and generic TLS
|
||||
// listens on the same port
|
||||
// would not consider those cases compatible, even though they are
|
||||
// distinct.
|
||||
//
|
||||
//
|
||||
// Note that requests SHOULD match at most one Listener. For
|
||||
// example, if
|
||||
// Listeners are defined for "foo.example.com" and
|
||||
// "*.example.com", a
|
||||
// request to "foo.example.com" SHOULD only be routed using routes
|
||||
// attached
|
||||
// to the "foo.example.com" Listener (and not the "*.example.com"
|
||||
// Listener).
|
||||
// This concept is known as "Listener Isolation". Implementations
|
||||
// that do
|
||||
// not support Listener Isolation MUST clearly document this.
|
||||
//
|
||||
//
|
||||
// Implementations MAY merge separate Gateways onto a single set
|
||||
// of
|
||||
// Addresses if all Listeners across all Gateways are compatible.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
listeners: list.MaxItems(64) & [...{
|
||||
// AllowedRoutes defines the types of routes that MAY be attached
|
||||
// to a
|
||||
// Listener and the trusted namespaces where those Route resources
|
||||
// MAY be
|
||||
// present.
|
||||
//
|
||||
//
|
||||
// Although a client request may match multiple route rules, only
|
||||
// one rule
|
||||
// may ultimately receive the request. Matching precedence MUST be
|
||||
// determined in order of the following criteria:
|
||||
//
|
||||
//
|
||||
// * The most specific match as defined by the Route type.
|
||||
// * The oldest Route based on creation timestamp. For example, a
|
||||
// Route with
|
||||
// a creation timestamp of "2020-09-08 01:02:03" is given
|
||||
// precedence over
|
||||
// a Route with a creation timestamp of "2020-09-08 01:02:04".
|
||||
// * If everything else is equivalent, the Route appearing first
|
||||
// in
|
||||
// alphabetical order (namespace/name) should be given precedence.
|
||||
// For
|
||||
// example, foo/bar is given precedence over foo/baz.
|
||||
//
|
||||
//
|
||||
// All valid rules within a Route attached to this Listener should
|
||||
// be
|
||||
// implemented. Invalid Route rules can be ignored (sometimes that
|
||||
// will mean
|
||||
// the full Route). If a Route rule transitions from valid to
|
||||
// invalid,
|
||||
// support for that Route rule should be dropped to ensure
|
||||
// consistency. For
|
||||
// example, even if a filter specified by a Route rule is invalid,
|
||||
// the rest
|
||||
// of the rules within that Route should still be supported.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
allowedRoutes?: {
|
||||
// Kinds specifies the groups and kinds of Routes that are allowed
|
||||
// to bind
|
||||
// to this Gateway Listener. When unspecified or empty, the kinds
|
||||
// of Routes
|
||||
// selected are determined using the Listener protocol.
|
||||
//
|
||||
//
|
||||
// A RouteGroupKind MUST correspond to kinds of Routes that are
|
||||
// compatible
|
||||
// with the application protocol specified in the Listener's
|
||||
// Protocol field.
|
||||
// If an implementation does not support or recognize this
|
||||
// resource type, it
|
||||
// MUST set the "ResolvedRefs" condition to False for this
|
||||
// Listener with the
|
||||
// "InvalidRouteKinds" reason.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
kinds?: list.MaxItems(8) & [...{
|
||||
// Group is the group of the Route.
|
||||
group?: strings.MaxRunes(253) & =~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | *"gateway.networking.k8s.io"
|
||||
|
||||
// Kind is the kind of the Route.
|
||||
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
|
||||
}
|
||||
}]
|
||||
|
||||
// Namespaces indicates namespaces from which Routes may be
|
||||
// attached to this
|
||||
// Listener. This is restricted to the namespace of this Gateway
|
||||
// by default.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
namespaces?: {
|
||||
// From indicates where Routes will be selected for this Gateway.
|
||||
// Possible
|
||||
// values are:
|
||||
//
|
||||
//
|
||||
// * All: Routes in all namespaces may be used by this Gateway.
|
||||
// * Selector: Routes in namespaces selected by the selector may
|
||||
// be used by
|
||||
// this Gateway.
|
||||
// * Same: Only Routes in the same namespace may be used by this
|
||||
// Gateway.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
from?: "All" | "Selector" | "Same" | *"Same"
|
||||
|
||||
// Selector must be specified when From is set to "Selector". In
|
||||
// that case,
|
||||
// only Routes in Namespaces matching this Selector will be
|
||||
// selected by this
|
||||
// Gateway. This field is ignored for other values of "From".
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
selector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn,
|
||||
// the values array must be non-empty. If the operator is Exists
|
||||
// or DoesNotExist,
|
||||
// the values array must be empty. This array is replaced during a
|
||||
// strategic
|
||||
// merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels
|
||||
// map is equivalent to an element of matchExpressions, whose key
|
||||
// field is "key", the
|
||||
// operator is "In", and the values array contains only "value".
|
||||
// The requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
} | *{
|
||||
from: "Same"
|
||||
}
|
||||
} | *{
|
||||
namespaces: {
|
||||
from: "Same"
|
||||
}
|
||||
}
|
||||
|
||||
// Hostname specifies the virtual hostname to match for protocol
|
||||
// types that
|
||||
// define this concept. When unspecified, all hostnames are
|
||||
// matched. This
|
||||
// field is ignored for protocols that don't require hostname
|
||||
// based
|
||||
// matching.
|
||||
//
|
||||
//
|
||||
// Implementations MUST apply Hostname matching appropriately for
|
||||
// each of
|
||||
// the following protocols:
|
||||
//
|
||||
//
|
||||
// * TLS: The Listener Hostname MUST match the SNI.
|
||||
// * HTTP: The Listener Hostname MUST match the Host header of the
|
||||
// request.
|
||||
// * HTTPS: The Listener Hostname SHOULD match at both the TLS and
|
||||
// HTTP
|
||||
// protocol layers as described above. If an implementation does
|
||||
// not
|
||||
// ensure that both the SNI and Host header match the Listener
|
||||
// hostname,
|
||||
// it MUST clearly document that.
|
||||
//
|
||||
//
|
||||
// For HTTPRoute and TLSRoute resources, there is an interaction
|
||||
// with the
|
||||
// `spec.hostnames` array. When both listener and route specify
|
||||
// hostnames,
|
||||
// there MUST be an intersection between the values for a Route to
|
||||
// be
|
||||
// accepted. For more information, refer to the Route specific
|
||||
// Hostnames
|
||||
// documentation.
|
||||
//
|
||||
//
|
||||
// Hostnames that are prefixed with a wildcard label (`*.`) are
|
||||
// interpreted
|
||||
// as a suffix match. That means that a match for `*.example.com`
|
||||
// would match
|
||||
// both `test.example.com`, and `foo.test.example.com`, but not
|
||||
// `example.com`.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
hostname?: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
=~"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Name is the name of the Listener. This name MUST be unique
|
||||
// within a
|
||||
// Gateway.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
name: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Port is the network port. Multiple listeners may use the
|
||||
// same port, subject to the Listener compatibility rules.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
port: uint16 & >=1
|
||||
|
||||
// Protocol specifies the network protocol this listener expects
|
||||
// to receive.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
protocol: strings.MaxRunes(255) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$"
|
||||
}
|
||||
|
||||
// TLS is the TLS configuration for the Listener. This field is
|
||||
// required if
|
||||
// the Protocol field is "HTTPS" or "TLS". It is invalid to set
|
||||
// this field
|
||||
// if the Protocol field is "HTTP", "TCP", or "UDP".
|
||||
//
|
||||
//
|
||||
// The association of SNIs to Certificate defined in
|
||||
// GatewayTLSConfig is
|
||||
// defined based on the Hostname field for this listener.
|
||||
//
|
||||
//
|
||||
// The GatewayClass MUST use the longest matching SNI out of all
|
||||
// available certificates for any TLS handshake.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
tls?: {
|
||||
// CertificateRefs contains a series of references to Kubernetes
|
||||
// objects that
|
||||
// contains TLS certificates and private keys. These certificates
|
||||
// are used to
|
||||
// establish a TLS handshake for requests that match the hostname
|
||||
// of the
|
||||
// associated listener.
|
||||
//
|
||||
//
|
||||
// A single CertificateRef to a Kubernetes Secret has "Core"
|
||||
// support.
|
||||
// Implementations MAY choose to support attaching multiple
|
||||
// certificates to
|
||||
// a Listener, but this behavior is implementation-specific.
|
||||
//
|
||||
//
|
||||
// References to a resource in different namespace are invalid
|
||||
// UNLESS there
|
||||
// is a ReferenceGrant in the target namespace that allows the
|
||||
// certificate
|
||||
// to be attached. If a ReferenceGrant does not allow this
|
||||
// reference, the
|
||||
// "ResolvedRefs" condition MUST be set to False for this listener
|
||||
// with the
|
||||
// "RefNotPermitted" reason.
|
||||
//
|
||||
//
|
||||
// This field is required to have at least one element when the
|
||||
// mode is set
|
||||
// to "Terminate" (default) and is optional otherwise.
|
||||
//
|
||||
//
|
||||
// CertificateRefs can reference to standard Kubernetes resources,
|
||||
// i.e.
|
||||
// Secret, or implementation-specific custom resources.
|
||||
//
|
||||
//
|
||||
// Support: Core - A single reference to a Kubernetes Secret of
|
||||
// type kubernetes.io/tls
|
||||
//
|
||||
//
|
||||
// Support: Implementation-specific (More than one reference or
|
||||
// other resource types)
|
||||
certificateRefs?: list.MaxItems(64) & [...{
|
||||
// Group is the group of the referent. For example,
|
||||
// "gateway.networking.k8s.io".
|
||||
// When unspecified or empty string, core API group is inferred.
|
||||
group?: strings.MaxRunes(253) & =~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | *""
|
||||
|
||||
// Kind is kind of the referent. For example "Secret".
|
||||
kind?: strings.MaxRunes(63) & strings.MinRunes(1) & =~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$" | *"Secret"
|
||||
|
||||
// Name is the name of the referent.
|
||||
name: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
|
||||
// Namespace is the namespace of the referenced object. When
|
||||
// unspecified, the local
|
||||
// namespace is inferred.
|
||||
//
|
||||
//
|
||||
// Note that when a namespace different than the local namespace
|
||||
// is specified,
|
||||
// a ReferenceGrant object is required in the referent namespace
|
||||
// to allow that
|
||||
// namespace's owner to accept the reference. See the
|
||||
// ReferenceGrant
|
||||
// documentation for details.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
|
||||
}
|
||||
}]
|
||||
|
||||
// Mode defines the TLS behavior for the TLS session initiated by
|
||||
// the client.
|
||||
// There are two possible modes:
|
||||
//
|
||||
//
|
||||
// - Terminate: The TLS session between the downstream client and
|
||||
// the
|
||||
// Gateway is terminated at the Gateway. This mode requires
|
||||
// certificates
|
||||
// to be specified in some way, such as populating the
|
||||
// certificateRefs
|
||||
// field.
|
||||
// - Passthrough: The TLS session is NOT terminated by the
|
||||
// Gateway. This
|
||||
// implies that the Gateway can't decipher the TLS stream except
|
||||
// for
|
||||
// the ClientHello message of the TLS protocol. The
|
||||
// certificateRefs field
|
||||
// is ignored in this mode.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
mode?: "Terminate" | "Passthrough" | *"Terminate"
|
||||
|
||||
// Options are a list of key/value pairs to enable extended TLS
|
||||
// configuration for each implementation. For example, configuring
|
||||
// the
|
||||
// minimum TLS version or supported cipher suites.
|
||||
//
|
||||
//
|
||||
// A set of common keys MAY be defined by the API in the future.
|
||||
// To avoid
|
||||
// any ambiguity, implementation-specific definitions MUST use
|
||||
// domain-prefixed names, such as `example.com/my-custom-option`.
|
||||
// Un-prefixed names are reserved for key names defined by Gateway
|
||||
// API.
|
||||
//
|
||||
//
|
||||
// Support: Implementation-specific
|
||||
options?: struct.MaxFields(16) & {
|
||||
{
|
||||
[string]: strings.MaxRunes(4096) & strings.MinRunes(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}] & [_, ...]
|
||||
}
|
||||
@@ -0,0 +1,672 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"list"
|
||||
"struct"
|
||||
)
|
||||
|
||||
// Gateway represents an instance of a service-traffic handling
|
||||
// infrastructure
|
||||
// by binding Listeners to a set of IP addresses.
|
||||
#Gateway: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "gateway.networking.k8s.io/v1beta1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "Gateway"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Spec defines the desired state of Gateway.
|
||||
spec!: #GatewaySpec
|
||||
}
|
||||
|
||||
// Spec defines the desired state of Gateway.
|
||||
#GatewaySpec: {
|
||||
// Addresses requested for this Gateway. This is optional and
|
||||
// behavior can
|
||||
// depend on the implementation. If a value is set in the spec and
|
||||
// the
|
||||
// requested address is invalid or unavailable, the implementation
|
||||
// MUST
|
||||
// indicate this in the associated entry in
|
||||
// GatewayStatus.Addresses.
|
||||
//
|
||||
//
|
||||
// The Addresses field represents a request for the address(es) on
|
||||
// the
|
||||
// "outside of the Gateway", that traffic bound for this Gateway
|
||||
// will use.
|
||||
// This could be the IP address or hostname of an external load
|
||||
// balancer or
|
||||
// other networking infrastructure, or some other address that
|
||||
// traffic will
|
||||
// be sent to.
|
||||
//
|
||||
//
|
||||
// If no Addresses are specified, the implementation MAY schedule
|
||||
// the
|
||||
// Gateway in an implementation-specific manner, assigning an
|
||||
// appropriate
|
||||
// set of Addresses.
|
||||
//
|
||||
//
|
||||
// The implementation MUST bind all Listeners to every
|
||||
// GatewayAddress that
|
||||
// it assigns to the Gateway and add a corresponding entry in
|
||||
// GatewayStatus.Addresses.
|
||||
//
|
||||
//
|
||||
// Support: Extended
|
||||
addresses?: list.MaxItems(16) & [...({
|
||||
type?: "IPAddress"
|
||||
value?: (_ | _) & {
|
||||
_
|
||||
}
|
||||
} | {
|
||||
type?: _
|
||||
}) & {
|
||||
// Type of the address.
|
||||
type?: strings.MaxRunes(253) & strings.MinRunes(1) & =~"^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$" | *"IPAddress"
|
||||
|
||||
// Value of the address. The validity of the values will depend
|
||||
// on the type and support by the controller.
|
||||
//
|
||||
//
|
||||
// Examples: `1.2.3.4`, `128::1`, `my-ip-address`.
|
||||
value: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
}]
|
||||
|
||||
// GatewayClassName used for this Gateway. This is the name of a
|
||||
// GatewayClass resource.
|
||||
gatewayClassName: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
|
||||
// Listeners associated with this Gateway. Listeners define
|
||||
// logical endpoints that are bound on this Gateway's addresses.
|
||||
// At least one Listener MUST be specified.
|
||||
//
|
||||
//
|
||||
// Each Listener in a set of Listeners (for example, in a single
|
||||
// Gateway)
|
||||
// MUST be _distinct_, in that a traffic flow MUST be able to be
|
||||
// assigned to
|
||||
// exactly one listener. (This section uses "set of Listeners"
|
||||
// rather than
|
||||
// "Listeners in a single Gateway" because implementations MAY
|
||||
// merge configuration
|
||||
// from multiple Gateways onto a single data plane, and these
|
||||
// rules _also_
|
||||
// apply in that case).
|
||||
//
|
||||
//
|
||||
// Practically, this means that each listener in a set MUST have a
|
||||
// unique
|
||||
// combination of Port, Protocol, and, if supported by the
|
||||
// protocol, Hostname.
|
||||
//
|
||||
//
|
||||
// Some combinations of port, protocol, and TLS settings are
|
||||
// considered
|
||||
// Core support and MUST be supported by implementations based on
|
||||
// their
|
||||
// targeted conformance profile:
|
||||
//
|
||||
//
|
||||
// HTTP Profile
|
||||
//
|
||||
//
|
||||
// 1. HTTPRoute, Port: 80, Protocol: HTTP
|
||||
// 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate,
|
||||
// TLS keypair provided
|
||||
//
|
||||
//
|
||||
// TLS Profile
|
||||
//
|
||||
//
|
||||
// 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough
|
||||
//
|
||||
//
|
||||
// "Distinct" Listeners have the following property:
|
||||
//
|
||||
//
|
||||
// The implementation can match inbound requests to a single
|
||||
// distinct
|
||||
// Listener. When multiple Listeners share values for fields (for
|
||||
// example, two Listeners with the same Port value), the
|
||||
// implementation
|
||||
// can match requests to only one of the Listeners using other
|
||||
// Listener fields.
|
||||
//
|
||||
//
|
||||
// For example, the following Listener scenarios are distinct:
|
||||
//
|
||||
//
|
||||
// 1. Multiple Listeners with the same Port that all use the
|
||||
// "HTTP"
|
||||
// Protocol that all have unique Hostname values.
|
||||
// 2. Multiple Listeners with the same Port that use either the
|
||||
// "HTTPS" or
|
||||
// "TLS" Protocol that all have unique Hostname values.
|
||||
// 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no
|
||||
// Listener
|
||||
// with the same Protocol has the same Port value.
|
||||
//
|
||||
//
|
||||
// Some fields in the Listener struct have possible values that
|
||||
// affect
|
||||
// whether the Listener is distinct. Hostname is particularly
|
||||
// relevant
|
||||
// for HTTP or HTTPS protocols.
|
||||
//
|
||||
//
|
||||
// When using the Hostname value to select between same-Port,
|
||||
// same-Protocol
|
||||
// Listeners, the Hostname value must be different on each
|
||||
// Listener for the
|
||||
// Listener to be distinct.
|
||||
//
|
||||
//
|
||||
// When the Listeners are distinct based on Hostname, inbound
|
||||
// request
|
||||
// hostnames MUST match from the most specific to least specific
|
||||
// Hostname
|
||||
// values to choose the correct Listener and its associated set of
|
||||
// Routes.
|
||||
//
|
||||
//
|
||||
// Exact matches must be processed before wildcard matches, and
|
||||
// wildcard
|
||||
// matches must be processed before fallback (empty Hostname
|
||||
// value)
|
||||
// matches. For example, `"foo.example.com"` takes precedence over
|
||||
// `"*.example.com"`, and `"*.example.com"` takes precedence over
|
||||
// `""`.
|
||||
//
|
||||
//
|
||||
// Additionally, if there are multiple wildcard entries, more
|
||||
// specific
|
||||
// wildcard entries must be processed before less specific
|
||||
// wildcard entries.
|
||||
// For example, `"*.foo.example.com"` takes precedence over
|
||||
// `"*.example.com"`.
|
||||
// The precise definition here is that the higher the number of
|
||||
// dots in the
|
||||
// hostname to the right of the wildcard character, the higher the
|
||||
// precedence.
|
||||
//
|
||||
//
|
||||
// The wildcard character will match any number of characters _and
|
||||
// dots_ to
|
||||
// the left, however, so `"*.example.com"` will match both
|
||||
// `"foo.bar.example.com"` _and_ `"bar.example.com"`.
|
||||
//
|
||||
//
|
||||
// If a set of Listeners contains Listeners that are not distinct,
|
||||
// then those
|
||||
// Listeners are Conflicted, and the implementation MUST set the
|
||||
// "Conflicted"
|
||||
// condition in the Listener Status to "True".
|
||||
//
|
||||
//
|
||||
// Implementations MAY choose to accept a Gateway with some
|
||||
// Conflicted
|
||||
// Listeners only if they only accept the partial Listener set
|
||||
// that contains
|
||||
// no Conflicted Listeners. To put this another way,
|
||||
// implementations may
|
||||
// accept a partial Listener set only if they throw out *all* the
|
||||
// conflicting
|
||||
// Listeners. No picking one of the conflicting listeners as the
|
||||
// winner.
|
||||
// This also means that the Gateway must have at least one
|
||||
// non-conflicting
|
||||
// Listener in this case, otherwise it violates the requirement
|
||||
// that at
|
||||
// least one Listener must be present.
|
||||
//
|
||||
//
|
||||
// The implementation MUST set a "ListenersNotValid" condition on
|
||||
// the
|
||||
// Gateway Status when the Gateway contains Conflicted Listeners
|
||||
// whether or
|
||||
// not they accept the Gateway. That Condition SHOULD clearly
|
||||
// indicate in the Message which Listeners are conflicted, and
|
||||
// which are
|
||||
// Accepted. Additionally, the Listener status for those listeners
|
||||
// SHOULD
|
||||
// indicate which Listeners are conflicted and not Accepted.
|
||||
//
|
||||
//
|
||||
// A Gateway's Listeners are considered "compatible" if:
|
||||
//
|
||||
//
|
||||
// 1. They are distinct.
|
||||
// 2. The implementation can serve them in compliance with the
|
||||
// Addresses
|
||||
// requirement that all Listeners are available on all assigned
|
||||
// addresses.
|
||||
//
|
||||
//
|
||||
// Compatible combinations in Extended support are expected to
|
||||
// vary across
|
||||
// implementations. A combination that is compatible for one
|
||||
// implementation
|
||||
// may not be compatible for another.
|
||||
//
|
||||
//
|
||||
// For example, an implementation that cannot serve both TCP and
|
||||
// UDP listeners
|
||||
// on the same address, or cannot mix HTTPS and generic TLS
|
||||
// listens on the same port
|
||||
// would not consider those cases compatible, even though they are
|
||||
// distinct.
|
||||
//
|
||||
//
|
||||
// Note that requests SHOULD match at most one Listener. For
|
||||
// example, if
|
||||
// Listeners are defined for "foo.example.com" and
|
||||
// "*.example.com", a
|
||||
// request to "foo.example.com" SHOULD only be routed using routes
|
||||
// attached
|
||||
// to the "foo.example.com" Listener (and not the "*.example.com"
|
||||
// Listener).
|
||||
// This concept is known as "Listener Isolation". Implementations
|
||||
// that do
|
||||
// not support Listener Isolation MUST clearly document this.
|
||||
//
|
||||
//
|
||||
// Implementations MAY merge separate Gateways onto a single set
|
||||
// of
|
||||
// Addresses if all Listeners across all Gateways are compatible.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
listeners: list.MaxItems(64) & [...{
|
||||
// AllowedRoutes defines the types of routes that MAY be attached
|
||||
// to a
|
||||
// Listener and the trusted namespaces where those Route resources
|
||||
// MAY be
|
||||
// present.
|
||||
//
|
||||
//
|
||||
// Although a client request may match multiple route rules, only
|
||||
// one rule
|
||||
// may ultimately receive the request. Matching precedence MUST be
|
||||
// determined in order of the following criteria:
|
||||
//
|
||||
//
|
||||
// * The most specific match as defined by the Route type.
|
||||
// * The oldest Route based on creation timestamp. For example, a
|
||||
// Route with
|
||||
// a creation timestamp of "2020-09-08 01:02:03" is given
|
||||
// precedence over
|
||||
// a Route with a creation timestamp of "2020-09-08 01:02:04".
|
||||
// * If everything else is equivalent, the Route appearing first
|
||||
// in
|
||||
// alphabetical order (namespace/name) should be given precedence.
|
||||
// For
|
||||
// example, foo/bar is given precedence over foo/baz.
|
||||
//
|
||||
//
|
||||
// All valid rules within a Route attached to this Listener should
|
||||
// be
|
||||
// implemented. Invalid Route rules can be ignored (sometimes that
|
||||
// will mean
|
||||
// the full Route). If a Route rule transitions from valid to
|
||||
// invalid,
|
||||
// support for that Route rule should be dropped to ensure
|
||||
// consistency. For
|
||||
// example, even if a filter specified by a Route rule is invalid,
|
||||
// the rest
|
||||
// of the rules within that Route should still be supported.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
allowedRoutes?: {
|
||||
// Kinds specifies the groups and kinds of Routes that are allowed
|
||||
// to bind
|
||||
// to this Gateway Listener. When unspecified or empty, the kinds
|
||||
// of Routes
|
||||
// selected are determined using the Listener protocol.
|
||||
//
|
||||
//
|
||||
// A RouteGroupKind MUST correspond to kinds of Routes that are
|
||||
// compatible
|
||||
// with the application protocol specified in the Listener's
|
||||
// Protocol field.
|
||||
// If an implementation does not support or recognize this
|
||||
// resource type, it
|
||||
// MUST set the "ResolvedRefs" condition to False for this
|
||||
// Listener with the
|
||||
// "InvalidRouteKinds" reason.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
kinds?: list.MaxItems(8) & [...{
|
||||
// Group is the group of the Route.
|
||||
group?: strings.MaxRunes(253) & =~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | *"gateway.networking.k8s.io"
|
||||
|
||||
// Kind is the kind of the Route.
|
||||
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
|
||||
}
|
||||
}]
|
||||
|
||||
// Namespaces indicates namespaces from which Routes may be
|
||||
// attached to this
|
||||
// Listener. This is restricted to the namespace of this Gateway
|
||||
// by default.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
namespaces?: {
|
||||
// From indicates where Routes will be selected for this Gateway.
|
||||
// Possible
|
||||
// values are:
|
||||
//
|
||||
//
|
||||
// * All: Routes in all namespaces may be used by this Gateway.
|
||||
// * Selector: Routes in namespaces selected by the selector may
|
||||
// be used by
|
||||
// this Gateway.
|
||||
// * Same: Only Routes in the same namespace may be used by this
|
||||
// Gateway.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
from?: "All" | "Selector" | "Same" | *"Same"
|
||||
|
||||
// Selector must be specified when From is set to "Selector". In
|
||||
// that case,
|
||||
// only Routes in Namespaces matching this Selector will be
|
||||
// selected by this
|
||||
// Gateway. This field is ignored for other values of "From".
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
selector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn,
|
||||
// the values array must be non-empty. If the operator is Exists
|
||||
// or DoesNotExist,
|
||||
// the values array must be empty. This array is replaced during a
|
||||
// strategic
|
||||
// merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels
|
||||
// map is equivalent to an element of matchExpressions, whose key
|
||||
// field is "key", the
|
||||
// operator is "In", and the values array contains only "value".
|
||||
// The requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
} | *{
|
||||
from: "Same"
|
||||
}
|
||||
} | *{
|
||||
namespaces: {
|
||||
from: "Same"
|
||||
}
|
||||
}
|
||||
|
||||
// Hostname specifies the virtual hostname to match for protocol
|
||||
// types that
|
||||
// define this concept. When unspecified, all hostnames are
|
||||
// matched. This
|
||||
// field is ignored for protocols that don't require hostname
|
||||
// based
|
||||
// matching.
|
||||
//
|
||||
//
|
||||
// Implementations MUST apply Hostname matching appropriately for
|
||||
// each of
|
||||
// the following protocols:
|
||||
//
|
||||
//
|
||||
// * TLS: The Listener Hostname MUST match the SNI.
|
||||
// * HTTP: The Listener Hostname MUST match the Host header of the
|
||||
// request.
|
||||
// * HTTPS: The Listener Hostname SHOULD match at both the TLS and
|
||||
// HTTP
|
||||
// protocol layers as described above. If an implementation does
|
||||
// not
|
||||
// ensure that both the SNI and Host header match the Listener
|
||||
// hostname,
|
||||
// it MUST clearly document that.
|
||||
//
|
||||
//
|
||||
// For HTTPRoute and TLSRoute resources, there is an interaction
|
||||
// with the
|
||||
// `spec.hostnames` array. When both listener and route specify
|
||||
// hostnames,
|
||||
// there MUST be an intersection between the values for a Route to
|
||||
// be
|
||||
// accepted. For more information, refer to the Route specific
|
||||
// Hostnames
|
||||
// documentation.
|
||||
//
|
||||
//
|
||||
// Hostnames that are prefixed with a wildcard label (`*.`) are
|
||||
// interpreted
|
||||
// as a suffix match. That means that a match for `*.example.com`
|
||||
// would match
|
||||
// both `test.example.com`, and `foo.test.example.com`, but not
|
||||
// `example.com`.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
hostname?: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
=~"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Name is the name of the Listener. This name MUST be unique
|
||||
// within a
|
||||
// Gateway.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
name: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Port is the network port. Multiple listeners may use the
|
||||
// same port, subject to the Listener compatibility rules.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
port: uint16 & >=1
|
||||
|
||||
// Protocol specifies the network protocol this listener expects
|
||||
// to receive.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
protocol: strings.MaxRunes(255) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9]+$"
|
||||
}
|
||||
|
||||
// TLS is the TLS configuration for the Listener. This field is
|
||||
// required if
|
||||
// the Protocol field is "HTTPS" or "TLS". It is invalid to set
|
||||
// this field
|
||||
// if the Protocol field is "HTTP", "TCP", or "UDP".
|
||||
//
|
||||
//
|
||||
// The association of SNIs to Certificate defined in
|
||||
// GatewayTLSConfig is
|
||||
// defined based on the Hostname field for this listener.
|
||||
//
|
||||
//
|
||||
// The GatewayClass MUST use the longest matching SNI out of all
|
||||
// available certificates for any TLS handshake.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
tls?: {
|
||||
// CertificateRefs contains a series of references to Kubernetes
|
||||
// objects that
|
||||
// contains TLS certificates and private keys. These certificates
|
||||
// are used to
|
||||
// establish a TLS handshake for requests that match the hostname
|
||||
// of the
|
||||
// associated listener.
|
||||
//
|
||||
//
|
||||
// A single CertificateRef to a Kubernetes Secret has "Core"
|
||||
// support.
|
||||
// Implementations MAY choose to support attaching multiple
|
||||
// certificates to
|
||||
// a Listener, but this behavior is implementation-specific.
|
||||
//
|
||||
//
|
||||
// References to a resource in different namespace are invalid
|
||||
// UNLESS there
|
||||
// is a ReferenceGrant in the target namespace that allows the
|
||||
// certificate
|
||||
// to be attached. If a ReferenceGrant does not allow this
|
||||
// reference, the
|
||||
// "ResolvedRefs" condition MUST be set to False for this listener
|
||||
// with the
|
||||
// "RefNotPermitted" reason.
|
||||
//
|
||||
//
|
||||
// This field is required to have at least one element when the
|
||||
// mode is set
|
||||
// to "Terminate" (default) and is optional otherwise.
|
||||
//
|
||||
//
|
||||
// CertificateRefs can reference to standard Kubernetes resources,
|
||||
// i.e.
|
||||
// Secret, or implementation-specific custom resources.
|
||||
//
|
||||
//
|
||||
// Support: Core - A single reference to a Kubernetes Secret of
|
||||
// type kubernetes.io/tls
|
||||
//
|
||||
//
|
||||
// Support: Implementation-specific (More than one reference or
|
||||
// other resource types)
|
||||
certificateRefs?: list.MaxItems(64) & [...{
|
||||
// Group is the group of the referent. For example,
|
||||
// "gateway.networking.k8s.io".
|
||||
// When unspecified or empty string, core API group is inferred.
|
||||
group?: strings.MaxRunes(253) & =~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | *""
|
||||
|
||||
// Kind is kind of the referent. For example "Secret".
|
||||
kind?: strings.MaxRunes(63) & strings.MinRunes(1) & =~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$" | *"Secret"
|
||||
|
||||
// Name is the name of the referent.
|
||||
name: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
|
||||
// Namespace is the namespace of the referenced object. When
|
||||
// unspecified, the local
|
||||
// namespace is inferred.
|
||||
//
|
||||
//
|
||||
// Note that when a namespace different than the local namespace
|
||||
// is specified,
|
||||
// a ReferenceGrant object is required in the referent namespace
|
||||
// to allow that
|
||||
// namespace's owner to accept the reference. See the
|
||||
// ReferenceGrant
|
||||
// documentation for details.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
|
||||
}
|
||||
}]
|
||||
|
||||
// Mode defines the TLS behavior for the TLS session initiated by
|
||||
// the client.
|
||||
// There are two possible modes:
|
||||
//
|
||||
//
|
||||
// - Terminate: The TLS session between the downstream client and
|
||||
// the
|
||||
// Gateway is terminated at the Gateway. This mode requires
|
||||
// certificates
|
||||
// to be specified in some way, such as populating the
|
||||
// certificateRefs
|
||||
// field.
|
||||
// - Passthrough: The TLS session is NOT terminated by the
|
||||
// Gateway. This
|
||||
// implies that the Gateway can't decipher the TLS stream except
|
||||
// for
|
||||
// the ClientHello message of the TLS protocol. The
|
||||
// certificateRefs field
|
||||
// is ignored in this mode.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
mode?: "Terminate" | "Passthrough" | *"Terminate"
|
||||
|
||||
// Options are a list of key/value pairs to enable extended TLS
|
||||
// configuration for each implementation. For example, configuring
|
||||
// the
|
||||
// minimum TLS version or supported cipher suites.
|
||||
//
|
||||
//
|
||||
// A set of common keys MAY be defined by the API in the future.
|
||||
// To avoid
|
||||
// any ambiguity, implementation-specific definitions MUST use
|
||||
// domain-prefixed names, such as `example.com/my-custom-option`.
|
||||
// Un-prefixed names are reserved for key names defined by Gateway
|
||||
// API.
|
||||
//
|
||||
//
|
||||
// Support: Implementation-specific
|
||||
options?: struct.MaxFields(16) & {
|
||||
{
|
||||
[string]: strings.MaxRunes(4096) & strings.MinRunes(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}] & [_, ...]
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
|
||||
|
||||
package v1
|
||||
|
||||
import "strings"
|
||||
|
||||
// GatewayClass describes a class of Gateways available to the
|
||||
// user for creating
|
||||
// Gateway resources.
|
||||
//
|
||||
//
|
||||
// It is recommended that this resource be used as a template for
|
||||
// Gateways. This
|
||||
// means that a Gateway is based on the state of the GatewayClass
|
||||
// at the time it
|
||||
// was created and changes to the GatewayClass or associated
|
||||
// parameters are not
|
||||
// propagated down to existing Gateways. This recommendation is
|
||||
// intended to
|
||||
// limit the blast radius of changes to GatewayClass or associated
|
||||
// parameters.
|
||||
// If implementations choose to propagate GatewayClass changes to
|
||||
// existing
|
||||
// Gateways, that MUST be clearly documented by the
|
||||
// implementation.
|
||||
//
|
||||
//
|
||||
// Whenever one or more Gateways are using a GatewayClass,
|
||||
// implementations SHOULD
|
||||
// add the `gateway-exists-finalizer.gateway.networking.k8s.io`
|
||||
// finalizer on the
|
||||
// associated GatewayClass. This ensures that a GatewayClass
|
||||
// associated with a
|
||||
// Gateway is not deleted while in use.
|
||||
//
|
||||
//
|
||||
// GatewayClass is a Cluster level resource.
|
||||
#GatewayClass: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "gateway.networking.k8s.io/v1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "GatewayClass"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Spec defines the desired state of GatewayClass.
|
||||
spec!: #GatewayClassSpec
|
||||
}
|
||||
|
||||
// Spec defines the desired state of GatewayClass.
|
||||
#GatewayClassSpec: {
|
||||
// ControllerName is the name of the controller that is managing
|
||||
// Gateways of
|
||||
// this class. The value of this field MUST be a domain prefixed
|
||||
// path.
|
||||
//
|
||||
//
|
||||
// Example: "example.net/gateway-controller".
|
||||
//
|
||||
//
|
||||
// This field is not mutable and cannot be empty.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
controllerName: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$"
|
||||
}
|
||||
|
||||
// Description helps describe a GatewayClass with more details.
|
||||
description?: strings.MaxRunes(64)
|
||||
|
||||
// ParametersRef is a reference to a resource that contains the
|
||||
// configuration
|
||||
// parameters corresponding to the GatewayClass. This is optional
|
||||
// if the
|
||||
// controller does not require any additional configuration.
|
||||
//
|
||||
//
|
||||
// ParametersRef can reference a standard Kubernetes resource,
|
||||
// i.e. ConfigMap,
|
||||
// or an implementation-specific custom resource. The resource can
|
||||
// be
|
||||
// cluster-scoped or namespace-scoped.
|
||||
//
|
||||
//
|
||||
// If the referent cannot be found, the GatewayClass's
|
||||
// "InvalidParameters"
|
||||
// status condition will be true.
|
||||
//
|
||||
//
|
||||
// A Gateway for this GatewayClass may provide its own
|
||||
// `parametersRef`. When both are specified,
|
||||
// the merging behavior is implementation specific.
|
||||
// It is generally recommended that GatewayClass provides defaults
|
||||
// that can be overridden by a Gateway.
|
||||
//
|
||||
//
|
||||
// Support: Implementation-specific
|
||||
parametersRef?: {
|
||||
// Group is the group of the referent.
|
||||
group: strings.MaxRunes(253) & {
|
||||
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Kind is kind of the referent.
|
||||
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
|
||||
}
|
||||
|
||||
// Name is the name of the referent.
|
||||
name: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
|
||||
// Namespace is the namespace of the referent.
|
||||
// This field is required when referring to a Namespace-scoped
|
||||
// resource and
|
||||
// MUST be unset when referring to a Cluster-scoped resource.
|
||||
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
|
||||
|
||||
package v1beta1
|
||||
|
||||
import "strings"
|
||||
|
||||
// GatewayClass describes a class of Gateways available to the
|
||||
// user for creating
|
||||
// Gateway resources.
|
||||
//
|
||||
//
|
||||
// It is recommended that this resource be used as a template for
|
||||
// Gateways. This
|
||||
// means that a Gateway is based on the state of the GatewayClass
|
||||
// at the time it
|
||||
// was created and changes to the GatewayClass or associated
|
||||
// parameters are not
|
||||
// propagated down to existing Gateways. This recommendation is
|
||||
// intended to
|
||||
// limit the blast radius of changes to GatewayClass or associated
|
||||
// parameters.
|
||||
// If implementations choose to propagate GatewayClass changes to
|
||||
// existing
|
||||
// Gateways, that MUST be clearly documented by the
|
||||
// implementation.
|
||||
//
|
||||
//
|
||||
// Whenever one or more Gateways are using a GatewayClass,
|
||||
// implementations SHOULD
|
||||
// add the `gateway-exists-finalizer.gateway.networking.k8s.io`
|
||||
// finalizer on the
|
||||
// associated GatewayClass. This ensures that a GatewayClass
|
||||
// associated with a
|
||||
// Gateway is not deleted while in use.
|
||||
//
|
||||
//
|
||||
// GatewayClass is a Cluster level resource.
|
||||
#GatewayClass: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "gateway.networking.k8s.io/v1beta1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "GatewayClass"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Spec defines the desired state of GatewayClass.
|
||||
spec!: #GatewayClassSpec
|
||||
}
|
||||
|
||||
// Spec defines the desired state of GatewayClass.
|
||||
#GatewayClassSpec: {
|
||||
// ControllerName is the name of the controller that is managing
|
||||
// Gateways of
|
||||
// this class. The value of this field MUST be a domain prefixed
|
||||
// path.
|
||||
//
|
||||
//
|
||||
// Example: "example.net/gateway-controller".
|
||||
//
|
||||
//
|
||||
// This field is not mutable and cannot be empty.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
controllerName: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/[A-Za-z0-9\\/\\-._~%!$&'()*+,;=:]+$"
|
||||
}
|
||||
|
||||
// Description helps describe a GatewayClass with more details.
|
||||
description?: strings.MaxRunes(64)
|
||||
|
||||
// ParametersRef is a reference to a resource that contains the
|
||||
// configuration
|
||||
// parameters corresponding to the GatewayClass. This is optional
|
||||
// if the
|
||||
// controller does not require any additional configuration.
|
||||
//
|
||||
//
|
||||
// ParametersRef can reference a standard Kubernetes resource,
|
||||
// i.e. ConfigMap,
|
||||
// or an implementation-specific custom resource. The resource can
|
||||
// be
|
||||
// cluster-scoped or namespace-scoped.
|
||||
//
|
||||
//
|
||||
// If the referent cannot be found, the GatewayClass's
|
||||
// "InvalidParameters"
|
||||
// status condition will be true.
|
||||
//
|
||||
//
|
||||
// A Gateway for this GatewayClass may provide its own
|
||||
// `parametersRef`. When both are specified,
|
||||
// the merging behavior is implementation specific.
|
||||
// It is generally recommended that GatewayClass provides defaults
|
||||
// that can be overridden by a Gateway.
|
||||
//
|
||||
//
|
||||
// Support: Implementation-specific
|
||||
parametersRef?: {
|
||||
// Group is the group of the referent.
|
||||
group: strings.MaxRunes(253) & {
|
||||
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Kind is kind of the referent.
|
||||
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
|
||||
}
|
||||
|
||||
// Name is the name of the referent.
|
||||
name: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
|
||||
// Namespace is the namespace of the referent.
|
||||
// This field is required when referring to a Namespace-scoped
|
||||
// resource and
|
||||
// MUST be unset when referring to a Cluster-scoped resource.
|
||||
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,183 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"list"
|
||||
)
|
||||
|
||||
// ReferenceGrant identifies kinds of resources in other
|
||||
// namespaces that are
|
||||
// trusted to reference the specified kinds of resources in the
|
||||
// same namespace
|
||||
// as the policy.
|
||||
//
|
||||
//
|
||||
// Each ReferenceGrant can be used to represent a unique trust
|
||||
// relationship.
|
||||
// Additional Reference Grants can be used to add to the set of
|
||||
// trusted
|
||||
// sources of inbound references for the namespace they are
|
||||
// defined within.
|
||||
//
|
||||
//
|
||||
// A ReferenceGrant is required for all cross-namespace references
|
||||
// in Gateway API
|
||||
// (with the exception of cross-namespace Route-Gateway
|
||||
// attachment, which is
|
||||
// governed by the AllowedRoutes configuration on the Gateway, and
|
||||
// cross-namespace
|
||||
// Service ParentRefs on a "consumer" mesh Route, which defines
|
||||
// routing rules
|
||||
// applicable only to workloads in the Route namespace).
|
||||
// ReferenceGrants allowing
|
||||
// a reference from a Route to a Service are only applicable to
|
||||
// BackendRefs.
|
||||
//
|
||||
//
|
||||
// ReferenceGrant is a form of runtime verification allowing users
|
||||
// to assert
|
||||
// which cross-namespace object references are permitted.
|
||||
// Implementations that
|
||||
// support ReferenceGrant MUST NOT permit cross-namespace
|
||||
// references which have
|
||||
// no grant, and MUST respond to the removal of a grant by
|
||||
// revoking the access
|
||||
// that the grant allowed.
|
||||
#ReferenceGrant: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "gateway.networking.k8s.io/v1alpha2"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "ReferenceGrant"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Spec defines the desired state of ReferenceGrant.
|
||||
spec!: #ReferenceGrantSpec
|
||||
}
|
||||
|
||||
// Spec defines the desired state of ReferenceGrant.
|
||||
#ReferenceGrantSpec: {
|
||||
// From describes the trusted namespaces and kinds that can
|
||||
// reference the
|
||||
// resources described in "To". Each entry in this list MUST be
|
||||
// considered
|
||||
// to be an additional place that references can be valid from, or
|
||||
// to put
|
||||
// this another way, entries MUST be combined using OR.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
from: list.MaxItems(16) & [...{
|
||||
// Group is the group of the referent.
|
||||
// When empty, the Kubernetes core API group is inferred.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
group: strings.MaxRunes(253) & {
|
||||
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Kind is the kind of the referent. Although implementations may
|
||||
// support
|
||||
// additional resources, the following types are part of the
|
||||
// "Core"
|
||||
// support level for this field.
|
||||
//
|
||||
//
|
||||
// When used to permit a SecretObjectReference:
|
||||
//
|
||||
//
|
||||
// * Gateway
|
||||
//
|
||||
//
|
||||
// When used to permit a BackendObjectReference:
|
||||
//
|
||||
//
|
||||
// * GRPCRoute
|
||||
// * HTTPRoute
|
||||
// * TCPRoute
|
||||
// * TLSRoute
|
||||
// * UDPRoute
|
||||
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
|
||||
}
|
||||
|
||||
// Namespace is the namespace of the referent.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
namespace: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
|
||||
}
|
||||
}] & [_, ...]
|
||||
|
||||
// To describes the resources that may be referenced by the
|
||||
// resources
|
||||
// described in "From". Each entry in this list MUST be considered
|
||||
// to be an
|
||||
// additional place that references can be valid to, or to put
|
||||
// this another
|
||||
// way, entries MUST be combined using OR.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
to: list.MaxItems(16) & [...{
|
||||
// Group is the group of the referent.
|
||||
// When empty, the Kubernetes core API group is inferred.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
group: strings.MaxRunes(253) & {
|
||||
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Kind is the kind of the referent. Although implementations may
|
||||
// support
|
||||
// additional resources, the following types are part of the
|
||||
// "Core"
|
||||
// support level for this field:
|
||||
//
|
||||
//
|
||||
// * Secret when used to permit a SecretObjectReference
|
||||
// * Service when used to permit a BackendObjectReference
|
||||
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
|
||||
}
|
||||
|
||||
// Name is the name of the referent. When unspecified, this policy
|
||||
// refers to all resources of the specified Group and Kind in the
|
||||
// local
|
||||
// namespace.
|
||||
name?: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
}] & [_, ...]
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f deploy/clusters/aws1/components/gateway-api/gateway-api.gen.yaml
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"list"
|
||||
)
|
||||
|
||||
// ReferenceGrant identifies kinds of resources in other
|
||||
// namespaces that are
|
||||
// trusted to reference the specified kinds of resources in the
|
||||
// same namespace
|
||||
// as the policy.
|
||||
//
|
||||
//
|
||||
// Each ReferenceGrant can be used to represent a unique trust
|
||||
// relationship.
|
||||
// Additional Reference Grants can be used to add to the set of
|
||||
// trusted
|
||||
// sources of inbound references for the namespace they are
|
||||
// defined within.
|
||||
//
|
||||
//
|
||||
// All cross-namespace references in Gateway API (with the
|
||||
// exception of cross-namespace
|
||||
// Gateway-route attachment) require a ReferenceGrant.
|
||||
//
|
||||
//
|
||||
// ReferenceGrant is a form of runtime verification allowing users
|
||||
// to assert
|
||||
// which cross-namespace object references are permitted.
|
||||
// Implementations that
|
||||
// support ReferenceGrant MUST NOT permit cross-namespace
|
||||
// references which have
|
||||
// no grant, and MUST respond to the removal of a grant by
|
||||
// revoking the access
|
||||
// that the grant allowed.
|
||||
#ReferenceGrant: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "gateway.networking.k8s.io/v1beta1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "ReferenceGrant"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Spec defines the desired state of ReferenceGrant.
|
||||
spec!: #ReferenceGrantSpec
|
||||
}
|
||||
|
||||
// Spec defines the desired state of ReferenceGrant.
|
||||
#ReferenceGrantSpec: {
|
||||
// From describes the trusted namespaces and kinds that can
|
||||
// reference the
|
||||
// resources described in "To". Each entry in this list MUST be
|
||||
// considered
|
||||
// to be an additional place that references can be valid from, or
|
||||
// to put
|
||||
// this another way, entries MUST be combined using OR.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
from: list.MaxItems(16) & [...{
|
||||
// Group is the group of the referent.
|
||||
// When empty, the Kubernetes core API group is inferred.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
group: strings.MaxRunes(253) & {
|
||||
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Kind is the kind of the referent. Although implementations may
|
||||
// support
|
||||
// additional resources, the following types are part of the
|
||||
// "Core"
|
||||
// support level for this field.
|
||||
//
|
||||
//
|
||||
// When used to permit a SecretObjectReference:
|
||||
//
|
||||
//
|
||||
// * Gateway
|
||||
//
|
||||
//
|
||||
// When used to permit a BackendObjectReference:
|
||||
//
|
||||
//
|
||||
// * GRPCRoute
|
||||
// * HTTPRoute
|
||||
// * TCPRoute
|
||||
// * TLSRoute
|
||||
// * UDPRoute
|
||||
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
|
||||
}
|
||||
|
||||
// Namespace is the namespace of the referent.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
namespace: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
|
||||
}
|
||||
}] & [_, ...]
|
||||
|
||||
// To describes the resources that may be referenced by the
|
||||
// resources
|
||||
// described in "From". Each entry in this list MUST be considered
|
||||
// to be an
|
||||
// additional place that references can be valid to, or to put
|
||||
// this another
|
||||
// way, entries MUST be combined using OR.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
to: list.MaxItems(16) & [...{
|
||||
// Group is the group of the referent.
|
||||
// When empty, the Kubernetes core API group is inferred.
|
||||
//
|
||||
//
|
||||
// Support: Core
|
||||
group: strings.MaxRunes(253) & {
|
||||
=~"^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
|
||||
}
|
||||
|
||||
// Kind is the kind of the referent. Although implementations may
|
||||
// support
|
||||
// additional resources, the following types are part of the
|
||||
// "Core"
|
||||
// support level for this field:
|
||||
//
|
||||
//
|
||||
// * Secret when used to permit a SecretObjectReference
|
||||
// * Service when used to permit a BackendObjectReference
|
||||
kind: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
=~"^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$"
|
||||
}
|
||||
|
||||
// Name is the name of the referent. When unspecified, this policy
|
||||
// refers to all resources of the specified Group and Kind in the
|
||||
// local
|
||||
// namespace.
|
||||
name?: strings.MaxRunes(253) & strings.MinRunes(1)
|
||||
}] & [_, ...]
|
||||
}
|
||||
@@ -11,12 +11,16 @@ package v1alpha1
|
||||
// Metadata represents the holos component name
|
||||
metadata?: #ObjectMeta @go(Metadata)
|
||||
spec?: #BuildPlanSpec @go(Spec)
|
||||
platform?: {...} @go(Platform,map[string]any)
|
||||
}
|
||||
|
||||
#BuildPlanSpec: {
|
||||
disabled?: bool @go(Disabled)
|
||||
components?: #BuildPlanComponents @go(Components)
|
||||
|
||||
// DeployFiles keys represent file paths relative to the cluster deploy
|
||||
// directory. Map values represent the string encoded file contents. Used to
|
||||
// write the argocd Application, but may be used to render any file from CUE.
|
||||
deployFiles?: #FileContentMap @go(DeployFiles)
|
||||
}
|
||||
|
||||
#BuildPlanComponents: {
|
||||
|
||||
@@ -4,10 +4,34 @@
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// Platform represents a platform to manage. A Platform resource tells holos
|
||||
// which components to build. The primary use case is to specify the cluster
|
||||
// names, cluster types, and holos components to build.
|
||||
import "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
// Platform represents a platform to manage. A Platform resource informs holos
|
||||
// which components to build. The platform resource also acts as a container
|
||||
// for the platform model form values provided by the PlatformService. The
|
||||
// primary use case is to collect the cluster names, cluster types, platform
|
||||
// model, and holos components to build into one resource.
|
||||
#Platform: {
|
||||
#TypeMeta
|
||||
metadata?: #ObjectMeta @go(Metadata)
|
||||
metadata: #ObjectMeta @go(Metadata)
|
||||
spec: #PlatformSpec @go(Spec)
|
||||
}
|
||||
|
||||
// PlatformSpec represents the platform build plan specification.
|
||||
#PlatformSpec: {
|
||||
// Model represents the platform model holos gets from from the
|
||||
// holos.platform.v1alpha1.PlatformService.GetPlatform method and provides to
|
||||
// CUE using a tag.
|
||||
model: structpb.#Struct @go(Model)
|
||||
components: [...#PlatformSpecComponent] @go(Components,[]PlatformSpecComponent)
|
||||
}
|
||||
|
||||
// PlatformSpecComponent represents a component to build or render with flags to
|
||||
// pass, for example the cluster name.
|
||||
#PlatformSpecComponent: {
|
||||
// Path is the path of the component relative to the platform root.
|
||||
path: string @go(Path)
|
||||
|
||||
// Cluster is the cluster name to use when building the component.
|
||||
cluster: string @go(Cluster)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user