mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 08:44:58 +00:00
Compare commits
83 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53cb9ba7fb | ||
|
|
4cc139b372 | ||
|
|
8bc7804a9c | ||
|
|
a39807a858 | ||
|
|
5170650760 | ||
|
|
1d81b3c3b4 | ||
|
|
33970dafe8 | ||
|
|
faa46c54d8 | ||
|
|
42509a34cf | ||
|
|
ef369d4860 | ||
|
|
747ed3462a | ||
|
|
1fb1798f60 | ||
|
|
accf80200f | ||
|
|
4522ee1d4e | ||
|
|
313ebc6817 | ||
|
|
e0f439515f | ||
|
|
caa7560ab9 | ||
|
|
bbcf280da7 | ||
|
|
6d2daacb7b | ||
|
|
62f96a2d6c | ||
|
|
50f414d520 | ||
|
|
882f3894f3 | ||
|
|
30ddde7b49 | ||
|
|
5cced6fb51 | ||
|
|
a82ebf43b6 | ||
|
|
ebb6d6205a | ||
|
|
58950c469a | ||
|
|
0eebdaf0c7 | ||
|
|
54e2f28f4c | ||
|
|
d4d50ef12b | ||
|
|
075f2b16a4 | ||
|
|
6f8008a53c | ||
|
|
0618b52bae | ||
|
|
f1951c5db3 | ||
|
|
dad12acd8d | ||
|
|
a4503e076f | ||
|
|
09ddd339b8 | ||
|
|
bc94f4b6b8 | ||
|
|
564406f60f | ||
|
|
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 |
8
Dockerfile
Normal file
8
Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM quay.io/holos-run/debian:bullseye AS final
|
||||
USER root
|
||||
WORKDIR /app
|
||||
ADD bin bin
|
||||
RUN chown -R app: /app
|
||||
# Kubernetes requires the user to be numeric
|
||||
USER 8192
|
||||
ENTRYPOINT bin/holos server
|
||||
18
Makefile
18
Makefile
@@ -7,7 +7,7 @@ REPO_PATH=$(ORG_PATH)/$(PROJ)
|
||||
VERSION := $(shell cat version/embedded/major version/embedded/minor version/embedded/patch | xargs printf "%s.%s.%s")
|
||||
BIN_NAME := holos
|
||||
|
||||
DOCKER_REPO=quay.io/openinfrastructure/holos
|
||||
DOCKER_REPO=quay.io/holos-run/holos
|
||||
IMAGE_NAME=$(DOCKER_REPO)
|
||||
|
||||
$( shell mkdir -p bin)
|
||||
@@ -16,10 +16,12 @@ $( shell mkdir -p bin)
|
||||
export PATH := $(PWD)/internal/frontend/holos/node_modules/.bin:$(PATH)
|
||||
|
||||
GIT_COMMIT=$(shell git rev-parse HEAD)
|
||||
GIT_SUFFIX=$(shell test -n "`git status --porcelain`" && echo "-dirty" || echo "")
|
||||
GIT_DETAIL=$(shell git describe --tags HEAD)
|
||||
GIT_TREE_STATE=$(shell test -n "`git status --porcelain`" && echo "dirty" || echo "clean")
|
||||
BUILD_DATE=$(shell date -Iseconds)
|
||||
|
||||
LD_FLAGS="-w -X ${ORG_PATH}/${PROJ}/version.GitCommit=${GIT_COMMIT} -X ${ORG_PATH}/${PROJ}/version.GitTreeState=${GIT_TREE_STATE} -X ${ORG_PATH}/${PROJ}/version.BuildDate=${BUILD_DATE}"
|
||||
LD_FLAGS="-w -X ${ORG_PATH}/${PROJ}/version.GitDescribe=${GIT_DETAIL}${GIT_SUFFIX} -X ${ORG_PATH}/${PROJ}/version.GitCommit=${GIT_COMMIT} -X ${ORG_PATH}/${PROJ}/version.GitTreeState=${GIT_TREE_STATE} -X ${ORG_PATH}/${PROJ}/version.BuildDate=${BUILD_DATE}"
|
||||
|
||||
.PHONY: default
|
||||
default: test
|
||||
@@ -53,6 +55,7 @@ tidy: ## Tidy go module.
|
||||
.PHONY: fmt
|
||||
fmt: ## Format code.
|
||||
cd docs/examples && cue fmt ./...
|
||||
cd internal/generate/platforms && cue fmt ./...
|
||||
go fmt ./...
|
||||
|
||||
.PHONY: vet
|
||||
@@ -62,6 +65,8 @@ vet: ## Vet Go code.
|
||||
.PHONY: gencue
|
||||
gencue: ## Generate CUE definitions
|
||||
cd internal/generate/platforms && cue get go github.com/holos-run/holos/api/v1alpha1/...
|
||||
cd internal/generate/platforms && cue get go github.com/holos-run/holos/api/core/...
|
||||
cd internal/generate/platforms && cue get go github.com/holos-run/holos/api/meta/...
|
||||
|
||||
.PHONY: rmgen
|
||||
rmgen: ## Remove generated code
|
||||
@@ -121,11 +126,13 @@ tools: go-deps frontend-deps ## install tool dependencies
|
||||
|
||||
.PHONY: go-deps
|
||||
go-deps: ## tool versions pinned in tools.go
|
||||
go install cuelang.org/go/cmd/cue
|
||||
go install github.com/bufbuild/buf/cmd/buf
|
||||
go install github.com/fullstorydev/grpcurl/cmd/grpcurl
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go
|
||||
go install connectrpc.com/connect/cmd/protoc-gen-connect-go
|
||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
go install honnef.co/go/tools/cmd/staticcheck
|
||||
go install golang.org/x/tools/cmd/godoc
|
||||
# curl https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash
|
||||
|
||||
.PHONY: frontend-deps
|
||||
@@ -145,6 +152,11 @@ frontend: buf
|
||||
cd internal/frontend/holos && ng build
|
||||
touch internal/frontend/frontend.go
|
||||
|
||||
.PHONY: image
|
||||
image: build ## Docker image build
|
||||
docker build . -t ${DOCKER_REPO}:v$(shell ./bin/holos --version)
|
||||
docker push ${DOCKER_REPO}:v$(shell ./bin/holos --version)
|
||||
|
||||
.PHONY: help
|
||||
help: ## Display this help menu.
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
44
api/core/v1alpha2/apiobjects.go
Normal file
44
api/core/v1alpha2/apiobjects.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package v1alpha2
|
||||
|
||||
import "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
// Label is an arbitrary unique identifier internal to holos itself. The holos
|
||||
// cli is expected to never write a Label value to rendered output files,
|
||||
// therefore use a [Label] then the identifier must be unique and internal.
|
||||
// Defined as a type for clarity and type checking.
|
||||
//
|
||||
// A Label is useful to convert a CUE struct to a list, for example producing a list of [APIObject] resources from an [APIObjectMap]. A CUE struct using
|
||||
// Label keys is guaranteed to not lose data when rendering output because a
|
||||
// Label is expected to never be written to the final output.
|
||||
type Label string
|
||||
|
||||
// Kind is a kubernetes api object kind. Defined as a type for clarity and type checking.
|
||||
type Kind string
|
||||
|
||||
// APIObject represents the most basic generic form of a single kubernetes api
|
||||
// object. Represented as a JSON object internally for compatibility between
|
||||
// tools, for example loading from CUE.
|
||||
type APIObject structpb.Struct
|
||||
|
||||
// APIObjectMap represents the marshalled yaml representation of kubernetes api
|
||||
// objects. Do not produce an APIObjectMap directly, instead use [APIObjects]
|
||||
// to produce the marshalled yaml representation from CUE data, then provide the
|
||||
// result to [HolosComponent].
|
||||
type APIObjectMap map[Kind]map[Label]string
|
||||
|
||||
// APIObjects represents Kubernetes API objects defined directly from CUE code.
|
||||
// Useful to mix in resources to any kind of [HolosComponent], for example
|
||||
// adding an ExternalSecret resource to a [HelmChart].
|
||||
//
|
||||
// [Kind] must be the resource kind, e.g. Deployment or Service.
|
||||
//
|
||||
// [Label] is an arbitrary internal identifier to uniquely identify the resource
|
||||
// within the context of a `holos` command. Holos will never write the
|
||||
// intermediate label to rendered output.
|
||||
//
|
||||
// Refer to [HolosComponent] which accepts an [APIObjectMap] field provided by
|
||||
// [APIObjects].
|
||||
type APIObjects struct {
|
||||
APIObjects map[Kind]map[Label]APIObject `json:"apiObjects"`
|
||||
APIObjectMap APIObjectMap `json:"apiObjectMap"`
|
||||
}
|
||||
96
api/core/v1alpha2/buildplan.go
Normal file
96
api/core/v1alpha2/buildplan.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package v1alpha2
|
||||
|
||||
// FilePath represents a file path.
|
||||
type FilePath string
|
||||
|
||||
// FileContent represents file contents.
|
||||
type FileContent string
|
||||
|
||||
// FileContentMap represents a mapping of file paths to file contents. Paths
|
||||
// are relative to the `holos` output "deploy" directory, and may contain
|
||||
// sub-directories.
|
||||
type FileContentMap map[FilePath]FileContent
|
||||
|
||||
// BuildPlan represents a build plan for the holos cli to execute. The purpose
|
||||
// of a BuildPlan is to define one or more [HolosComponent] kinds. For example a
|
||||
// [HelmChart], [KustomizeBuild], or [KubernetesObjects].
|
||||
//
|
||||
// A BuildPlan usually has an additional empty [KubernetesObjects] for the
|
||||
// purpose of using the [HolosComponent] DeployFiles field to deploy an ArgoCD
|
||||
// or Flux gitops resource for the holos component.
|
||||
type BuildPlan struct {
|
||||
Kind string `json:"kind" cue:"\"BuildPlan\""`
|
||||
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha2\""`
|
||||
Spec BuildPlanSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// BuildPlanSpec represents the specification of the build plan.
|
||||
type BuildPlanSpec struct {
|
||||
// Disabled causes the holos cli to take no action over the [BuildPlan].
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
// Components represents multiple [HolosComponent] kinds to manage.
|
||||
Components BuildPlanComponents `json:"components,omitempty"`
|
||||
}
|
||||
|
||||
type BuildPlanComponents struct {
|
||||
Resources map[Label]KubernetesObjects `json:"resources,omitempty"`
|
||||
KubernetesObjectsList []KubernetesObjects `json:"kubernetesObjectsList,omitempty"`
|
||||
HelmChartList []HelmChart `json:"helmChartList,omitempty"`
|
||||
KustomizeBuildList []KustomizeBuild `json:"kustomizeBuildList,omitempty"`
|
||||
}
|
||||
|
||||
// HolosComponent defines the fields common to all holos component kinds. Every
|
||||
// holos component kind should embed HolosComponent.
|
||||
type HolosComponent struct {
|
||||
// Kind is a string value representing the resource this object represents.
|
||||
Kind string `json:"kind"`
|
||||
// APIVersion represents the versioned schema of this representation of an object.
|
||||
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha2\""`
|
||||
// Metadata represents data about the holos component such as the Name.
|
||||
Metadata Metadata `json:"metadata"`
|
||||
|
||||
// APIObjectMap holds the marshalled representation of api objects. Useful to
|
||||
// mix in resources to each HolosComponent type, for example adding an
|
||||
// ExternalSecret to a HelmChart HolosComponent. Refer to [APIObjects].
|
||||
APIObjectMap APIObjectMap `json:"apiObjectMap,omitempty"`
|
||||
|
||||
// DeployFiles represents file paths relative to the cluster deploy directory
|
||||
// with the value representing the file content. Intended for defining the
|
||||
// ArgoCD Application resource or Flux Kustomization resource from within CUE,
|
||||
// but may be used to render any file related to the build plan from CUE.
|
||||
DeployFiles FileContentMap `json:"deployFiles,omitempty"`
|
||||
|
||||
// Kustomize represents a kubectl kustomize build post-processing step.
|
||||
Kustomize `json:"kustomize,omitempty"`
|
||||
|
||||
// Skip causes holos to take no action regarding this component.
|
||||
Skip bool `json:"skip" cue:"bool | *false"`
|
||||
}
|
||||
|
||||
// Metadata represents data about the holos component such as the Name.
|
||||
type Metadata struct {
|
||||
// Name represents the name of the holos component.
|
||||
Name string `json:"name"`
|
||||
// Namespace is the primary namespace of the holos component. A holos
|
||||
// component may manage resources in multiple namespaces, in this case
|
||||
// consider setting the component namespace to default.
|
||||
//
|
||||
// This field is optional because not all resources require a namespace,
|
||||
// particularly CRD's and DeployFiles functionality.
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// Kustomize represents resources necessary to execute a kustomize build.
|
||||
// Intended for at least two use cases:
|
||||
//
|
||||
// 1. Process a [KustomizeBuild] [HolosComponent] which represents raw yaml
|
||||
// file resources in a holos component directory.
|
||||
// 2. Post process a [HelmChart] [HolosComponent] to inject istio, patch jobs,
|
||||
// add custom labels, etc...
|
||||
type Kustomize struct {
|
||||
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
|
||||
KustomizeFiles FileContentMap `json:"kustomizeFiles,omitempty"`
|
||||
// ResourcesFile is the file name used for api objects in kustomization.yaml
|
||||
ResourcesFile string `json:"resourcesFile,omitempty"`
|
||||
}
|
||||
11
api/core/v1alpha2/constants.go
Normal file
11
api/core/v1alpha2/constants.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package v1alpha2
|
||||
|
||||
const (
|
||||
APIVersion = "v1alpha2"
|
||||
BuildPlanKind = "BuildPlan"
|
||||
HelmChartKind = "HelmChart"
|
||||
// ChartDir is the directory name created in the holos component directory to cache a chart.
|
||||
ChartDir = "vendor"
|
||||
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
|
||||
ResourcesFile = "resources.yaml"
|
||||
)
|
||||
44
api/core/v1alpha2/core.go
Normal file
44
api/core/v1alpha2/core.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package v1alpha2
|
||||
|
||||
import "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
type PlatformMetadata struct {
|
||||
// Name represents the Platform name.
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// Kind is a string value representing the resource this object represents.
|
||||
Kind string `json:"kind" cue:"\"Platform\""`
|
||||
// APIVersion represents the versioned schema of this representation of an object.
|
||||
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha2\""`
|
||||
// Metadata represents data about the object such as the Name.
|
||||
Metadata PlatformMetadata `json:"metadata"`
|
||||
|
||||
// Spec represents the specification.
|
||||
Spec PlatformSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// PlatformSpec represents the specification of a Platform. Think of a platform
|
||||
// specification as a list of platform components to apply to a list of
|
||||
// kubernetes clusters combined with the user-specified Platform Model.
|
||||
type PlatformSpec struct {
|
||||
// Model represents the platform model holos gets from from the
|
||||
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
|
||||
Model structpb.Struct `json:"model"`
|
||||
// Components represents a list of holos components to manage.
|
||||
Components []PlatformSpecComponent `json:"components"`
|
||||
}
|
||||
|
||||
// PlatformSpecComponent represents a holos component to build or render.
|
||||
type PlatformSpecComponent struct {
|
||||
// Path is the path of the component relative to the platform root.
|
||||
Path string `json:"path"`
|
||||
// Cluster is the cluster name to provide when rendering the component.
|
||||
Cluster string `json:"cluster"`
|
||||
}
|
||||
24
api/core/v1alpha2/doc.go
Normal file
24
api/core/v1alpha2/doc.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// Package v1alpha2 contains the core API contract between the holos cli and CUE
|
||||
// configuration code. Platform designers, operators, and software developers
|
||||
// use this API to write configuration in CUE which `holos` loads. The overall
|
||||
// shape of the API defines imperative actions `holos` should carry out to
|
||||
// render the complete yaml that represents a Platform.
|
||||
//
|
||||
// [Platform] defines the complete configuration of a platform. With the holos
|
||||
// reference platform this takes the shape of one management cluster and at
|
||||
// least two workload cluster. Each cluster has multiple [HolosComponent]
|
||||
// resources applied to it.
|
||||
//
|
||||
// Each holos component path, e.g. `components/namespaces` produces exactly one
|
||||
// [BuildPlan] which in turn contains a set of [HolosComponent] kinds.
|
||||
//
|
||||
// The primary kinds of [HolosComponent] are:
|
||||
//
|
||||
// 1. [HelmChart] to render config from a helm chart.
|
||||
// 2. [KustomizeBuild] to render config from [Kustomize]
|
||||
// 3. [KubernetesObjects] to render [APIObjects] defined directly in CUE
|
||||
// configuration.
|
||||
//
|
||||
// Note that Holos operates as a data pipeline, so the output of a [HelmChart]
|
||||
// may be provided to [Kustomize] for post-processing.
|
||||
package v1alpha2
|
||||
38
api/core/v1alpha2/helm.go
Normal file
38
api/core/v1alpha2/helm.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package v1alpha2
|
||||
|
||||
// HelmChart represents a holos component which wraps around an upstream helm
|
||||
// chart. Holos orchestrates helm by providing values obtained from CUE,
|
||||
// renders the output using `helm template`, then post-processes the helm output
|
||||
// yaml using the general functionality provided by [HolosComponent], for
|
||||
// example [Kustomize] post-rendering and mixing in additional kubernetes api
|
||||
// objects.
|
||||
type HelmChart struct {
|
||||
HolosComponent `json:",inline"`
|
||||
Kind string `json:"kind" cue:"\"HelmChart\""`
|
||||
|
||||
// Chart represents a helm chart to manage.
|
||||
Chart Chart `json:"chart"`
|
||||
// ValuesContent represents the values.yaml file holos passes to the `helm
|
||||
// template` command.
|
||||
ValuesContent string `json:"valuesContent"`
|
||||
// EnableHooks enables helm hooks when executing the `helm template` command.
|
||||
EnableHooks bool `json:"enableHooks" cue:"bool | *false"`
|
||||
}
|
||||
|
||||
// Chart represents a helm chart.
|
||||
type Chart struct {
|
||||
// Name represents the chart name.
|
||||
Name string `json:"name"`
|
||||
// Version represents the chart version.
|
||||
Version string `json:"version"`
|
||||
// Release represents the chart release when executing helm template.
|
||||
Release string `json:"release"`
|
||||
// Repository represents the repository to fetch the chart from.
|
||||
Repository Repository `json:"repository,omitempty"`
|
||||
}
|
||||
|
||||
// Repository represents a helm chart repository.
|
||||
type Repository struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
10
api/core/v1alpha2/kubernetesobjects.go
Normal file
10
api/core/v1alpha2/kubernetesobjects.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package v1alpha2
|
||||
|
||||
const KubernetesObjectsKind = "KubernetesObjects"
|
||||
|
||||
// KubernetesObjects represents a [HolosComponent] composed of Kubernetes API
|
||||
// objects provided directly from CUE using [APIObjects].
|
||||
type KubernetesObjects struct {
|
||||
HolosComponent `json:",inline"`
|
||||
Kind string `json:"kind" cue:"\"KubernetesObjects\""`
|
||||
}
|
||||
8
api/core/v1alpha2/kustomizebuild.go
Normal file
8
api/core/v1alpha2/kustomizebuild.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package v1alpha2
|
||||
|
||||
// KustomizeBuild represents a [HolosComponent] that renders plain yaml files in
|
||||
// the holos component directory using `kubectl kustomize build`.
|
||||
type KustomizeBuild struct {
|
||||
HolosComponent `json:",inline"`
|
||||
Kind string `json:"kind" cue:"\"KustomizeBuild\""`
|
||||
}
|
||||
37
api/meta/v1alpha2/meta.go
Normal file
37
api/meta/v1alpha2/meta.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package v1alpha2
|
||||
|
||||
// TypeMeta describes an individual object in an API response or request with
|
||||
// strings representing the type of the object and its API schema version.
|
||||
// Structures that are versioned or persisted should inline TypeMeta.
|
||||
type TypeMeta struct {
|
||||
// Kind is a string value representing the resource this object represents.
|
||||
Kind string `json:"kind"`
|
||||
// APIVersion defines the versioned schema of this representation of an object.
|
||||
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha2\""`
|
||||
}
|
||||
|
||||
func (tm *TypeMeta) GetKind() string {
|
||||
return tm.Kind
|
||||
}
|
||||
|
||||
func (tm *TypeMeta) GetAPIVersion() string {
|
||||
return tm.APIVersion
|
||||
}
|
||||
|
||||
// Discriminator discriminates the kind of an api object.
|
||||
type Discriminator interface {
|
||||
// GetKind returns Kind.
|
||||
GetKind() string
|
||||
// GetAPIVersion returns APIVersion.
|
||||
GetAPIVersion() string
|
||||
}
|
||||
|
||||
// ObjectMeta represents metadata of a holos component object. The fields are a
|
||||
// copy of upstream kubernetes api machinery but are holos objects distinct from
|
||||
// kubernetes api objects.
|
||||
type ObjectMeta struct {
|
||||
// Name uniquely identifies the holos component instance and must be suitable as a file name.
|
||||
Name string `json:"name,omitempty"`
|
||||
// Namespace confines a holos component to a single namespace via kustomize if set.
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
@@ -16,6 +16,10 @@ type BuildPlan struct {
|
||||
type BuildPlanSpec struct {
|
||||
Disabled bool `json:"disabled,omitempty" yaml:"disabled,omitempty"`
|
||||
Components BuildPlanComponents `json:"components,omitempty" yaml:"components,omitempty"`
|
||||
// DeployFiles keys represent file paths relative to the cluster deploy
|
||||
// directory. Map values represent the string encoded file contents. Used to
|
||||
// write the argocd Application, but may be used to render any file from CUE.
|
||||
DeployFiles FileContentMap `json:"deployFiles,omitempty" yaml:"deployFiles,omitempty"`
|
||||
}
|
||||
|
||||
type BuildPlanComponents struct {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/holos-run/holos"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
@@ -121,6 +122,14 @@ func (hc *HelmChart) helm(ctx context.Context, r *Result, path holos.InstancePat
|
||||
}
|
||||
|
||||
// cacheChart stores a cached copy of Chart in the chart subdirectory of path.
|
||||
//
|
||||
// It is assumed that the only method responsible for writing to chartDir is
|
||||
// cacheChart itself.
|
||||
//
|
||||
// This relies on the atomicity of moving temporary directories into place on
|
||||
// the same filesystem via os.Rename. If a syscall.EEXIST error occurs during
|
||||
// renaming, it indicates that the cached chart already exists, which is an
|
||||
// expected scenario when this function is called concurrently.
|
||||
func cacheChart(ctx context.Context, path holos.InstancePath, chartDir string, chart Chart) error {
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
@@ -156,11 +165,16 @@ func cacheChart(ctx context.Context, path holos.InstancePath, chartDir string, c
|
||||
dst := filepath.Join(cachePath, item.Name())
|
||||
log.DebugContext(ctx, "rename", "src", src, "dst", dst)
|
||||
if err := os.Rename(src, dst); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not rename: %w", err))
|
||||
var linkErr *os.LinkError
|
||||
if errors.As(err, &linkErr) && errors.Is(linkErr.Err, syscall.EEXIST) {
|
||||
log.DebugContext(ctx, "cache already exists", "chart", chart.Name, "chart_version", chart.Version, "path", cachePath)
|
||||
} else {
|
||||
return errors.Wrap(fmt.Errorf("could not rename: %w", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.InfoContext(ctx, "cached", "chart", chart.Name, "version", chart.Version, "path", cachePath)
|
||||
log.InfoContext(ctx, "cached", "chart", chart.Name, "chart_version", chart.Version, "path", cachePath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -40,11 +44,6 @@ func (r *Result) KustomizationFilename(writeTo string, cluster string) string {
|
||||
return filepath.Join(writeTo, "clusters", cluster, "holos", "components", r.Metadata.Name+"-kustomization.gen.yaml")
|
||||
}
|
||||
|
||||
// KustomizationContent returns the kustomization file contents to write.
|
||||
func (r *Result) KustomizationContent() string {
|
||||
return r.KsContent
|
||||
}
|
||||
|
||||
// AccumulatedOutput returns the accumulated rendered output.
|
||||
func (r *Result) AccumulatedOutput() string {
|
||||
return r.accumulatedOutput
|
||||
@@ -133,6 +132,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 +155,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)
|
||||
|
||||
@@ -10,7 +10,7 @@ func (tm *TypeMeta) GetKind() string {
|
||||
}
|
||||
|
||||
func (tm *TypeMeta) GetAPIVersion() string {
|
||||
return tm.Kind
|
||||
return tm.APIVersion
|
||||
}
|
||||
|
||||
// Discriminator is an interface to discriminate the kind api object.
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
module: "github.com/holos-run/holos/docs/examples"
|
||||
language: version: "v0.9.2"
|
||||
|
||||
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 @@
|
||||
{}
|
||||
@@ -151,7 +151,7 @@ let OBJECTS = #APIObjects & {
|
||||
loopback: #Service & {
|
||||
_description: LoopbackDescription
|
||||
metadata: LoopbackMetaName
|
||||
spec: selector: LoopbackLabels
|
||||
spec: selector: LoopbackLabels
|
||||
spec: ports: [{port: 80, name: "http"}, {port: 443, name: "https"}]
|
||||
}
|
||||
}
|
||||
|
||||
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 .
|
||||
```
|
||||
30
docs/runbooks/namespace.md
Normal file
30
docs/runbooks/namespace.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Namespaces
|
||||
|
||||
Holos follows the [Namespace Sameness - Sig Multicluster Position][1]. A
|
||||
namespace is the same on all clusters within the scope of a platform.
|
||||
|
||||
Namespaces are also security boundaries for role based access control. As such,
|
||||
permission to read a secret in a namespace means the secret is readable on all
|
||||
clusters in the platform.
|
||||
|
||||
When adding a component to a platform, create a namespace using the following
|
||||
process. This ensures a namespace scoped `SecretStore` is created to sync
|
||||
`ExternalSecret` resources from the management cluster.
|
||||
|
||||
1. Add a new project to the `_Projects` struct in `platform.cue`.
|
||||
2. Add the namespace to the `spec.namespaces` field of the project.
|
||||
3. Render the platform
|
||||
4. Apply the `namespaces` component to the management cluster
|
||||
5. Apply the `eso-creds-manager` component to the management cluster to create the `eso-reader` ksa for the namespace `SecretStore`
|
||||
6. Get a timestamp: `STAMP="$(date +%s)"`
|
||||
7. Run the job to populate ecr creds: `kubectl create job -n holos-system --from=cronjob/ecr-creds-manager ecr-creds-manager-$STAMP`
|
||||
8. Wait for the job to complete: `kubectl -n holos-system logs -l job-name=ecr-creds-manager-$STAMP -f`
|
||||
9. Apply the `namespaces` component to the workload clusters
|
||||
10. On the workload cluster, run the job to fetch the eso-reader creds: `kubectl create job -n holos-system --from=cronjob/eso-creds-refresher eso-creds-refresher-${STAMP}`
|
||||
11. Wait for the job to complete: `kubectl -n holos-system logs -l job-name=eso-creds-refresher-${STAMP}`
|
||||
12. Apply the secretstores component to the workload cluster.
|
||||
13. Apply any other cluster specific components which were modified by the `holos render platform ./platform` command.
|
||||
|
||||
Your namespace is created and you have the ability to create secrets in the management cluster and pull them using ExternalSecret resources. (edited)
|
||||
|
||||
[1]: https://github.com/kubernetes/community/blob/dd4c8b704ef1c9c3bfd928c6fa9234276d61ad18/sig-multicluster/namespace-sameness-position-statement.md
|
||||
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']` |
|
||||
28
go.mod
28
go.mod
@@ -8,7 +8,7 @@ require (
|
||||
connectrpc.com/grpcreflect v1.2.0
|
||||
connectrpc.com/otelconnect v0.7.0
|
||||
connectrpc.com/validate v0.1.0
|
||||
cuelang.org/go v0.8.0
|
||||
cuelang.org/go v0.9.2
|
||||
entgo.io/ent v0.13.1
|
||||
github.com/bufbuild/buf v1.30.1
|
||||
github.com/choria-io/machine-room v0.0.0-20240417064836-c604da2f005e
|
||||
@@ -29,8 +29,9 @@ require (
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/tools v0.20.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/tools v0.22.0
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa
|
||||
google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002
|
||||
honnef.co/go/tools v0.4.7
|
||||
@@ -44,9 +45,8 @@ require (
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect
|
||||
cloud.google.com/go/compute v1.23.3 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240314152124-224736b49f2e // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 // indirect
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
@@ -215,6 +215,7 @@ require (
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
|
||||
github.com/tetratelabs/wazero v1.6.0 // indirect
|
||||
github.com/tidwall/gjson v1.17.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
@@ -225,6 +226,7 @@ require (
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5 // indirect
|
||||
github.com/yashtewari/glob-intersection v0.2.0 // indirect
|
||||
github.com/yuin/goldmark v1.4.13 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
@@ -236,17 +238,15 @@ require (
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.18.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/term v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/oauth2 v0.20.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/term v0.21.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa // indirect
|
||||
google.golang.org/grpc v1.62.1 // indirect
|
||||
|
||||
51
go.sum
51
go.sum
@@ -23,10 +23,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
|
||||
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
@@ -46,10 +44,10 @@ connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY
|
||||
connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc=
|
||||
connectrpc.com/validate v0.1.0 h1:r55jirxMK7HO/xZwVHj3w2XkVFarsUM77ZDy367NtH4=
|
||||
connectrpc.com/validate v0.1.0/go.mod h1:GU47c9/x/gd+u9wRSPkrQOP46gx2rMN+Wo37EHgI3Ow=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240314152124-224736b49f2e h1:GwCVItFUPxwdsEYnlUcJ6PJxOjTeFFCKOh6QWg4oAzQ=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240314152124-224736b49f2e/go.mod h1:ApHceQLLwcOkCEXM1+DyCXTHEJhNGDpJ2kmV6axsx24=
|
||||
cuelang.org/go v0.8.0 h1:fO1XPe/SUGtc7dhnGnTPbpIDoQm/XxhDtoSF7jzO01c=
|
||||
cuelang.org/go v0.8.0/go.mod h1:CoDbYolfMms4BhWUlhD+t5ORnihR7wvjcfgyO9lL5FI=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 h1:BnG6pr9TTr6CYlrJznYUDj6V7xldD1W+1iXPum0wT/w=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2/go.mod h1:pK23AUVXuNzzTpfMCA06sxZGeVQ/75FdVtW249de9Uo=
|
||||
cuelang.org/go v0.9.2 h1:pfNiry2PdRBr02G/aKm5k2vhzmqbAOoaB4WurmEbWvs=
|
||||
cuelang.org/go v0.9.2/go.mod h1:qpAYsLOf7gTM1YdEg6cxh553uZ4q9ZDWlPbtZr9q1Wk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
entgo.io/ent v0.13.1 h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE=
|
||||
entgo.io/ent v0.13.1/go.mod h1:qCEmo+biw3ccBn9OyL4ZK5dfpwg++l1Gxwac5B1206A=
|
||||
@@ -638,6 +636,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
|
||||
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||
github.com/tetratelabs/wazero v1.6.0 h1:z0H1iikCdP8t+q341xqepY4EWvHEw8Es7tlqiVzlP3g=
|
||||
github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
|
||||
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
||||
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
@@ -670,6 +670,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
@@ -719,8 +720,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -758,8 +759,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -793,16 +794,16 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
|
||||
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -868,16 +869,16 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -885,12 +886,12 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -942,8 +943,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -970,8 +971,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
// Package v1alpha1 is the unstable version of the core api.
|
||||
package v1alpha1
|
||||
@@ -10,26 +10,30 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"cuelang.org/go/cue/build"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/load"
|
||||
"github.com/holos-run/holos/api/core/v1alpha2"
|
||||
"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"
|
||||
"github.com/holos-run/holos/internal/render"
|
||||
)
|
||||
|
||||
const (
|
||||
KubernetesObjects = v1alpha1.KubernetesObjectsKind
|
||||
KubernetesObjects = v1alpha2.KubernetesObjectsKind
|
||||
// Helm is the value of the kind field of holos build output indicating helm
|
||||
// values and helm command information.
|
||||
Helm = v1alpha1.HelmChartKind
|
||||
Helm = v1alpha2.HelmChartKind
|
||||
// Skip is the value when the instance should be skipped
|
||||
Skip = "Skip"
|
||||
// KustomizeBuild is the value of the kind field of cue output indicating holos should process the component using kustomize build to render output.
|
||||
// KustomizeBuild is the value of the kind field of cue output indicating
|
||||
// holos should process the component using kustomize build to render output.
|
||||
KustomizeBuild = v1alpha1.KustomizeBuildKind
|
||||
)
|
||||
|
||||
@@ -45,6 +49,43 @@ type Builder struct {
|
||||
cfg config
|
||||
}
|
||||
|
||||
type buildPlanWrapper struct {
|
||||
buildPlan *v1alpha2.BuildPlan
|
||||
}
|
||||
|
||||
func (b *buildPlanWrapper) validate() error {
|
||||
if b == nil {
|
||||
return fmt.Errorf("invalid BuildPlan: is nil")
|
||||
}
|
||||
bp := b.buildPlan
|
||||
if bp == nil {
|
||||
return fmt.Errorf("invalid BuildPlan: is nil")
|
||||
}
|
||||
errs := make([]string, 0, 2)
|
||||
if bp.Kind != v1alpha2.BuildPlanKind {
|
||||
errs = append(errs, fmt.Sprintf("kind invalid: want: %s have: %s", v1alpha1.BuildPlanKind, bp.Kind))
|
||||
}
|
||||
if bp.APIVersion != v1alpha2.APIVersion {
|
||||
errs = append(errs, fmt.Sprintf("apiVersion invalid: want: %s have: %s", v1alpha2.APIVersion, bp.APIVersion))
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("invalid BuildPlan: " + strings.Join(errs, ", "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *buildPlanWrapper) resultCapacity() (count int) {
|
||||
if b == nil {
|
||||
return 0
|
||||
}
|
||||
bp := b.buildPlan
|
||||
count = len(bp.Spec.Components.HelmChartList) +
|
||||
len(bp.Spec.Components.KubernetesObjectsList) +
|
||||
len(bp.Spec.Components.KustomizeBuildList) +
|
||||
len(bp.Spec.Components.Resources)
|
||||
return count
|
||||
}
|
||||
|
||||
// New returns a new *Builder configured by opts Option.
|
||||
func New(opts ...Option) *Builder {
|
||||
var cfg config
|
||||
@@ -91,7 +132,18 @@ func (b *Builder) Instances(ctx context.Context, cfg *client.Config) ([]*build.I
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
|
||||
cueConfig.Tags = append(cueConfig.Tags, "platform_config="+string(data))
|
||||
if b.Cluster() != "" {
|
||||
cueConfig.Tags = append(cueConfig.Tags, "cluster="+b.Cluster())
|
||||
}
|
||||
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cueConfig.Tags))
|
||||
|
||||
prefix := []string{"cue", "export", "--out", "yaml"}
|
||||
for _, tag := range cueConfig.Tags {
|
||||
prefix = append(prefix, "-t", fmt.Sprintf("'%s'", tag))
|
||||
}
|
||||
|
||||
// Make args relative to the module directory
|
||||
args := make([]string, len(b.cfg.args))
|
||||
@@ -106,27 +158,24 @@ func (b *Builder) Instances(ctx context.Context, cfg *client.Config) ([]*build.I
|
||||
}
|
||||
relPath = "./" + relPath
|
||||
args[idx] = relPath
|
||||
equiv := fmt.Sprintf("cue export --out yaml -t cluster=%v %v", b.Cluster(), relPath)
|
||||
log.Debug("cue: equivalent command: " + equiv)
|
||||
}
|
||||
|
||||
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
|
||||
if b.Cluster() != "" {
|
||||
cueConfig.Tags = append(cueConfig.Tags, "cluster="+b.Cluster())
|
||||
equiv := make([]string, len(prefix), 1+len(prefix))
|
||||
copy(equiv, prefix)
|
||||
equiv = append(equiv, relPath)
|
||||
log.Debug(strings.Join(equiv, " "), "comment", "cue equivalent command")
|
||||
}
|
||||
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cueConfig.Tags))
|
||||
|
||||
return load.Instances(args, &cueConfig), nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, cfg *client.Config) (results []*v1alpha1.Result, err error) {
|
||||
func (b *Builder) Run(ctx context.Context, cfg *client.Config) (results []*render.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "cue: building instances")
|
||||
instances, err := b.Instances(ctx, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = make([]*v1alpha1.Result, 0, len(instances)*8)
|
||||
results = make([]*render.Result, 0, len(instances)*8)
|
||||
|
||||
// Each CUE instance provides a BuildPlan
|
||||
for idx, instance := range instances {
|
||||
@@ -141,7 +190,7 @@ func (b *Builder) Run(ctx context.Context, cfg *client.Config) (results []*v1alp
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (results []*v1alpha1.Result, err error) {
|
||||
func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (results []*render.Result, err error) {
|
||||
path := holos.InstancePath(instance.Dir)
|
||||
log := logger.FromContext(ctx).With("dir", path)
|
||||
|
||||
@@ -175,28 +224,36 @@ 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
|
||||
var bp v1alpha2.BuildPlan
|
||||
if err = decoder.Decode(&bp); err != nil {
|
||||
err = errors.Wrap(fmt.Errorf("could not decode BuildPlan %s: %w", instance.Dir, err))
|
||||
return
|
||||
}
|
||||
results, err = b.buildPlan(ctx, &bp, path)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
default:
|
||||
err = errors.Wrap(fmt.Errorf("unknown kind: %v", tm.Kind))
|
||||
}
|
||||
|
||||
return
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha1.BuildPlan, path holos.InstancePath) (results []*v1alpha1.Result, err error) {
|
||||
func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha2.BuildPlan, path holos.InstancePath) (results []*render.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
if err := buildPlan.Validate(); err != nil {
|
||||
bpw := buildPlanWrapper{buildPlan: buildPlan}
|
||||
|
||||
if err := bpw.validate(); err != nil {
|
||||
log.WarnContext(ctx, "could not validate", "skipped", true, "err", err)
|
||||
return nil, errors.Wrap(fmt.Errorf("could not validate %w", err))
|
||||
}
|
||||
@@ -206,11 +263,12 @@ func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha1.BuildPlan,
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: concurrent renders
|
||||
results = make([]*v1alpha1.Result, 0, buildPlan.ResultCapacity())
|
||||
log.DebugContext(ctx, "allocated results slice", "cap", buildPlan.ResultCapacity())
|
||||
results = make([]*render.Result, 0, bpw.resultCapacity())
|
||||
log.DebugContext(ctx, "allocated results slice", "cap", bpw.resultCapacity())
|
||||
|
||||
for _, component := range buildPlan.Spec.Components.Resources {
|
||||
if result, err := component.Render(ctx, path); err != nil {
|
||||
ko := render.KubernetesObjects{Component: component}
|
||||
if result, err := ko.Render(ctx, path); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not render: %w", err))
|
||||
} else {
|
||||
results = append(results, result)
|
||||
@@ -218,21 +276,24 @@ func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha1.BuildPlan,
|
||||
}
|
||||
|
||||
for _, component := range buildPlan.Spec.Components.KubernetesObjectsList {
|
||||
if result, err := component.Render(ctx, path); err != nil {
|
||||
ko := render.KubernetesObjects{Component: component}
|
||||
if result, err := ko.Render(ctx, path); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not render: %w", err))
|
||||
} else {
|
||||
results = append(results, result)
|
||||
}
|
||||
}
|
||||
for _, component := range buildPlan.Spec.Components.HelmChartList {
|
||||
if result, err := component.Render(ctx, path); err != nil {
|
||||
hc := render.HelmChart{Component: component}
|
||||
if result, err := hc.Render(ctx, path); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not render: %w", err))
|
||||
} else {
|
||||
results = append(results, result)
|
||||
}
|
||||
}
|
||||
for _, component := range buildPlan.Spec.Components.KustomizeBuildList {
|
||||
if result, err := component.Render(ctx, path); err != nil {
|
||||
kb := render.KustomizeBuild{Component: component}
|
||||
if result, err := kb.Render(ctx, path); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not render: %w", err))
|
||||
} else {
|
||||
results = append(results, result)
|
||||
|
||||
@@ -9,14 +9,15 @@ import (
|
||||
"cuelang.org/go/cue/build"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"github.com/holos-run/holos"
|
||||
"github.com/holos-run/holos/api/v1alpha1"
|
||||
core "github.com/holos-run/holos/api/core/v1alpha2"
|
||||
meta "github.com/holos-run/holos/api/meta/v1alpha2"
|
||||
"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) {
|
||||
func (b *Builder) Platform(ctx context.Context, cfg *client.Config) (*core.Platform, error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "cue: building platform instance")
|
||||
instances, err := b.Instances(ctx, cfg)
|
||||
@@ -38,7 +39,7 @@ func (b *Builder) Platform(ctx context.Context, cfg *client.Config) (*v1alpha1.P
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*v1alpha1.Platform, error) {
|
||||
func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*core.Platform, error) {
|
||||
path := holos.InstancePath(instance.Dir)
|
||||
log := logger.FromContext(ctx).With("dir", path)
|
||||
|
||||
@@ -60,22 +61,23 @@ func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*v1
|
||||
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{}
|
||||
tm := &meta.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)
|
||||
log.DebugContext(ctx, "cue: discriminated build kind: "+tm.GetKind(), "kind", tm.GetKind(), "apiVersion", tm.GetAPIVersion())
|
||||
|
||||
// New decoder for the full object
|
||||
decoder = json.NewDecoder(bytes.NewReader(jsonBytes))
|
||||
decoder.DisallowUnknownFields()
|
||||
|
||||
var pf v1alpha1.Platform
|
||||
switch tm.Kind {
|
||||
var pf core.Platform
|
||||
switch tm.GetKind() {
|
||||
case "Platform":
|
||||
if err = decoder.Decode(&pf); err != nil {
|
||||
err = errors.Wrap(fmt.Errorf("could not decode platform %s: %w", instance.Dir, err))
|
||||
@@ -83,7 +85,7 @@ func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*v1
|
||||
}
|
||||
return &pf, nil
|
||||
default:
|
||||
err = errors.Wrap(fmt.Errorf("unknown kind: %v", tm.Kind))
|
||||
err = errors.Wrap(fmt.Errorf("unknown kind: %v", tm.GetKind()))
|
||||
}
|
||||
|
||||
return nil, err
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/holos-run/holos/internal/client"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/server/middleware/logger"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
func makeBuildRunFunc(cfg *client.Config) command.RunFunc {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
logger.FromContext(ctx).DebugContext(ctx, "RunE", "args", args)
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.Holos().ClusterName()))
|
||||
results, err := build.Run(ctx, cfg)
|
||||
if err != nil {
|
||||
@@ -24,7 +26,7 @@ func makeBuildRunFunc(cfg *client.Config) command.RunFunc {
|
||||
}
|
||||
outs := make([]string, 0, len(results))
|
||||
for idx, result := range results {
|
||||
if result == nil || result.Skip {
|
||||
if result.Continue() {
|
||||
slog.Debug("skip result", "idx", idx, "result", result)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -41,6 +43,7 @@ func NewPlatform(cfg *holos.Config) *cobra.Command {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -53,33 +56,47 @@ func NewComponent() *cobra.Command {
|
||||
cmd.Short = "generate a component from an embedded schematic"
|
||||
|
||||
cmd.AddCommand(NewCueComponent())
|
||||
cmd.AddCommand(NewHelmComponent())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewHelmComponent() *cobra.Command {
|
||||
cmd := command.New("helm")
|
||||
cmd.Short = "generate a helm component from a schematic"
|
||||
|
||||
for _, name := range generate.HelmComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("helm", name))
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCueComponent() *cobra.Command {
|
||||
cmd := command.New("cue")
|
||||
cmd.Short = "generate a cue component from an embedded schematic"
|
||||
cmd.Short = "generate a cue component from a schematic"
|
||||
|
||||
components := generate.CueComponents()
|
||||
cmd.Long = fmt.Sprintf("Embedded cue components available to generate:\n\n %s", strings.Join(components, "\n "))
|
||||
for _, name := range components {
|
||||
cmd.AddCommand(makeCueCommand(name))
|
||||
for _, name := range generate.CueComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("cue", name))
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func makeCueCommand(name string) *cobra.Command {
|
||||
func makeSchematicCommand(kind, name string) *cobra.Command {
|
||||
cmd := command.New(name)
|
||||
cmd.Short = fmt.Sprintf("generate a %s cue component from an embedded schematic", name)
|
||||
cfg, err := generate.NewSchematic(filepath.Join("components", kind), name)
|
||||
if err != nil {
|
||||
slog.Error("could not get schematic", "err", err)
|
||||
return nil
|
||||
}
|
||||
cmd.Short = cfg.Short
|
||||
cmd.Long = cfg.Long
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
cfg := &generate.CueConfig{}
|
||||
cmd.Flags().AddGoFlagSet(cfg.FlagSet())
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
if err := generate.GenerateCueComponent(ctx, name, cfg); err != nil {
|
||||
if err := generate.GenerateComponent(ctx, kind, name, cfg); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -38,8 +38,9 @@ func NewPlatform(cfg *client.Config) *cobra.Command {
|
||||
}
|
||||
|
||||
func NewPlatformConfig(cfg *client.Config) *cobra.Command {
|
||||
cmd := command.New("config")
|
||||
cmd.Short = "pull platform config"
|
||||
cmd := command.New("model")
|
||||
cmd.Aliases = []string{"config"}
|
||||
cmd.Short = "pull platform model"
|
||||
cmd.Args = cobra.MinimumNArgs(1)
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
@@ -35,7 +35,7 @@ func NewPlatform(cfg *client.Config) *cobra.Command {
|
||||
cmd.Args = cobra.NoArgs
|
||||
|
||||
cmd.AddCommand(NewPlatformForm(cfg))
|
||||
// cmd.AddCommand(NewPlatformModel(cfg))
|
||||
cmd.AddCommand(NewPlatformModel(cfg))
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -74,3 +74,34 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewPlatformModel(cfg *client.Config) *cobra.Command {
|
||||
cmd := command.New("model")
|
||||
cmd.Short = "push platform model to holos server"
|
||||
cmd.Args = cobra.MinimumNArgs(1)
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
if ctx == nil {
|
||||
return errors.Wrap(errors.New("cannot execute: no context"))
|
||||
}
|
||||
ctx = logger.NewContext(ctx, logger.FromContext(ctx).With("server", cfg.Client().Server()))
|
||||
rpc := client.New(cfg)
|
||||
for _, name := range args {
|
||||
// Get the platform config for the platform id.
|
||||
p, err := client.LoadPlatformConfig(ctx, name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// Make the rpc call to update the platform form.
|
||||
if err := rpc.UpdatePlatformModel(ctx, p.PlatformId, p.PlatformModel); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
slog.Default().InfoContext(ctx, fmt.Sprintf("pushed: %s/ui/platform/%s", cfg.Client().Server(), p.PlatformId))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/holos-run/holos/internal/builder"
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
@@ -43,7 +44,6 @@ func NewComponent(cfg *holos.Config) *cobra.Command {
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
log := logger.FromContext(ctx).With("cluster", cfg.ClusterName())
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
|
||||
|
||||
if printInstances {
|
||||
@@ -67,20 +67,29 @@ func NewComponent(cfg *holos.Config) *cobra.Command {
|
||||
// place.
|
||||
var result Result
|
||||
for _, result = range results {
|
||||
log := logger.FromContext(ctx).With(
|
||||
"cluster", cfg.ClusterName(),
|
||||
"name", result.Name(),
|
||||
)
|
||||
if result.Continue() {
|
||||
continue
|
||||
}
|
||||
// DeployFiles from the BuildPlan
|
||||
if err := result.WriteDeployFiles(ctx, cfg.WriteTo()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// API Objects
|
||||
path := result.Filename(cfg.WriteTo(), cfg.ClusterName())
|
||||
if err := result.Save(ctx, path, result.AccumulatedOutput()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
if result.SkipWriteAccumulatedOutput() {
|
||||
log.DebugContext(ctx, "skipped writing k8s objects for "+result.Name())
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
log.InfoContext(ctx, "rendered "+result.Name(), "status", "ok", "action", "rendered", "name", result.Name())
|
||||
|
||||
log.InfoContext(ctx, "rendered "+result.Name(), "status", "ok", "action", "rendered")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -96,6 +105,9 @@ func NewPlatform(cfg *holos.Config) *cobra.Command {
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
|
||||
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
|
||||
|
||||
var concurrency int
|
||||
cmd.Flags().IntVar(&concurrency, "concurrency", min(runtime.NumCPU(), 8), "Number of concurrent components to render")
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Root().Context()
|
||||
build := builder.New(builder.Entrypoints(args))
|
||||
@@ -105,7 +117,7 @@ func NewPlatform(cfg *holos.Config) *cobra.Command {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
return render.Platform(ctx, platform, cmd.ErrOrStderr())
|
||||
return render.Platform(ctx, concurrency, platform, cmd.ErrOrStderr())
|
||||
}
|
||||
|
||||
return cmd
|
||||
@@ -118,5 +130,8 @@ type Result interface {
|
||||
KustomizationFilename(writeTo string, cluster string) string
|
||||
Save(ctx context.Context, path string, content string) error
|
||||
AccumulatedOutput() string
|
||||
KustomizationContent() string
|
||||
SkipWriteAccumulatedOutput() bool
|
||||
WriteDeployFiles(ctx context.Context, writeTo string) error
|
||||
GetKind() string
|
||||
GetAPIVersion() string
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "holos",
|
||||
Short: "holos manages a holistic integrated software development platform",
|
||||
Version: version.Version,
|
||||
Version: version.GetVersion(),
|
||||
Args: cobra.NoArgs,
|
||||
CompletionOptions: cobra.CompletionOptions{
|
||||
HiddenDefaultCmd: true, // Don't complete the complete subcommand itself
|
||||
|
||||
@@ -3,6 +3,7 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"time"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
@@ -18,6 +19,26 @@ import (
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
type PlatformMutation struct {
|
||||
Name string
|
||||
DisplayName string
|
||||
flagSet *flag.FlagSet
|
||||
}
|
||||
|
||||
func (pm *PlatformMutation) FlagSet() *flag.FlagSet {
|
||||
if pm == nil {
|
||||
return nil
|
||||
}
|
||||
if pm.flagSet != nil {
|
||||
return pm.flagSet
|
||||
}
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fs.StringVar(&pm.Name, "name", "example", "platform name")
|
||||
fs.StringVar(&pm.DisplayName, "display-name", "Example Platform", "platform display name")
|
||||
pm.flagSet = fs
|
||||
return fs
|
||||
}
|
||||
|
||||
func New(cfg *Config) *Client {
|
||||
t := token.NewClient(cfg.Token())
|
||||
s := cfg.Client().Server()
|
||||
@@ -57,7 +78,8 @@ func (c *Client) Platforms(ctx context.Context, orgID string) ([]*platform.Platf
|
||||
func (c *Client) UpdateForm(ctx context.Context, platformID string, form *object.Form) error {
|
||||
start := time.Now()
|
||||
req := &platform.UpdatePlatformRequest{
|
||||
Update: &platform.UpdatePlatformOperation{PlatformId: platformID, Form: form},
|
||||
PlatformId: platformID,
|
||||
Update: &platform.PlatformMutation{Form: form},
|
||||
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"form"}},
|
||||
}
|
||||
_, err := c.pltSvc.UpdatePlatform(ctx, connect.NewRequest(req))
|
||||
@@ -69,6 +91,22 @@ func (c *Client) UpdateForm(ctx context.Context, platformID string, form *object
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) UpdatePlatformModel(ctx context.Context, platformID string, model *structpb.Struct) error {
|
||||
start := time.Now()
|
||||
req := &platform.UpdatePlatformRequest{
|
||||
PlatformId: platformID,
|
||||
Update: &platform.PlatformMutation{Model: model},
|
||||
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"model"}},
|
||||
}
|
||||
_, err := c.pltSvc.UpdatePlatform(ctx, connect.NewRequest(req))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "updated platform", "platform_id", platformID, "duration", time.Since(start))
|
||||
return nil
|
||||
}
|
||||
|
||||
// PlatformModel gets the platform model from the PlatformService.
|
||||
func (c *Client) PlatformModel(ctx context.Context, platformID string) (*structpb.Struct, error) {
|
||||
start := time.Now()
|
||||
@@ -84,3 +122,22 @@ func (c *Client) PlatformModel(ctx context.Context, platformID string) (*structp
|
||||
log.DebugContext(ctx, "get platform", "platform_id", platformID, "duration", time.Since(start))
|
||||
return pf.Msg.GetPlatform().GetSpec().GetModel(), nil
|
||||
}
|
||||
|
||||
func (c *Client) CreatePlatform(ctx context.Context, pm PlatformMutation) (*platform.Platform, error) {
|
||||
log := logger.FromContext(ctx).With("platform", pm.Name)
|
||||
start := time.Now()
|
||||
req := &platform.CreatePlatformRequest{
|
||||
OrgId: c.cfg.context.OrgID,
|
||||
Create: &platform.PlatformMutation{
|
||||
Name: &pm.Name,
|
||||
DisplayName: &pm.DisplayName,
|
||||
},
|
||||
}
|
||||
pf, err := c.pltSvc.CreatePlatform(ctx, connect.NewRequest(req))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
log = log.With("platform_id", pf.Msg.GetPlatform().GetId())
|
||||
log.DebugContext(ctx, "create platform", "duration", time.Since(start))
|
||||
return pf.Msg.GetPlatform(), nil
|
||||
}
|
||||
|
||||
@@ -52,7 +52,8 @@ func LoadPlatformConfig(ctx context.Context, name string) (*object.PlatformConfi
|
||||
|
||||
// SavePlatformConfig writes pc to the platform root directory path identified by name.
|
||||
func SavePlatformConfig(ctx context.Context, name string, pc *object.PlatformConfig) (string, error) {
|
||||
data, err := protojson.Marshal(pc)
|
||||
encoder := protojson.MarshalOptions{Multiline: true}
|
||||
data, err := encoder.Marshal(pc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
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.34.0",
|
||||
"@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
|
||||
|
||||
@@ -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) })
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
@@ -21,22 +22,62 @@ var components embed.FS
|
||||
// componentsRoot is the root path to copy component cue code from.
|
||||
const componentsRoot = "components"
|
||||
|
||||
// CueConfig represents the config values passed to cue go templates.
|
||||
type CueConfig struct {
|
||||
ComponentName string
|
||||
flagSet *flag.FlagSet
|
||||
func NewSchematic(root string, name string) (*Schematic, error) {
|
||||
data, err := components.ReadFile(filepath.Join(root, name, "schematic.json"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
schematic := Schematic{Name: name}
|
||||
if err := json.Unmarshal(data, &schematic); err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
return &schematic, nil
|
||||
}
|
||||
|
||||
func (c *CueConfig) FlagSet() *flag.FlagSet {
|
||||
if c == nil {
|
||||
// Schematic represents the flags and command metadata stored in the
|
||||
// schematic.yaml file along side each schematic.
|
||||
type Schematic struct {
|
||||
// Name represents the name of the resource the schematic generates.
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
|
||||
Short string `json:"short,omitempty" yaml:"short,omitempty"`
|
||||
Long string `json:"long,omitempty" yaml:"long,omitempty"`
|
||||
|
||||
Chart *string `json:"chart,omitempty" yaml:"chart,omitempty"`
|
||||
Version *string `json:"version,omitempty" yaml:"version,omitempty"`
|
||||
Namespace *string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
|
||||
RepoName *string `json:"reponame,omitempty" yaml:"reponame,omitempty"`
|
||||
RepoURL *string `json:"repourl,omitempty" yaml:"repourl,omitempty"`
|
||||
|
||||
flagSet *flag.FlagSet
|
||||
}
|
||||
|
||||
func (s *Schematic) FlagSet() *flag.FlagSet {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
if c.flagSet != nil {
|
||||
return c.flagSet
|
||||
if s.flagSet != nil {
|
||||
return s.flagSet
|
||||
}
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fs.StringVar(&c.ComponentName, "name", "example", "component name")
|
||||
c.flagSet = fs
|
||||
fs.StringVar(&s.Name, "name", s.Name, "component name")
|
||||
if s.Chart != nil {
|
||||
fs.StringVar(s.Chart, "chart", *s.Chart, "chart name")
|
||||
}
|
||||
if s.Version != nil {
|
||||
fs.StringVar(s.Version, "component-version", *s.Version, "component version")
|
||||
}
|
||||
if s.Namespace != nil {
|
||||
fs.StringVar(s.Namespace, "namespace", *s.Namespace, "namespace")
|
||||
}
|
||||
if s.RepoName != nil {
|
||||
fs.StringVar(s.RepoName, "repo-name", *s.RepoName, "chart repository name")
|
||||
}
|
||||
if s.RepoURL != nil {
|
||||
fs.StringVar(s.RepoURL, "repo-url", *s.RepoURL, "chart repository url")
|
||||
}
|
||||
s.flagSet = fs
|
||||
return fs
|
||||
}
|
||||
|
||||
@@ -53,8 +94,21 @@ func CueComponents() []string {
|
||||
return dirs
|
||||
}
|
||||
|
||||
// HelmComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func HelmComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "helm"))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// makeRenderFunc makes a template rendering function for embedded files.
|
||||
func makeRenderFunc(log *slog.Logger, path string, cfg *CueConfig) func([]byte) *bytes.Buffer {
|
||||
func makeRenderFunc[T any](log *slog.Logger, path string, cfg T) func([]byte) *bytes.Buffer {
|
||||
return func(content []byte) *bytes.Buffer {
|
||||
tmpl, err := template.New(filepath.Base(path)).Parse(string(content))
|
||||
if err != nil {
|
||||
@@ -72,12 +126,14 @@ func makeRenderFunc(log *slog.Logger, path string, cfg *CueConfig) func([]byte)
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateCueComponent writes the cue code for a component to the local working
|
||||
// GenerateComponent writes the cue code for a component to the local working
|
||||
// directory.
|
||||
func GenerateCueComponent(ctx context.Context, name string, cfg *CueConfig) error {
|
||||
path := filepath.Join(componentsRoot, "cue", name)
|
||||
dstPath := filepath.Join(getCwd(ctx), cfg.ComponentName)
|
||||
log := logger.FromContext(ctx).With("name", cfg.ComponentName, "path", dstPath)
|
||||
func GenerateComponent(ctx context.Context, kind string, name string, cfg *Schematic) error {
|
||||
// use name from args to build the source path
|
||||
path := filepath.Join(componentsRoot, kind, name)
|
||||
// use cfg.Name from flags to build the destination path
|
||||
dstPath := filepath.Join(getCwd(ctx), cfg.Name)
|
||||
log := logger.FromContext(ctx).With("name", cfg.Name, "path", dstPath)
|
||||
log.DebugContext(ctx, "mkdir")
|
||||
if err := os.MkdirAll(dstPath, os.ModePerm); err != nil {
|
||||
return errors.Wrap(err)
|
||||
|
||||
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"
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package holos
|
||||
|
||||
import v1 "github.com/holos-run/holos/api/v1alpha1"
|
||||
import "encoding/yaml"
|
||||
|
||||
let ComponentName = "{{ .ComponentName }}"
|
||||
|
||||
// The BuildPlan represents the kubernetes api objects to manage. CUE returns
|
||||
// the build plan to the holos CLI for rendering to plain yaml files.
|
||||
v1.#BuildPlan & {
|
||||
spec: components: resources: "\(ComponentName)": {
|
||||
metadata: name: ComponentName
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
}
|
||||
}
|
||||
|
||||
// OBJECTS represents the kubernetes api objects to manage.
|
||||
let OBJECTS = v1.#APIObjects & {
|
||||
// Add Kubernetes API Objects to manage here.
|
||||
apiObjects: ConfigMap: "\(ComponentName)": {
|
||||
metadata: {
|
||||
name: ComponentName
|
||||
namespace: "default"
|
||||
}
|
||||
data: platform: yaml.Marshal(PLATFORM)
|
||||
}
|
||||
}
|
||||
|
||||
// This is an example of how to refer to the Platform model.
|
||||
let PLATFORM = {
|
||||
spec: model: _Platform.spec.model
|
||||
}
|
||||
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"
|
||||
}
|
||||
@@ -41,17 +41,25 @@ func copyEmbedFS(ctx context.Context, srcFS embed.FS, srcPath, dstPath string, m
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.DebugContext(ctx, "created", "directory", dstFullPath)
|
||||
} else {
|
||||
data, err := srcFS.ReadFile(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
buf := mapFunc(data)
|
||||
if err := os.WriteFile(dstFullPath, buf.Bytes(), os.ModePerm); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.DebugContext(ctx, "wrote", "file", dstFullPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
if filepath.Base(path) == "schematic.json" {
|
||||
log.DebugContext(ctx, "skipped", "file", dstFullPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := srcFS.ReadFile(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
buf := mapFunc(data)
|
||||
if err := os.WriteFile(dstFullPath, buf.Bytes(), 0666); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
log.DebugContext(ctx, "wrote", "file", dstFullPath)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
34
internal/generate/platforms/bare/buildplan.cue
Normal file
34
internal/generate/platforms/bare/buildplan.cue
Normal file
@@ -0,0 +1,34 @@
|
||||
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,6 +1,7 @@
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
|
||||
import v1 "github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
// Provide a BuildPlan to the holos cli to render k8s api objects.
|
||||
|
||||
@@ -58,13 +58,13 @@ let FormBuilder = v1.#FormBuilder & {
|
||||
multiple: true
|
||||
selectAllOption: "Select All"
|
||||
options: [
|
||||
{value: "aws", label: "Amazon Web Services"},
|
||||
{value: "gcp", label: "Google Cloud Platform"},
|
||||
{value: "azure", label: "Microsoft Azure"},
|
||||
{value: "aws", label: "Amazon Web Services"},
|
||||
{value: "gcp", label: "Google Cloud Platform"},
|
||||
{value: "azure", label: "Microsoft Azure"},
|
||||
{value: "cloudflare", label: "Cloudflare"},
|
||||
{value: "github", label: "GitHub"},
|
||||
{value: "ois", label: "Open Infrastructure Services"},
|
||||
{value: "onprem", label: "On Premises", disabled: true},
|
||||
{value: "github", label: "GitHub"},
|
||||
{value: "ois", label: "Open Infrastructure Services"},
|
||||
{value: "onprem", label: "On Premises", disabled: true},
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
@@ -237,73 +237,73 @@ let FormBuilder = v1.#FormBuilder & {
|
||||
}
|
||||
|
||||
let GCPRegions = [
|
||||
{value: "africa-south1", label: "africa-south1"},
|
||||
{value: "asia-east1", label: "asia-east1"},
|
||||
{value: "asia-east2", label: "asia-east2"},
|
||||
{value: "asia-northeast1", label: "asia-northeast1"},
|
||||
{value: "asia-northeast2", label: "asia-northeast2"},
|
||||
{value: "asia-northeast3", label: "asia-northeast3"},
|
||||
{value: "asia-south1", label: "asia-south1"},
|
||||
{value: "asia-south2", label: "asia-south2"},
|
||||
{value: "asia-southeast1", label: "asia-southeast1"},
|
||||
{value: "asia-southeast2", label: "asia-southeast2"},
|
||||
{value: "australia-southeast1", label: "australia-southeast1"},
|
||||
{value: "australia-southeast2", label: "australia-southeast2"},
|
||||
{value: "europe-central2", label: "europe-central2"},
|
||||
{value: "europe-north1", label: "europe-north1"},
|
||||
{value: "europe-southwest1", label: "europe-southwest1"},
|
||||
{value: "europe-west1", label: "europe-west1"},
|
||||
{value: "europe-west10", label: "europe-west10"},
|
||||
{value: "europe-west12", label: "europe-west12"},
|
||||
{value: "europe-west2", label: "europe-west2"},
|
||||
{value: "europe-west3", label: "europe-west3"},
|
||||
{value: "europe-west4", label: "europe-west4"},
|
||||
{value: "europe-west6", label: "europe-west6"},
|
||||
{value: "europe-west8", label: "europe-west8"},
|
||||
{value: "europe-west9", label: "europe-west9"},
|
||||
{value: "me-central1", label: "me-central1"},
|
||||
{value: "me-central2", label: "me-central2"},
|
||||
{value: "me-west1", label: "me-west1"},
|
||||
{value: "africa-south1", label: "africa-south1"},
|
||||
{value: "asia-east1", label: "asia-east1"},
|
||||
{value: "asia-east2", label: "asia-east2"},
|
||||
{value: "asia-northeast1", label: "asia-northeast1"},
|
||||
{value: "asia-northeast2", label: "asia-northeast2"},
|
||||
{value: "asia-northeast3", label: "asia-northeast3"},
|
||||
{value: "asia-south1", label: "asia-south1"},
|
||||
{value: "asia-south2", label: "asia-south2"},
|
||||
{value: "asia-southeast1", label: "asia-southeast1"},
|
||||
{value: "asia-southeast2", label: "asia-southeast2"},
|
||||
{value: "australia-southeast1", label: "australia-southeast1"},
|
||||
{value: "australia-southeast2", label: "australia-southeast2"},
|
||||
{value: "europe-central2", label: "europe-central2"},
|
||||
{value: "europe-north1", label: "europe-north1"},
|
||||
{value: "europe-southwest1", label: "europe-southwest1"},
|
||||
{value: "europe-west1", label: "europe-west1"},
|
||||
{value: "europe-west10", label: "europe-west10"},
|
||||
{value: "europe-west12", label: "europe-west12"},
|
||||
{value: "europe-west2", label: "europe-west2"},
|
||||
{value: "europe-west3", label: "europe-west3"},
|
||||
{value: "europe-west4", label: "europe-west4"},
|
||||
{value: "europe-west6", label: "europe-west6"},
|
||||
{value: "europe-west8", label: "europe-west8"},
|
||||
{value: "europe-west9", label: "europe-west9"},
|
||||
{value: "me-central1", label: "me-central1"},
|
||||
{value: "me-central2", label: "me-central2"},
|
||||
{value: "me-west1", label: "me-west1"},
|
||||
{value: "northamerica-northeast1", label: "northamerica-northeast1"},
|
||||
{value: "northamerica-northeast2", label: "northamerica-northeast2"},
|
||||
{value: "southamerica-east1", label: "southamerica-east1"},
|
||||
{value: "southamerica-west1", label: "southamerica-west1"},
|
||||
{value: "us-central1", label: "us-central1"},
|
||||
{value: "us-east1", label: "us-east1"},
|
||||
{value: "us-east4", label: "us-east4"},
|
||||
{value: "us-east5", label: "us-east5"},
|
||||
{value: "us-south1", label: "us-south1"},
|
||||
{value: "us-west1", label: "us-west1"},
|
||||
{value: "us-west2", label: "us-west2"},
|
||||
{value: "us-west3", label: "us-west3"},
|
||||
{value: "us-west4", label: "us-west4"},
|
||||
{value: "southamerica-east1", label: "southamerica-east1"},
|
||||
{value: "southamerica-west1", label: "southamerica-west1"},
|
||||
{value: "us-central1", label: "us-central1"},
|
||||
{value: "us-east1", label: "us-east1"},
|
||||
{value: "us-east4", label: "us-east4"},
|
||||
{value: "us-east5", label: "us-east5"},
|
||||
{value: "us-south1", label: "us-south1"},
|
||||
{value: "us-west1", label: "us-west1"},
|
||||
{value: "us-west2", label: "us-west2"},
|
||||
{value: "us-west3", label: "us-west3"},
|
||||
{value: "us-west4", label: "us-west4"},
|
||||
]
|
||||
|
||||
let AWSRegions = [
|
||||
{value: "us-east-1", label: "N. Virginia (us-east-1)"},
|
||||
{value: "us-east-2", label: "Ohio (us-east-2)"},
|
||||
{value: "us-west-1", label: "N. California (us-west-1)"},
|
||||
{value: "us-west-2", label: "Oregon (us-west-2)"},
|
||||
{value: "us-gov-west1", label: "US GovCloud West (us-gov-west1)"},
|
||||
{value: "us-gov-east1", label: "US GovCloud East (us-gov-east1)"},
|
||||
{value: "ca-central-1", label: "Canada (ca-central-1)"},
|
||||
{value: "eu-north-1", label: "Stockholm (eu-north-1)"},
|
||||
{value: "eu-west-1", label: "Ireland (eu-west-1)"},
|
||||
{value: "eu-west-2", label: "London (eu-west-2)"},
|
||||
{value: "eu-west-3", label: "Paris (eu-west-3)"},
|
||||
{value: "eu-central-1", label: "Frankfurt (eu-central-1)"},
|
||||
{value: "eu-south-1", label: "Milan (eu-south-1)"},
|
||||
{value: "af-south-1", label: "Cape Town (af-south-1)"},
|
||||
{value: "us-east-1", label: "N. Virginia (us-east-1)"},
|
||||
{value: "us-east-2", label: "Ohio (us-east-2)"},
|
||||
{value: "us-west-1", label: "N. California (us-west-1)"},
|
||||
{value: "us-west-2", label: "Oregon (us-west-2)"},
|
||||
{value: "us-gov-west1", label: "US GovCloud West (us-gov-west1)"},
|
||||
{value: "us-gov-east1", label: "US GovCloud East (us-gov-east1)"},
|
||||
{value: "ca-central-1", label: "Canada (ca-central-1)"},
|
||||
{value: "eu-north-1", label: "Stockholm (eu-north-1)"},
|
||||
{value: "eu-west-1", label: "Ireland (eu-west-1)"},
|
||||
{value: "eu-west-2", label: "London (eu-west-2)"},
|
||||
{value: "eu-west-3", label: "Paris (eu-west-3)"},
|
||||
{value: "eu-central-1", label: "Frankfurt (eu-central-1)"},
|
||||
{value: "eu-south-1", label: "Milan (eu-south-1)"},
|
||||
{value: "af-south-1", label: "Cape Town (af-south-1)"},
|
||||
{value: "ap-northeast-1", label: "Tokyo (ap-northeast-1)"},
|
||||
{value: "ap-northeast-2", label: "Seoul (ap-northeast-2)"},
|
||||
{value: "ap-northeast-3", label: "Osaka (ap-northeast-3)"},
|
||||
{value: "ap-southeast-1", label: "Singapore (ap-southeast-1)"},
|
||||
{value: "ap-southeast-2", label: "Sydney (ap-southeast-2)"},
|
||||
{value: "ap-east-1", label: "Hong Kong (ap-east-1)"},
|
||||
{value: "ap-south-1", label: "Mumbai (ap-south-1)"},
|
||||
{value: "me-south-1", label: "Bahrain (me-south-1)"},
|
||||
{value: "sa-east-1", label: "São Paulo (sa-east-1)"},
|
||||
{value: "cn-north-1", label: "Bejing (cn-north-1)"},
|
||||
{value: "ap-east-1", label: "Hong Kong (ap-east-1)"},
|
||||
{value: "ap-south-1", label: "Mumbai (ap-south-1)"},
|
||||
{value: "me-south-1", label: "Bahrain (me-south-1)"},
|
||||
{value: "sa-east-1", label: "São Paulo (sa-east-1)"},
|
||||
{value: "cn-north-1", label: "Bejing (cn-north-1)"},
|
||||
{value: "cn-northwest-1", label: "Ningxia (cn-northwest-1)"},
|
||||
{value: "ap-southeast-3", label: "Jakarta (ap-southeast-3)"},
|
||||
]
|
||||
|
||||
@@ -3,11 +3,12 @@ package holos
|
||||
import "encoding/json"
|
||||
|
||||
import v1 "github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
import dto "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
|
||||
|
||||
// _PlatformConfig represents all of the data passed from holos to cue.
|
||||
// Intended to carry the platform model and project models.
|
||||
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
|
||||
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
|
||||
_PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
|
||||
|
||||
// _Platform provides a platform resource to the holos cli for rendering. The
|
||||
@@ -16,7 +17,9 @@ _PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
|
||||
// resource itself is output once when rendering the entire platform, see the
|
||||
// platform/ subdirectory.
|
||||
_Platform: v1.#Platform & {
|
||||
metadata: name: string | *"bare" @tag(platform_name, type=string)
|
||||
metadata: {
|
||||
name: string | *"bare" @tag(platform_name, type=string)
|
||||
}
|
||||
|
||||
// spec is the platform specification
|
||||
spec: {
|
||||
@@ -28,7 +31,7 @@ _Platform: v1.#Platform & {
|
||||
_components: {
|
||||
for WorkloadCluster in _Clusters.Workload {
|
||||
"\(WorkloadCluster)-configmap": {
|
||||
path: "components/configmap"
|
||||
path: "components/configmap"
|
||||
cluster: WorkloadCluster
|
||||
}
|
||||
}
|
||||
|
||||
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,340 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f https://raw.githubusercontent.com/crossplane-contrib/provider-upjet-aws/v1.5.0/package/crds/aws.upbound.io_providerconfigs.yaml
|
||||
|
||||
package v1beta1
|
||||
|
||||
import "strings"
|
||||
|
||||
// A ProviderConfig configures the AWS provider.
|
||||
#ProviderConfig: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object.
|
||||
// Servers should convert recognized schemas to the latest
|
||||
// internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "aws.upbound.io/v1beta1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents.
|
||||
// Servers may infer this from the endpoint the client submits
|
||||
// requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "ProviderConfig"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace?: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A ProviderConfigSpec defines the desired state of a
|
||||
// ProviderConfig.
|
||||
spec!: #ProviderConfigSpec
|
||||
}
|
||||
|
||||
// A ProviderConfigSpec defines the desired state of a
|
||||
// ProviderConfig.
|
||||
#ProviderConfigSpec: {
|
||||
// AssumeRoleChain defines the options for assuming an IAM role
|
||||
assumeRoleChain?: [...{
|
||||
// ExternalID is the external ID used when assuming role.
|
||||
externalID?: string
|
||||
|
||||
// AssumeRoleARN to assume with provider credentials
|
||||
roleARN?: string
|
||||
|
||||
// Tags is list of session tags that you want to pass. Each
|
||||
// session tag consists of a key
|
||||
// name and an associated value. For more information about
|
||||
// session tags, see
|
||||
// Tagging STS Sessions
|
||||
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html).
|
||||
tags?: [...{
|
||||
// Name of the tag.
|
||||
// Key is a required field
|
||||
key: string
|
||||
|
||||
// Value of the tag.
|
||||
// Value is a required field
|
||||
value: string
|
||||
}]
|
||||
|
||||
// TransitiveTagKeys is a list of keys for session tags that you
|
||||
// want to set as transitive. If you set a
|
||||
// tag key as transitive, the corresponding key and value passes
|
||||
// to subsequent
|
||||
// sessions in a role chain. For more information, see Chaining
|
||||
// Roles with Session Tags
|
||||
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining).
|
||||
transitiveTagKeys?: [...string]
|
||||
}]
|
||||
|
||||
// Credentials required to authenticate to this provider.
|
||||
credentials: {
|
||||
env?: {
|
||||
// Name is the name of an environment variable.
|
||||
name: string
|
||||
}
|
||||
fs?: {
|
||||
// Path is a filesystem path.
|
||||
path: string
|
||||
}
|
||||
|
||||
// A SecretRef is a reference to a secret key that contains the
|
||||
// credentials
|
||||
// that must be used to connect to the provider.
|
||||
secretRef?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the secret.
|
||||
name: string
|
||||
|
||||
// Namespace of the secret.
|
||||
namespace: string
|
||||
}
|
||||
|
||||
// Source of the provider credentials.
|
||||
source: "None" | "Secret" | "IRSA" | "WebIdentity" | "Upbound"
|
||||
upbound?: {
|
||||
// WebIdentity defines the options for assuming an IAM role with a
|
||||
// Web
|
||||
// Identity.
|
||||
webIdentity?: {
|
||||
// AssumeRoleARN to assume with provider credentials
|
||||
roleARN?: string
|
||||
|
||||
// RoleSessionName is the session name, if you wish to uniquely
|
||||
// identify this session.
|
||||
roleSessionName?: string
|
||||
|
||||
// TokenConfig is the Web Identity Token config to assume the
|
||||
// role.
|
||||
tokenConfig?: {
|
||||
fs?: {
|
||||
// Path is a filesystem path.
|
||||
path: string
|
||||
}
|
||||
|
||||
// A SecretRef is a reference to a secret key that contains the
|
||||
// credentials
|
||||
// that must be used to obtain the web identity token.
|
||||
secretRef?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the secret.
|
||||
name: string
|
||||
|
||||
// Namespace of the secret.
|
||||
namespace: string
|
||||
}
|
||||
|
||||
// Source is the source of the web identity token.
|
||||
source: "Secret" | "Filesystem"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WebIdentity defines the options for assuming an IAM role with a
|
||||
// Web Identity.
|
||||
webIdentity?: {
|
||||
// AssumeRoleARN to assume with provider credentials
|
||||
roleARN?: string
|
||||
|
||||
// RoleSessionName is the session name, if you wish to uniquely
|
||||
// identify this session.
|
||||
roleSessionName?: string
|
||||
|
||||
// TokenConfig is the Web Identity Token config to assume the
|
||||
// role.
|
||||
tokenConfig?: {
|
||||
fs?: {
|
||||
// Path is a filesystem path.
|
||||
path: string
|
||||
}
|
||||
|
||||
// A SecretRef is a reference to a secret key that contains the
|
||||
// credentials
|
||||
// that must be used to obtain the web identity token.
|
||||
secretRef?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the secret.
|
||||
name: string
|
||||
|
||||
// Namespace of the secret.
|
||||
namespace: string
|
||||
}
|
||||
|
||||
// Source is the source of the web identity token.
|
||||
source: "Secret" | "Filesystem"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Endpoint is where you can override the default endpoint
|
||||
// configuration
|
||||
// of AWS calls made by the provider.
|
||||
endpoint?: {
|
||||
// Specifies if the endpoint's hostname can be modified by the
|
||||
// SDK's API
|
||||
// client.
|
||||
//
|
||||
//
|
||||
// If the hostname is mutable the SDK API clients may modify any
|
||||
// part of
|
||||
// the hostname based on the requirements of the API, (e.g.
|
||||
// adding, or
|
||||
// removing content in the hostname). Such as, Amazon S3 API
|
||||
// client
|
||||
// prefixing "bucketname" to the hostname, or changing the
|
||||
// hostname service name component from "s3." to
|
||||
// "s3-accesspoint.dualstack."
|
||||
// for the dualstack endpoint of an S3 Accesspoint resource.
|
||||
//
|
||||
//
|
||||
// Care should be taken when providing a custom endpoint for an
|
||||
// API. If the
|
||||
// endpoint hostname is mutable, and the client cannot modify the
|
||||
// endpoint
|
||||
// correctly, the operation call will most likely fail, or have
|
||||
// undefined
|
||||
// behavior.
|
||||
//
|
||||
//
|
||||
// If hostname is immutable, the SDK API clients will not modify
|
||||
// the
|
||||
// hostname of the URL. This may cause the API client not to
|
||||
// function
|
||||
// correctly if the API requires the operation specific hostname
|
||||
// values
|
||||
// to be used by the client.
|
||||
//
|
||||
//
|
||||
// This flag does not modify the API client's behavior if this
|
||||
// endpoint
|
||||
// will be used instead of Endpoint Discovery, or if the endpoint
|
||||
// will be
|
||||
// used to perform Endpoint Discovery. That behavior is configured
|
||||
// via the
|
||||
// API Client's Options.
|
||||
// Note that this is effective only for resources that use AWS SDK
|
||||
// v2.
|
||||
hostnameImmutable?: bool
|
||||
|
||||
// The AWS partition the endpoint belongs to.
|
||||
partitionId?: string
|
||||
|
||||
// Specifies the list of services you want endpoint to be used for
|
||||
services?: [...string]
|
||||
|
||||
// The signing method that should be used for signing the requests
|
||||
// to the
|
||||
// endpoint.
|
||||
signingMethod?: string
|
||||
|
||||
// The service name that should be used for signing the requests
|
||||
// to the
|
||||
// endpoint.
|
||||
signingName?: string
|
||||
|
||||
// The region that should be used for signing the request to the
|
||||
// endpoint.
|
||||
// For IAM, which doesn't have any region, us-east-1 is used to
|
||||
// sign the
|
||||
// requests, which is the only signing region of IAM.
|
||||
signingRegion?: string
|
||||
|
||||
// The source of the Endpoint. By default, this will be
|
||||
// ServiceMetadata.
|
||||
// When providing a custom endpoint, you should set the source as
|
||||
// Custom.
|
||||
// If source is not provided when providing a custom endpoint, the
|
||||
// SDK may not
|
||||
// perform required host mutations correctly. Source should be
|
||||
// used along with
|
||||
// HostnameImmutable property as per the usage requirement.
|
||||
// Note that this is effective only for resources that use AWS SDK
|
||||
// v2.
|
||||
source?: "ServiceMetadata" | "Custom"
|
||||
|
||||
// URL lets you configure the endpoint URL to be used in SDK
|
||||
// calls.
|
||||
url: {
|
||||
// Dynamic lets you configure the behavior of endpoint URL
|
||||
// resolver.
|
||||
dynamic?: {
|
||||
// Host is the address of the main host that the resolver will use
|
||||
// to
|
||||
// prepend protocol, service and region configurations.
|
||||
// For example, the final URL for EC2 in us-east-1 looks like
|
||||
// https://ec2.us-east-1.amazonaws.com
|
||||
// You would need to use "amazonaws.com" as Host and "https" as
|
||||
// protocol
|
||||
// to have the resolver construct it.
|
||||
host: string
|
||||
|
||||
// Protocol is the HTTP protocol that will be used in the URL.
|
||||
// Currently,
|
||||
// only http and https are supported.
|
||||
protocol: "http" | "https"
|
||||
}
|
||||
|
||||
// Static is the full URL you'd like the AWS SDK to use.
|
||||
// Recommended for using tools like localstack where a single host
|
||||
// is exposed
|
||||
// for all services and regions.
|
||||
static?: string
|
||||
|
||||
// You can provide a static URL that will be used regardless of
|
||||
// the service
|
||||
// and region by choosing Static type. Alternatively, you can
|
||||
// provide
|
||||
// configuration for dynamically resolving the URL with the config
|
||||
// you provide
|
||||
// once you set the type as Dynamic.
|
||||
type: "Static" | "Dynamic"
|
||||
}
|
||||
}
|
||||
|
||||
// Whether to enable the request to use path-style addressing,
|
||||
// i.e., https://s3.amazonaws.com/BUCKET/KEY.
|
||||
s3_use_path_style?: bool
|
||||
|
||||
// Whether to skip credentials validation via the STS API.
|
||||
// This can be useful for testing and for AWS API implementations
|
||||
// that do not have STS available.
|
||||
skip_credentials_validation?: bool
|
||||
|
||||
// Whether to skip the AWS Metadata API check
|
||||
// Useful for AWS API implementations that do not have a metadata
|
||||
// API endpoint.
|
||||
skip_metadata_api_check?: bool
|
||||
|
||||
// Whether to skip validation of provided region name.
|
||||
// Useful for AWS-like implementations that use their own region
|
||||
// names or to bypass the validation for
|
||||
// regions that aren't publicly available yet.
|
||||
skip_region_validation?: bool
|
||||
|
||||
// Whether to skip requesting the account ID.
|
||||
// Useful for AWS API implementations that do not have the IAM,
|
||||
// STS API, or metadata API
|
||||
skip_requesting_account_id?: bool
|
||||
}
|
||||
@@ -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)
|
||||
}] & [_, ...]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user