mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 16:54:58 +00:00
Compare commits
150 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6756ecf11 | ||
|
|
ef7ec30037 | ||
|
|
1642787825 | ||
|
|
f83781480f | ||
|
|
9b70205855 | ||
|
|
0e4bf3c144 | ||
|
|
1241c74b41 | ||
|
|
44fea098de | ||
|
|
52286efa25 | ||
|
|
a1b2179442 | ||
|
|
cffc430738 | ||
|
|
d76454272b | ||
|
|
9d1e77c00f | ||
|
|
2050abdc6c | ||
|
|
3ea013c503 | ||
|
|
309db96138 | ||
|
|
283b4be71c | ||
|
|
ab9bca0750 | ||
|
|
ac2be67c3c | ||
|
|
6ffafb8cca | ||
|
|
590e6b556c | ||
|
|
5dc5c6fbdf | ||
|
|
cd8c9f2c32 | ||
|
|
3490941d4c | ||
|
|
3f201df0c2 | ||
|
|
4c22d515bd | ||
|
|
ec0ef1c4b3 | ||
|
|
1e51e2d49a | ||
|
|
5186499b90 | ||
|
|
fc275e4164 | ||
|
|
9fa466f7cf | ||
|
|
efd6f256a5 | ||
|
|
f7f9d6b5f0 | ||
|
|
0526062ab2 | ||
|
|
a1ededa722 | ||
|
|
9b09a02912 | ||
|
|
657a5e82a5 | ||
|
|
1eece02254 | ||
|
|
c866b47dcb | ||
|
|
ff52ec750b | ||
|
|
4184619afc | ||
|
|
954dbd1ec8 | ||
|
|
30b70e76aa | ||
|
|
ec6d112711 | ||
|
|
e796c6a763 | ||
|
|
be32201294 | ||
|
|
5ebc54b5b7 | ||
|
|
2954a57872 | ||
|
|
df705bd79f | ||
|
|
4e8ce3585d | ||
|
|
ab5f17c3d2 | ||
|
|
a8918c74d4 | ||
|
|
ae5738d82d | ||
|
|
bb99aedffa | ||
|
|
d6ee1864c8 | ||
|
|
8a4be66277 | ||
|
|
79ce2f8458 | ||
|
|
3d4ae44ddd | ||
|
|
1efb1faa40 | ||
|
|
bfd6a56397 | ||
|
|
a788f6d8e8 | ||
|
|
80fa91d74d | ||
|
|
db34562e9a | ||
|
|
d6af089ab3 | ||
|
|
b3a70c5911 | ||
|
|
bf5765c9cb | ||
|
|
6c7697648c | ||
|
|
04158485c7 | ||
|
|
cf83c77280 | ||
|
|
6e545b13dd | ||
|
|
bf258a1f41 | ||
|
|
6f06c73d6f | ||
|
|
a689c53a9c | ||
|
|
58cdda1d35 | ||
|
|
bcb02b5c5c | ||
|
|
0736c7de1a | ||
|
|
28be9f9fbb | ||
|
|
647681de38 | ||
|
|
81beb5c539 | ||
|
|
5c1e0a29c8 | ||
|
|
01ac5276a9 | ||
|
|
e40594ad8e | ||
|
|
bc9c6a622a | ||
|
|
17f22199b7 | ||
|
|
7e93fe4535 | ||
|
|
2e98df3572 | ||
|
|
3b561de413 | ||
|
|
0d0dae8742 | ||
|
|
61b4b5bd17 | ||
|
|
0060740b76 | ||
|
|
bf8a4af579 | ||
|
|
dc057fe39d | ||
|
|
9877ab131a | ||
|
|
13aba64cb7 | ||
|
|
fe9bc2dbfc | ||
|
|
c53b682852 | ||
|
|
3aca6a9e4c | ||
|
|
40fdfc0317 | ||
|
|
25d9415b0a | ||
|
|
43c8702398 | ||
|
|
ce94776dbb | ||
|
|
78ab6cd848 | ||
|
|
0a7001f868 | ||
|
|
2db7be671b | ||
|
|
b51870f7bf | ||
|
|
0227dfa7e5 | ||
|
|
05b59d9af0 | ||
|
|
04f9f3b3a8 | ||
|
|
b58be8b38c | ||
|
|
10493d754a | ||
|
|
cf28516b8b | ||
|
|
d81e25c4e4 | ||
|
|
c4612ff5d2 | ||
|
|
d70acbb47e | ||
|
|
3c977d22fe | ||
|
|
e34db2b583 | ||
|
|
71de57ac88 | ||
|
|
c7cc661018 | ||
|
|
09f39c02fe | ||
|
|
23c76a73e0 | ||
|
|
1cafe08237 | ||
|
|
45b07964ef | ||
|
|
6cc4a57b62 | ||
|
|
31280acbae | ||
|
|
6f0928b12c | ||
|
|
c6e9250d60 | ||
|
|
104bda459f | ||
|
|
bd2effa183 | ||
|
|
562412fbe7 | ||
|
|
fd6fbe5598 | ||
|
|
67472e1e1c | ||
|
|
d64c3e8c66 | ||
|
|
f344f97374 | ||
|
|
770088b912 | ||
|
|
cb9b39c3ca | ||
|
|
0f34b20546 | ||
|
|
0d7bbbb659 | ||
|
|
3f3e36bbe9 | ||
|
|
9f41478d33 | ||
|
|
b86fee04fc | ||
|
|
c78da6949f | ||
|
|
7b215bb8f1 | ||
|
|
78cec76a96 | ||
|
|
0e98ad2ecb | ||
|
|
30bb3f183a | ||
|
|
1369338f3c | ||
|
|
ac03f64724 | ||
|
|
bea4468972 | ||
|
|
224adffa15 | ||
|
|
b4d34ffdbc |
27
.github/workflows/lint.yaml
vendored
27
.github/workflows/lint.yaml
vendored
@@ -17,12 +17,33 @@ jobs:
|
||||
name: lint
|
||||
runs-on: gha-rs
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Packages
|
||||
run: sudo apt update && sudo apt -qq -y install git curl zip unzip tar bzip2 make
|
||||
|
||||
- name: Install Tools
|
||||
run: |
|
||||
set -x
|
||||
make tools
|
||||
make buf
|
||||
go generate ./...
|
||||
make frontend
|
||||
go mod tidy
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
with:
|
||||
version: latest
|
||||
skip-pkg-cache: true
|
||||
|
||||
33
.github/workflows/release.yaml
vendored
33
.github/workflows/release.yaml
vendored
@@ -14,23 +14,46 @@ jobs:
|
||||
goreleaser:
|
||||
runs-on: gha-rs
|
||||
steps:
|
||||
# Must come before Checkout, otherwise goreleaser fails
|
||||
- name: Provide GPG and Git
|
||||
run: sudo apt update && sudo apt -qq -y install gnupg git
|
||||
run: sudo apt update && sudo apt -qq -y install gnupg git curl zip unzip tar bzip2 make
|
||||
|
||||
# Must come after git executable is provided
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: stable
|
||||
|
||||
# Necessary to run these outside of goreleaser, otherwise
|
||||
# /home/runner/_work/holos/holos/internal/frontend/node_modules/.bin/protoc-gen-connect-query is not in PATH
|
||||
- name: Install Tools
|
||||
run: |
|
||||
set -x
|
||||
make tools
|
||||
make buf
|
||||
go generate ./...
|
||||
make frontend
|
||||
go mod tidy
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPG_CODE_SIGNING_SECRETKEY }}
|
||||
passphrase: ${{ secrets.GPG_CODE_SIGNING_PASSPHRASE }}
|
||||
|
||||
- name: List keys
|
||||
run: gpg -K
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: stable
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
|
||||
18
.github/workflows/test.yaml
vendored
18
.github/workflows/test.yaml
vendored
@@ -18,13 +18,18 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: stable
|
||||
|
||||
- name: Provide unzip for Helm
|
||||
run: sudo apt update && sudo apt -qq -y install curl zip unzip tar bzip2
|
||||
- name: Install Packages
|
||||
run: sudo apt update && sudo apt -qq -y install git curl zip unzip tar bzip2 make
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v4
|
||||
@@ -32,5 +37,14 @@ jobs:
|
||||
- name: Set up Kubectl
|
||||
uses: azure/setup-kubectl@v3
|
||||
|
||||
- name: Install Tools
|
||||
run: |
|
||||
set -x
|
||||
make tools
|
||||
make buf
|
||||
go generate ./...
|
||||
make frontend
|
||||
go mod tidy
|
||||
|
||||
- name: Test
|
||||
run: ./scripts/test
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,7 +1,8 @@
|
||||
bin/
|
||||
/bin/
|
||||
vendor/
|
||||
.idea/
|
||||
coverage.out
|
||||
dist/
|
||||
/dist/
|
||||
*.hold/
|
||||
/deploy/
|
||||
.vscode/
|
||||
|
||||
@@ -10,10 +10,8 @@ version: 1
|
||||
|
||||
before:
|
||||
hooks:
|
||||
# You may remove this if you don't use go modules.
|
||||
- go mod tidy
|
||||
# you may remove this if you don't need go generate
|
||||
- go generate ./...
|
||||
- go mod tidy
|
||||
|
||||
builds:
|
||||
- main: ./cmd/holos
|
||||
@@ -23,6 +21,9 @@ builds:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
|
||||
signs:
|
||||
- artifacts: checksum
|
||||
|
||||
54
Makefile
54
Makefile
@@ -4,7 +4,7 @@ PROJ=holos
|
||||
ORG_PATH=github.com/holos-run
|
||||
REPO_PATH=$(ORG_PATH)/$(PROJ)
|
||||
|
||||
VERSION := $(shell grep "const Version " pkg/version/version.go | sed -E 's/.*"(.+)"$$/\1/')
|
||||
VERSION := $(shell cat version/embedded/major version/embedded/minor version/embedded/patch | xargs printf "%s.%s.%s")
|
||||
BIN_NAME := holos
|
||||
|
||||
DOCKER_REPO=quay.io/openinfrastructure/holos
|
||||
@@ -12,11 +12,14 @@ IMAGE_NAME=$(DOCKER_REPO)
|
||||
|
||||
$( shell mkdir -p bin)
|
||||
|
||||
# For buf plugin protoc-gen-connect-es
|
||||
export PATH := $(PWD)/internal/frontend/holos/node_modules/.bin:$(PATH)
|
||||
|
||||
GIT_COMMIT=$(shell git rev-parse HEAD)
|
||||
GIT_TREE_STATE=$(shell test -n "`git status --porcelain`" && echo "dirty" || echo "clean")
|
||||
BUILD_DATE=$(shell date -Iseconds)
|
||||
|
||||
LD_FLAGS="-w -X ${ORG_PATH}/${PROJ}/pkg/version.GitCommit=${GIT_COMMIT} -X ${ORG_PATH}/${PROJ}/pkg/version.GitTreeState=${GIT_TREE_STATE} -X ${ORG_PATH}/${PROJ}/pkg/version.BuildDate=${BUILD_DATE}"
|
||||
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}"
|
||||
|
||||
.PHONY: default
|
||||
default: test
|
||||
@@ -39,24 +42,33 @@ bumpmajor: ## Bump the major version.
|
||||
scripts/bump minor 0
|
||||
scripts/bump patch 0
|
||||
|
||||
.PHONY: show-version
|
||||
show-version: ## Print the full version.
|
||||
@echo $(VERSION)
|
||||
|
||||
.PHONY: tidy
|
||||
tidy: ## Tidy go module.
|
||||
go mod tidy
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: ## Format Go code.
|
||||
fmt: ## Format code.
|
||||
cd docs/examples && cue fmt ./...
|
||||
go fmt ./...
|
||||
|
||||
.PHONY: vet
|
||||
vet: ## Vet Go code.
|
||||
go vet ./...
|
||||
|
||||
.PHONY: gencue
|
||||
gencue: ## Generate CUE definitions
|
||||
cd docs/examples && cue get go github.com/holos-run/holos/api/...
|
||||
|
||||
.PHONY: generate
|
||||
generate: ## Generate code.
|
||||
go generate ./...
|
||||
|
||||
.PHONY: build
|
||||
build: generate ## Build holos executable.
|
||||
build: generate frontend ## Build holos executable.
|
||||
@echo "building ${BIN_NAME} ${VERSION}"
|
||||
@echo "GOPATH=${GOPATH}"
|
||||
go build -trimpath -o bin/$(BIN_NAME) -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/$(BIN_NAME)
|
||||
@@ -85,6 +97,40 @@ coverage: test ## Test coverage profile.
|
||||
snapshot: ## Go release snapshot
|
||||
goreleaser release --snapshot --clean
|
||||
|
||||
.PHONY: buf
|
||||
buf: ## buf generate
|
||||
cd service && buf mod update
|
||||
buf generate
|
||||
|
||||
.PHONY: tools
|
||||
tools: go-deps frontend-deps ## install tool dependencies
|
||||
|
||||
.PHONY: go-deps
|
||||
go-deps: ## tool versions pinned in tools.go
|
||||
go install github.com/bufbuild/buf/cmd/buf
|
||||
go install github.com/fullstorydev/grpcurl/cmd/grpcurl
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go
|
||||
go install connectrpc.com/connect/cmd/protoc-gen-connect-go
|
||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
# curl https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash
|
||||
|
||||
.PHONY: frontend-deps
|
||||
frontend-deps: ## Setup npm and vite
|
||||
cd internal/frontend/holos && npm install
|
||||
cd internal/frontend/holos && npm install --save-dev @bufbuild/buf @connectrpc/protoc-gen-connect-es
|
||||
cd internal/frontend/holos && npm install @connectrpc/connect @connectrpc/connect-web @bufbuild/protobuf
|
||||
# https://github.com/connectrpc/connect-query-es/blob/1350b6f07b6aead81793917954bdb1cc3ce09df9/packages/protoc-gen-connect-query/README.md?plain=1#L23
|
||||
cd internal/frontend/holos && npm install --save-dev @connectrpc/protoc-gen-connect-query @bufbuild/protoc-gen-es
|
||||
cd internal/frontend/holos && npm install @connectrpc/connect-query @bufbuild/protobuf
|
||||
|
||||
|
||||
.PHONY: frontend
|
||||
frontend: buf
|
||||
cd internal/frontend/holos && rm -rf dist
|
||||
mkdir -p internal/frontend/holos/dist
|
||||
cd internal/frontend/holos && ng build
|
||||
touch internal/frontend/frontend.go
|
||||
|
||||
.PHONY: help
|
||||
help: ## Display this help menu.
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
315
Tiltfile
Normal file
315
Tiltfile
Normal file
@@ -0,0 +1,315 @@
|
||||
# -*- mode: Python -*-
|
||||
# This Tiltfile manages a Go project with live leload in Kubernetes
|
||||
|
||||
listen_port = 3000
|
||||
metrics_port = 9090
|
||||
|
||||
# Use our wrapper to set the kube namespace
|
||||
if os.getenv('TILT_WRAPPER') != '1':
|
||||
fail("could not run, ./hack/tilt/bin/tilt was not used to start tilt")
|
||||
|
||||
# AWS Account to work in
|
||||
aws_account = '271053619184'
|
||||
aws_region = 'us-east-2'
|
||||
|
||||
# Resource ids
|
||||
holos_backend = 'Holos Backend'
|
||||
pg_admin = 'pgAdmin'
|
||||
pg_cluster = 'PostgresCluster'
|
||||
pg_svc = 'Database Pod'
|
||||
compile_id = 'Go Build'
|
||||
auth_id = 'Auth Policy'
|
||||
lint_id = 'Run Linters'
|
||||
tests_id = 'Run Tests'
|
||||
|
||||
# PostgresCluster resource name in k8s
|
||||
pg_cluster_name = 'holos'
|
||||
# Database name inside the PostgresCluster
|
||||
pg_database_name = 'holos'
|
||||
# PGAdmin name
|
||||
pg_admin_name = 'pgadmin'
|
||||
|
||||
# Default Registry.
|
||||
# See: https://github.com/tilt-dev/tilt.build/blob/master/docs/choosing_clusters.md#manual-configuration
|
||||
# Note, Tilt will append the image name to the registry uri path
|
||||
default_registry('{account}.dkr.ecr.{region}.amazonaws.com/holos-run/holos-server'.format(account=aws_account, region=aws_region))
|
||||
|
||||
# Set a name prefix specific to the user. Multiple developers share the tilt-holos namespace.
|
||||
developer = os.getenv('USER')
|
||||
holos_server = 'holos'
|
||||
# See ./hack/tilt/bin/tilt
|
||||
namespace = os.getenv('NAMESPACE')
|
||||
# We always develop against the k1 cluster.
|
||||
os.putenv('KUBECONFIG', os.path.abspath('./hack/tilt/kubeconfig'))
|
||||
# The context defined in ./hack/tilt/kubeconfig
|
||||
allow_k8s_contexts('sso@k1')
|
||||
allow_k8s_contexts('sso@k2')
|
||||
allow_k8s_contexts('sso@k3')
|
||||
allow_k8s_contexts('sso@k4')
|
||||
allow_k8s_contexts('sso@k5')
|
||||
# PG db connection for localhost -> k8s port-forward
|
||||
os.putenv('PGHOST', 'localhost')
|
||||
os.putenv('PGPORT', '15432')
|
||||
# We always develop in the dev aws account.
|
||||
os.putenv('AWS_CONFIG_FILE', os.path.abspath('./hack/tilt/aws.config'))
|
||||
os.putenv('AWS_ACCOUNT', aws_account)
|
||||
os.putenv('AWS_DEFAULT_REGION', aws_region)
|
||||
os.putenv('AWS_PROFILE', 'dev-holos')
|
||||
os.putenv('AWS_SDK_LOAD_CONFIG', '1')
|
||||
# Authenticate to AWS ECR when tilt up is run by the developer
|
||||
local_resource('AWS Credentials', './hack/tilt/aws-login.sh', auto_init=True)
|
||||
|
||||
# Extensions are open-source, pre-packaged functions that extend Tilt
|
||||
#
|
||||
# More info: https://github.com/tilt-dev/tilt-extensions
|
||||
# More info: https://docs.tilt.dev/extensions.html
|
||||
load('ext://restart_process', 'docker_build_with_restart')
|
||||
load('ext://k8s_attach', 'k8s_attach')
|
||||
load('ext://git_resource', 'git_checkout')
|
||||
load('ext://uibutton', 'cmd_button')
|
||||
|
||||
# Paths edited by the developer Tilt watches to trigger compilation.
|
||||
# Generated files should be excluded to avoid an infinite build loop.
|
||||
developer_paths = [
|
||||
'./cmd',
|
||||
'./internal/server',
|
||||
'./internal/ent/schema',
|
||||
'./frontend/package-lock.json',
|
||||
'./frontend/src',
|
||||
'./go.mod',
|
||||
'./pkg',
|
||||
'./service/holos',
|
||||
]
|
||||
|
||||
# Builds the holos-server executable
|
||||
local_resource(compile_id, 'make build', deps=developer_paths)
|
||||
|
||||
# Build Docker image
|
||||
# Tilt will automatically associate image builds with the resource(s)
|
||||
# that reference them (e.g. via Kubernetes or Docker Compose YAML).
|
||||
#
|
||||
# More info: https://docs.tilt.dev/api.html#api.docker_build
|
||||
#
|
||||
docker_build_with_restart(
|
||||
'holos',
|
||||
context='.',
|
||||
entrypoint=[
|
||||
'/app/bin/holos',
|
||||
'server',
|
||||
'--listen-port={}'.format(listen_port),
|
||||
'--oidc-issuer=https://login.ois.run',
|
||||
'--oidc-audience=262096764402729854@holos_platform',
|
||||
'--metrics-port={}'.format(metrics_port),
|
||||
],
|
||||
dockerfile='./hack/tilt/Dockerfile',
|
||||
only=['./bin'],
|
||||
# (Recommended) Updating a running container in-place
|
||||
# https://docs.tilt.dev/live_update_reference.html
|
||||
live_update=[
|
||||
# Sync files from host to container
|
||||
sync('./bin', '/app/bin'),
|
||||
# Wait for aws-login https://github.com/tilt-dev/tilt/issues/3048
|
||||
sync('./tilt/aws-login.last', '/dev/null'),
|
||||
# Execute commands in the container when paths change
|
||||
# run('/app/hack/codegen.sh', trigger=['./app/api'])
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
# Run local commands
|
||||
# Local commands can be helpful for one-time tasks like installing
|
||||
# project prerequisites. They can also manage long-lived processes
|
||||
# for non-containerized services or dependencies.
|
||||
#
|
||||
# More info: https://docs.tilt.dev/local_resource.html
|
||||
#
|
||||
# local_resource('install-helm',
|
||||
# cmd='which helm > /dev/null || brew install helm',
|
||||
# # `cmd_bat`, when present, is used instead of `cmd` on Windows.
|
||||
# cmd_bat=[
|
||||
# 'powershell.exe',
|
||||
# '-Noninteractive',
|
||||
# '-Command',
|
||||
# '& {if (!(Get-Command helm -ErrorAction SilentlyContinue)) {scoop install helm}}'
|
||||
# ]
|
||||
# )
|
||||
|
||||
# Teach tilt about our custom resources (Note, this may be intended for workloads)
|
||||
# k8s_kind('authorizationpolicy')
|
||||
# k8s_kind('requestauthentication')
|
||||
# k8s_kind('virtualservice')
|
||||
k8s_kind('pgadmin')
|
||||
|
||||
|
||||
# Troubleshooting
|
||||
def resource_name(id):
|
||||
print('resource: {}'.format(id))
|
||||
return id.name
|
||||
|
||||
|
||||
workload_to_resource_function(resource_name)
|
||||
|
||||
# Apply Kubernetes manifests
|
||||
# Tilt will build & push any necessary images, re-deploying your
|
||||
# resources as they change.
|
||||
#
|
||||
# More info: https://docs.tilt.dev/api.html#api.k8s_yaml
|
||||
#
|
||||
|
||||
def holos_yaml():
|
||||
"""Return a k8s Deployment personalized for the developer."""
|
||||
k8s_yaml_template = str(read_file('./hack/tilt/k8s.yaml'))
|
||||
return k8s_yaml_template.format(
|
||||
name=holos_server,
|
||||
developer=developer,
|
||||
namespace=namespace,
|
||||
listen_port=listen_port,
|
||||
metrics_port=metrics_port,
|
||||
tz=os.getenv('TZ'),
|
||||
)
|
||||
|
||||
# Customize a Kubernetes resource
|
||||
# By default, Kubernetes resource names are automatically assigned
|
||||
# based on objects in the YAML manifests, e.g. Deployment name.
|
||||
#
|
||||
# Tilt strives for sane defaults, so calling k8s_resource is
|
||||
# optional, and you only need to pass the arguments you want to
|
||||
# override.
|
||||
#
|
||||
# More info: https://docs.tilt.dev/api.html#api.k8s_resource
|
||||
#
|
||||
k8s_yaml(blob(holos_yaml()))
|
||||
|
||||
# Backend server process
|
||||
k8s_resource(
|
||||
workload=holos_server,
|
||||
new_name=holos_backend,
|
||||
objects=[
|
||||
'{}:serviceaccount'.format(holos_server),
|
||||
'{}:servicemonitor'.format(holos_server),
|
||||
],
|
||||
resource_deps=[compile_id],
|
||||
links=[
|
||||
link('https://{}.holos.dev.k2.ois.run/app/'.format(developer), "Holos Web UI")
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
# AuthorizationPolicy - Beyond Corp functionality
|
||||
k8s_resource(
|
||||
new_name=auth_id,
|
||||
objects=[
|
||||
'{}:virtualservice'.format(holos_server),
|
||||
'{}-allow-groups:authorizationpolicy'.format(holos_server),
|
||||
'{}-allow-nothing:authorizationpolicy'.format(holos_server),
|
||||
'{}-allow-well-known-paths:authorizationpolicy'.format(holos_server),
|
||||
'{}-auth:authorizationpolicy'.format(holos_server),
|
||||
'{}:requestauthentication'.format(holos_server),
|
||||
],
|
||||
)
|
||||
|
||||
# Database
|
||||
# Note: Tilt confuses the backup pods with the database server pods, so this code is careful to tease the pods
|
||||
# apart so logs are streamed correctly.
|
||||
# See: https://github.com/tilt-dev/tilt.specs/blob/master/resource_assembly.md
|
||||
|
||||
# pgAdmin Web UI
|
||||
k8s_resource(
|
||||
workload=pg_admin_name,
|
||||
new_name=pg_admin,
|
||||
port_forwards=[
|
||||
port_forward(15050, 5050, pg_admin),
|
||||
],
|
||||
)
|
||||
|
||||
# Disabled because these don't group resources nicely
|
||||
# k8s_kind('postgrescluster')
|
||||
|
||||
# Postgres database in-cluster
|
||||
k8s_resource(
|
||||
new_name=pg_cluster,
|
||||
objects=['holos:postgrescluster'],
|
||||
)
|
||||
|
||||
# Needed to select the database by label
|
||||
# https://docs.tilt.dev/api.html#api.k8s_custom_deploy
|
||||
k8s_custom_deploy(
|
||||
pg_svc,
|
||||
apply_cmd=['./hack/tilt/k8s-get-db-sts', pg_cluster_name],
|
||||
delete_cmd=['echo', 'Skipping delete. Object managed by custom resource.'],
|
||||
deps=[],
|
||||
)
|
||||
k8s_resource(
|
||||
pg_svc,
|
||||
port_forwards=[
|
||||
port_forward(15432, 5432, 'psql'),
|
||||
],
|
||||
resource_deps=[pg_cluster]
|
||||
)
|
||||
|
||||
|
||||
# Run tests
|
||||
local_resource(
|
||||
tests_id,
|
||||
'make test',
|
||||
allow_parallel=True,
|
||||
auto_init=False,
|
||||
deps=developer_paths,
|
||||
)
|
||||
|
||||
# Run linter
|
||||
local_resource(
|
||||
lint_id,
|
||||
'make lint',
|
||||
allow_parallel=True,
|
||||
auto_init=False,
|
||||
deps=developer_paths,
|
||||
)
|
||||
|
||||
# UI Buttons for helpful things.
|
||||
# Icons: https://fonts.google.com/icons
|
||||
os.putenv("GH_FORCE_TTY", "80%")
|
||||
cmd_button(
|
||||
'{}:go-test-failfast'.format(tests_id),
|
||||
argv=['./hack/tilt/go-test-failfast'],
|
||||
resource=tests_id,
|
||||
icon_name='quiz',
|
||||
text='Fail Fast',
|
||||
)
|
||||
cmd_button(
|
||||
'{}:issues'.format(holos_server),
|
||||
argv=['./hack/tilt/gh-issues'],
|
||||
resource=holos_backend,
|
||||
icon_name='folder_data',
|
||||
text='Issues',
|
||||
)
|
||||
cmd_button(
|
||||
'{}:gh-issue-view'.format(holos_server),
|
||||
argv=['./hack/tilt/gh-issue-view'],
|
||||
resource=holos_backend,
|
||||
icon_name='task',
|
||||
text='View Issue',
|
||||
)
|
||||
cmd_button(
|
||||
'{}:get-pgdb-creds'.format(holos_server),
|
||||
argv=['./hack/tilt/get-pgdb-creds', pg_cluster_name, pg_database_name],
|
||||
resource=pg_svc,
|
||||
icon_name='lock_open_right',
|
||||
text='DB Creds',
|
||||
)
|
||||
cmd_button(
|
||||
'{}:get-pgdb-creds'.format(pg_admin_name),
|
||||
argv=['./hack/tilt/get-pgdb-creds', pg_cluster_name, pg_database_name],
|
||||
resource=pg_admin,
|
||||
icon_name='lock_open_right',
|
||||
text='DB Creds',
|
||||
)
|
||||
cmd_button(
|
||||
'{}:get-pgadmin-creds'.format(pg_admin_name),
|
||||
argv=['./hack/tilt/get-pgadmin-creds', pg_admin_name],
|
||||
resource=pg_admin,
|
||||
icon_name='lock_open_right',
|
||||
text='pgAdmin Login',
|
||||
)
|
||||
|
||||
print("✨ Tiltfile evaluated")
|
||||
40
api/v1alpha1/buildplan.go
Normal file
40
api/v1alpha1/buildplan.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BuildPlan is the primary interface between CUE and the Holos cli.
|
||||
type BuildPlan struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
// Metadata represents the holos component name
|
||||
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
Spec BuildPlanSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
||||
}
|
||||
|
||||
type BuildPlanSpec struct {
|
||||
Disabled bool `json:"disabled,omitempty" yaml:"disabled,omitempty"`
|
||||
Components BuildPlanComponents `json:"components,omitempty" yaml:"components,omitempty"`
|
||||
}
|
||||
|
||||
type BuildPlanComponents struct {
|
||||
HelmChartList []HelmChart `json:"helmChartList,omitempty" yaml:"helmChartList,omitempty"`
|
||||
KubernetesObjectsList []KubernetesObjects `json:"kubernetesObjectsList,omitempty" yaml:"kubernetesObjectsList,omitempty"`
|
||||
KustomizeBuildList []KustomizeBuild `json:"kustomizeBuildList,omitempty" yaml:"kustomizeBuildList,omitempty"`
|
||||
Resources map[string]KubernetesObjects `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||
}
|
||||
|
||||
func (bp *BuildPlan) Validate() error {
|
||||
errs := make([]string, 0, 2)
|
||||
if bp.Kind != BuildPlanKind {
|
||||
errs = append(errs, fmt.Sprintf("kind invalid: want: %s have: %s", BuildPlanKind, bp.Kind))
|
||||
}
|
||||
if bp.APIVersion != APIVersion {
|
||||
errs = append(errs, fmt.Sprintf("apiVersion invalid: want: %s have: %s", APIVersion, bp.APIVersion))
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("invalid BuildPlan: " + strings.Join(errs, ", "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
22
api/v1alpha1/component.go
Normal file
22
api/v1alpha1/component.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package v1alpha1
|
||||
|
||||
// HolosComponent defines the fields common to all holos component kinds including the Render Result.
|
||||
type HolosComponent struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
// Metadata represents the holos component name
|
||||
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
// APIObjectMap holds the marshalled representation of api objects. Think of
|
||||
// these as resources overlaid at the back of the render pipeline.
|
||||
APIObjectMap APIObjectMap `json:"apiObjectMap,omitempty" yaml:"apiObjectMap,omitempty"`
|
||||
// Kustomization holds the marshalled representation of the flux kustomization
|
||||
// which reconciles resources in git with the api server.
|
||||
Kustomization `json:",inline" yaml:",inline"`
|
||||
// Kustomize represents a kubectl kustomize build post-processing step.
|
||||
Kustomize `json:",inline" yaml:",inline"`
|
||||
// Skip causes holos to take no action regarding the component.
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (hc *HolosComponent) NewResult() *Result {
|
||||
return &Result{HolosComponent: *hc}
|
||||
}
|
||||
11
api/v1alpha1/constants.go
Normal file
11
api/v1alpha1/constants.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package v1alpha1
|
||||
|
||||
const (
|
||||
APIVersion = "holos.run/v1alpha1"
|
||||
BuildPlanKind = "BuildPlan"
|
||||
HelmChartKind = "HelmChart"
|
||||
// ChartDir is the directory name created in the holos component directory to cache a chart.
|
||||
ChartDir = "vendor"
|
||||
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
|
||||
ResourcesFile = "resources.yaml"
|
||||
)
|
||||
2
api/v1alpha1/doc.go
Normal file
2
api/v1alpha1/doc.go
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package v1alpha1 defines the api boundary between CUE and Holos.
|
||||
package v1alpha1
|
||||
170
api/v1alpha1/helm.go
Normal file
170
api/v1alpha1/helm.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/holos-run/holos"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/holos-run/holos/internal/util"
|
||||
)
|
||||
|
||||
// A HelmChart represents a helm command to provide chart values in order to render kubernetes api objects.
|
||||
type HelmChart struct {
|
||||
HolosComponent `json:",inline" yaml:",inline"`
|
||||
// Namespace is the namespace to install into. TODO: Use metadata.namespace instead.
|
||||
Namespace string `json:"namespace"`
|
||||
Chart Chart `json:"chart"`
|
||||
ValuesContent string `json:"valuesContent"`
|
||||
EnableHooks bool `json:"enableHooks"`
|
||||
}
|
||||
|
||||
type Chart struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Release string `json:"release"`
|
||||
Repository Repository `json:"repository,omitempty"`
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (hc *HelmChart) Render(ctx context.Context, path holos.InstancePath) (*Result, error) {
|
||||
result := Result{HolosComponent: hc.HolosComponent}
|
||||
if err := hc.helm(ctx, &result, path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.addObjectMap(ctx, hc.APIObjectMap)
|
||||
if err := result.kustomize(ctx); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not kustomize: %w", err))
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// runHelm provides the values produced by CUE to helm template and returns
|
||||
// the rendered kubernetes api objects in the result.
|
||||
func (hc *HelmChart) helm(ctx context.Context, r *Result, path holos.InstancePath) error {
|
||||
log := logger.FromContext(ctx).With("chart", hc.Chart.Name)
|
||||
if hc.Chart.Name == "" {
|
||||
log.WarnContext(ctx, "skipping helm: no chart name specified, use a different component type")
|
||||
return nil
|
||||
}
|
||||
|
||||
cachedChartPath := filepath.Join(string(path), ChartDir, filepath.Base(hc.Chart.Name))
|
||||
if isNotExist(cachedChartPath) {
|
||||
// Add repositories
|
||||
repo := hc.Chart.Repository
|
||||
if repo.URL != "" {
|
||||
out, err := util.RunCmd(ctx, "helm", "repo", "add", repo.Name, repo.URL)
|
||||
if err != nil {
|
||||
log.ErrorContext(ctx, "could not run helm", "stderr", out.Stderr.String(), "stdout", out.Stdout.String())
|
||||
return errors.Wrap(fmt.Errorf("could not run helm repo add: %w", err))
|
||||
}
|
||||
// Update repository
|
||||
out, err = util.RunCmd(ctx, "helm", "repo", "update", repo.Name)
|
||||
if err != nil {
|
||||
log.ErrorContext(ctx, "could not run helm", "stderr", out.Stderr.String(), "stdout", out.Stdout.String())
|
||||
return errors.Wrap(fmt.Errorf("could not run helm repo update: %w", err))
|
||||
}
|
||||
} else {
|
||||
log.DebugContext(ctx, "no chart repository url proceeding assuming oci chart")
|
||||
}
|
||||
|
||||
// Cache the chart
|
||||
if err := cacheChart(ctx, path, ChartDir, hc.Chart); err != nil {
|
||||
return fmt.Errorf("could not cache chart: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Write values file
|
||||
tempDir, err := os.MkdirTemp("", "holos")
|
||||
if err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not make temp dir: %w", err))
|
||||
}
|
||||
defer util.Remove(ctx, tempDir)
|
||||
|
||||
valuesPath := filepath.Join(tempDir, "values.yaml")
|
||||
if err := os.WriteFile(valuesPath, []byte(hc.ValuesContent), 0644); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not write values: %w", err))
|
||||
}
|
||||
log.DebugContext(ctx, "helm: wrote values", "path", valuesPath, "bytes", len(hc.ValuesContent))
|
||||
|
||||
// Run charts
|
||||
chart := hc.Chart
|
||||
args := []string{"template"}
|
||||
if !hc.EnableHooks {
|
||||
args = append(args, "--no-hooks")
|
||||
}
|
||||
namespace := hc.Namespace
|
||||
args = append(args, "--include-crds", "--values", valuesPath, "--namespace", namespace, "--kubeconfig", "/dev/null", "--version", chart.Version, chart.Release, cachedChartPath)
|
||||
helmOut, err := util.RunCmd(ctx, "helm", args...)
|
||||
if err != nil {
|
||||
stderr := helmOut.Stderr.String()
|
||||
lines := strings.Split(stderr, "\n")
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "Error:") {
|
||||
err = fmt.Errorf("%s: %w", line, err)
|
||||
}
|
||||
}
|
||||
return errors.Wrap(fmt.Errorf("could not run helm template: %w", err))
|
||||
}
|
||||
|
||||
r.accumulatedOutput = helmOut.Stdout.String()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// cacheChart stores a cached copy of Chart in the chart subdirectory of path.
|
||||
func cacheChart(ctx context.Context, path holos.InstancePath, chartDir string, chart Chart) error {
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
cacheTemp, err := os.MkdirTemp(string(path), chartDir)
|
||||
if err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not make temp dir: %w", err))
|
||||
}
|
||||
defer util.Remove(ctx, cacheTemp)
|
||||
|
||||
chartName := chart.Name
|
||||
if chart.Repository.Name != "" {
|
||||
chartName = fmt.Sprintf("%s/%s", chart.Repository.Name, chart.Name)
|
||||
}
|
||||
helmOut, err := util.RunCmd(ctx, "helm", "pull", "--destination", cacheTemp, "--untar=true", "--version", chart.Version, chartName)
|
||||
if err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not run helm pull: %w", err))
|
||||
}
|
||||
log.Debug("helm pull", "stdout", helmOut.Stdout, "stderr", helmOut.Stderr)
|
||||
|
||||
cachePath := filepath.Join(string(path), chartDir)
|
||||
|
||||
if err := os.MkdirAll(cachePath, 0777); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not mkdir: %w", err))
|
||||
}
|
||||
|
||||
items, err := os.ReadDir(cacheTemp)
|
||||
if err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not read directory: %w", err))
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
src := filepath.Join(cacheTemp, item.Name())
|
||||
dst := filepath.Join(cachePath, item.Name())
|
||||
log.DebugContext(ctx, "rename", "src", src, "dst", dst)
|
||||
if err := os.Rename(src, dst); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not rename: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
log.InfoContext(ctx, "cached", "chart", chart.Name, "version", chart.Version, "path", cachePath)
|
||||
|
||||
return nil
|
||||
}
|
||||
func isNotExist(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
return os.IsNotExist(err)
|
||||
}
|
||||
21
api/v1alpha1/kubernetesobjects.go
Normal file
21
api/v1alpha1/kubernetesobjects.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/holos-run/holos"
|
||||
)
|
||||
|
||||
const KubernetesObjectsKind = "KubernetesObjects"
|
||||
|
||||
// KubernetesObjects represents CUE output which directly provides Kubernetes api objects to holos.
|
||||
type KubernetesObjects struct {
|
||||
HolosComponent `json:",inline" yaml:",inline"`
|
||||
}
|
||||
|
||||
// Render produces kubernetes api objects from the APIObjectMap
|
||||
func (o *KubernetesObjects) Render(ctx context.Context, path holos.InstancePath) (*Result, error) {
|
||||
result := Result{HolosComponent: o.HolosComponent}
|
||||
result.addObjectMap(ctx, o.APIObjectMap)
|
||||
return &result, nil
|
||||
}
|
||||
7
api/v1alpha1/kustomization.go
Normal file
7
api/v1alpha1/kustomization.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package v1alpha1
|
||||
|
||||
// Kustomization holds the rendered flux kustomization api object content for git ops.
|
||||
type Kustomization struct {
|
||||
// KsContent is the yaml representation of the flux kustomization for gitops.
|
||||
KsContent string `json:"ksContent,omitempty" yaml:"ksContent,omitempty"`
|
||||
}
|
||||
47
api/v1alpha1/kustomize.go
Normal file
47
api/v1alpha1/kustomize.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/holos-run/holos"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/holos-run/holos/internal/util"
|
||||
)
|
||||
|
||||
const KustomizeBuildKind = "KustomizeBuild"
|
||||
|
||||
// Kustomize represents resources necessary to execute a kustomize build.
|
||||
// Intended for at least two use cases:
|
||||
//
|
||||
// 1. Process raw yaml file resources in a holos component directory.
|
||||
// 2. Post process a HelmChart to inject istio, add custom labels, etc...
|
||||
type Kustomize struct {
|
||||
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
|
||||
KustomizeFiles FileContentMap `json:"kustomizeFiles,omitempty" yaml:"kustomizeFiles,omitempty"`
|
||||
// ResourcesFile is the file name used for api objects in kustomization.yaml
|
||||
ResourcesFile string `json:"resourcesFile,omitempty" yaml:"resourcesFile,omitempty"`
|
||||
}
|
||||
|
||||
// KustomizeBuild renders plain yaml files in the holos component directory using kubectl kustomize build.
|
||||
type KustomizeBuild struct {
|
||||
HolosComponent `json:",inline" yaml:",inline"`
|
||||
}
|
||||
|
||||
// Render produces a Result by executing kubectl kustomize on the holos
|
||||
// component path. Useful for processing raw yaml files.
|
||||
func (kb *KustomizeBuild) Render(ctx context.Context, path holos.InstancePath) (*Result, error) {
|
||||
log := logger.FromContext(ctx)
|
||||
result := Result{HolosComponent: kb.HolosComponent}
|
||||
// Run kustomize.
|
||||
kOut, err := util.RunCmd(ctx, "kubectl", "kustomize", string(path))
|
||||
if err != nil {
|
||||
log.ErrorContext(ctx, kOut.Stderr.String())
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
// Replace the accumulated output
|
||||
result.accumulatedOutput = kOut.Stdout.String()
|
||||
// Add CUE based api objects.
|
||||
result.addObjectMap(ctx, kb.APIObjectMap)
|
||||
return &result, nil
|
||||
}
|
||||
14
api/v1alpha1/objectmap.go
Normal file
14
api/v1alpha1/objectmap.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package v1alpha1
|
||||
|
||||
// Label is an arbitrary unique identifier. Defined as a type for clarity and type checking.
|
||||
type Label string
|
||||
|
||||
// Kind is a kubernetes api object kind. Defined as a type for clarity and type checking.
|
||||
type Kind string
|
||||
|
||||
// APIObjectMap is the shape of marshalled api objects returned from cue to the
|
||||
// holos cli. A map is used to improve the clarity of error messages from cue.
|
||||
type APIObjectMap map[Kind]map[Label]string
|
||||
|
||||
// FileContentMap is a map of file names to file contents.
|
||||
type FileContentMap map[string]string
|
||||
15
api/v1alpha1/objectmeta.go
Normal file
15
api/v1alpha1/objectmeta.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package v1alpha1
|
||||
|
||||
// ObjectMeta represents metadata of a holos component object. The fields are a
|
||||
// copy of upstream kubernetes api machinery but are by holos objects distinct
|
||||
// from kubernetes api objects.
|
||||
type ObjectMeta struct {
|
||||
// Name uniquely identifies the holos component instance and must be suitable as a file name.
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
// Namespace confines a holos component to a single namespace via kustomize if set.
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
// Labels are not used but are copied from api machinery ObjectMeta for completeness.
|
||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
// Annotations are not used but are copied from api machinery ObjectMeta for completeness.
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
}
|
||||
22
api/v1alpha1/render.go
Normal file
22
api/v1alpha1/render.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/holos-run/holos"
|
||||
)
|
||||
|
||||
type Renderer interface {
|
||||
GetKind() string
|
||||
Render(ctx context.Context, path holos.InstancePath) (*Result, error)
|
||||
}
|
||||
|
||||
// Render produces a Result representing the kubernetes api objects to
|
||||
// configure. Each of the various holos component types, e.g. Helm, Kustomize,
|
||||
// et al, should implement the Renderer interface. This process is best
|
||||
// conceptualized as a data pipeline, for example a component may render a
|
||||
// result by first calling helm template, then passing the result through
|
||||
// kustomize, then mixing in overlay api objects.
|
||||
func Render(ctx context.Context, r Renderer, path holos.InstancePath) (*Result, error) {
|
||||
return r.Render(ctx, path)
|
||||
}
|
||||
138
api/v1alpha1/result.go
Normal file
138
api/v1alpha1/result.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/holos-run/holos/internal/util"
|
||||
)
|
||||
|
||||
// Result is the build result for display or writing. Holos components Render the Result as a data pipeline.
|
||||
type Result struct {
|
||||
HolosComponent
|
||||
// accumulatedOutput accumulates rendered api objects.
|
||||
accumulatedOutput string
|
||||
}
|
||||
|
||||
func (r *Result) Name() string {
|
||||
return r.Metadata.Name
|
||||
}
|
||||
|
||||
func (r *Result) Filename(writeTo string, cluster string) string {
|
||||
name := r.Metadata.Name
|
||||
return filepath.Join(writeTo, "clusters", cluster, "components", name, name+".gen.yaml")
|
||||
}
|
||||
|
||||
func (r *Result) KustomizationFilename(writeTo string, cluster string) string {
|
||||
return filepath.Join(writeTo, "clusters", cluster, "holos", "components", r.Metadata.Name+"-kustomization.gen.yaml")
|
||||
}
|
||||
|
||||
// AccumulatedOutput returns the accumulated rendered output.
|
||||
func (r *Result) AccumulatedOutput() string {
|
||||
return r.accumulatedOutput
|
||||
}
|
||||
|
||||
// addObjectMap renders the provided APIObjectMap into the accumulated output.
|
||||
func (r *Result) addObjectMap(ctx context.Context, objectMap APIObjectMap) {
|
||||
log := logger.FromContext(ctx)
|
||||
b := []byte(r.AccumulatedOutput())
|
||||
kinds := make([]Kind, 0, len(objectMap))
|
||||
// Sort the keys
|
||||
for kind := range objectMap {
|
||||
kinds = append(kinds, kind)
|
||||
}
|
||||
slices.Sort(kinds)
|
||||
|
||||
for _, kind := range kinds {
|
||||
v := objectMap[kind]
|
||||
// Sort the keys
|
||||
names := make([]Label, 0, len(v))
|
||||
for name := range v {
|
||||
names = append(names, name)
|
||||
}
|
||||
slices.Sort(names)
|
||||
|
||||
for _, name := range names {
|
||||
yamlString := v[name]
|
||||
log.Debug(fmt.Sprintf("%s/%s", kind, name), "kind", kind, "name", name)
|
||||
b = util.EnsureNewline(b)
|
||||
header := fmt.Sprintf("---\n# Source: CUE apiObjects.%s.%s\n", kind, name)
|
||||
b = append(b, []byte(header+yamlString)...)
|
||||
b = util.EnsureNewline(b)
|
||||
}
|
||||
}
|
||||
r.accumulatedOutput = string(b)
|
||||
}
|
||||
|
||||
// kustomize replaces the accumulated output with the output of kustomize build
|
||||
func (r *Result) kustomize(ctx context.Context) error {
|
||||
log := logger.FromContext(ctx)
|
||||
if r.ResourcesFile == "" {
|
||||
log.DebugContext(ctx, "skipping kustomize: no resourcesFile")
|
||||
return nil
|
||||
}
|
||||
if len(r.KustomizeFiles) < 1 {
|
||||
log.DebugContext(ctx, "skipping kustomize: no kustomizeFiles")
|
||||
return nil
|
||||
}
|
||||
tempDir, err := os.MkdirTemp("", "holos.kustomize")
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
defer util.Remove(ctx, tempDir)
|
||||
|
||||
// Write the main api object resources file for kustomize.
|
||||
target := filepath.Join(tempDir, r.ResourcesFile)
|
||||
b := []byte(r.AccumulatedOutput())
|
||||
b = util.EnsureNewline(b)
|
||||
if err := os.WriteFile(target, b, 0644); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not write resources: %w", err))
|
||||
}
|
||||
log.DebugContext(ctx, "wrote: "+target, "op", "write", "path", target, "bytes", len(b))
|
||||
|
||||
// Write the kustomization tree, kustomization.yaml must be in this map for kustomize to work.
|
||||
for file, content := range r.KustomizeFiles {
|
||||
target := filepath.Join(tempDir, file)
|
||||
if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
b := []byte(content)
|
||||
b = util.EnsureNewline(b)
|
||||
if err := os.WriteFile(target, b, 0644); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not write: %w", err))
|
||||
}
|
||||
log.DebugContext(ctx, "wrote: "+target, "op", "write", "path", target, "bytes", len(b))
|
||||
}
|
||||
|
||||
// Run kustomize.
|
||||
kOut, err := util.RunCmd(ctx, "kubectl", "kustomize", tempDir)
|
||||
if err != nil {
|
||||
log.ErrorContext(ctx, kOut.Stderr.String())
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Replace the accumulated output
|
||||
r.accumulatedOutput = kOut.Stdout.String()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save writes the content to the filesystem for git ops.
|
||||
func (r *Result) Save(ctx context.Context, path string, content string) error {
|
||||
log := logger.FromContext(ctx)
|
||||
dir := filepath.Dir(path)
|
||||
if err := os.MkdirAll(dir, os.FileMode(0775)); err != nil {
|
||||
log.WarnContext(ctx, "could not mkdir", "path", dir, "err", err)
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Write the kube api objects
|
||||
if err := os.WriteFile(path, []byte(content), os.FileMode(0644)); err != nil {
|
||||
log.WarnContext(ctx, "could not write", "path", path, "err", err)
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.DebugContext(ctx, "out: wrote "+path, "action", "write", "path", path, "status", "ok")
|
||||
return nil
|
||||
}
|
||||
10
api/v1alpha1/typemeta.go
Normal file
10
api/v1alpha1/typemeta.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package v1alpha1
|
||||
|
||||
type TypeMeta struct {
|
||||
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
|
||||
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
||||
}
|
||||
|
||||
func (tm *TypeMeta) GetKind() string {
|
||||
return tm.Kind
|
||||
}
|
||||
24
buf.gen.yaml
Normal file
24
buf.gen.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# Generates gRPC and ConnectRPC bindings for Go and TypeScript
|
||||
#
|
||||
# Note: protoc-gen-connect-query is the primary method of wiring up the React
|
||||
# frontend.
|
||||
version: v1
|
||||
plugins:
|
||||
- plugin: go
|
||||
out: service/gen
|
||||
opt: paths=source_relative
|
||||
- plugin: connect-go
|
||||
out: service/gen
|
||||
opt: paths=source_relative
|
||||
- plugin: es
|
||||
out: internal/frontend/holos/gen
|
||||
opt:
|
||||
- target=ts
|
||||
- plugin: connect-es
|
||||
out: internal/frontend/holos/gen
|
||||
opt:
|
||||
- target=ts
|
||||
- plugin: connect-query
|
||||
out: internal/frontend/holos/gen
|
||||
opt:
|
||||
- target=ts
|
||||
8
buf.lock
Normal file
8
buf.lock
Normal file
@@ -0,0 +1,8 @@
|
||||
# Generated by buf. DO NOT EDIT.
|
||||
version: v1
|
||||
deps:
|
||||
- remote: buf.build
|
||||
owner: bufbuild
|
||||
repository: protovalidate
|
||||
commit: b983156c5e994cc9892e0ce3e64e17e0
|
||||
digest: shake256:fb47a62989d38c2529bcc5cd86ded43d800eb84cee82b42b9e8a9e815d4ee8134a0fb9d0ce8299b27c2d2bbb7d6ade0c4ad5a8a4d467e1e2c7ca619ae9f634e2
|
||||
3
buf.work.yaml
Normal file
3
buf.work.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
version: v1
|
||||
directories:
|
||||
- service
|
||||
@@ -1,8 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/holos-run/holos/pkg/cli"
|
||||
"os"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/holos-run/holos/pkg/cli"
|
||||
"github.com/rogpeppe/go-internal/testscript"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli"
|
||||
"github.com/rogpeppe/go-internal/testscript"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
||||
29
cmd/holos/testdata/constraints.txt
vendored
29
cmd/holos/testdata/constraints.txt
vendored
@@ -1,7 +1,6 @@
|
||||
# Want support for intermediary constraints
|
||||
exec holos build ./foo/... --log-level debug
|
||||
stdout '^bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b$'
|
||||
stderr 'processing holos component kind Skip'
|
||||
|
||||
-- cue.mod --
|
||||
package holos
|
||||
@@ -12,31 +11,21 @@ metadata: name: "jeff"
|
||||
-- foo/bar/bar.cue --
|
||||
package holos
|
||||
|
||||
#KubernetesObjects & {
|
||||
apiObjectMap: foo: bar: "bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b"
|
||||
}
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
apiObjectMap: foo: bar: "bf2bc7f9-9ba0-4f9e-9bd2-9a205627eb0b"
|
||||
}
|
||||
]
|
||||
-- schema.cue --
|
||||
package holos
|
||||
|
||||
cluster: string @tag(cluster, string)
|
||||
|
||||
// #OutputTypeMeta is shared among all output types
|
||||
#OutputTypeMeta: {
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: #KubernetesObjects.kind | #NoOutput.kind
|
||||
metadata: name: string
|
||||
}
|
||||
_cluster: string @tag(cluster, string)
|
||||
|
||||
#KubernetesObjects: {
|
||||
#OutputTypeMeta
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "KubernetesObjects"
|
||||
apiObjectMap: {...}
|
||||
}
|
||||
|
||||
#NoOutput: {
|
||||
#OutputTypeMeta
|
||||
kind: string | *"Skip"
|
||||
metadata: name: string | *"skipped"
|
||||
}
|
||||
|
||||
#NoOutput & {}
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
|
||||
15
cmd/holos/testdata/issue15_cue_errors.txt
vendored
15
cmd/holos/testdata/issue15_cue_errors.txt
vendored
@@ -1,16 +1,17 @@
|
||||
# Want cue errors to show files and lines
|
||||
! exec holos build .
|
||||
stderr '^apiObjectMap.foo.bar: cannot convert non-concrete value string'
|
||||
stderr '/component.cue:7:20$'
|
||||
stderr 'apiObjectMap.foo.bar: cannot convert incomplete value'
|
||||
stderr '/component.cue:\d+:\d+$'
|
||||
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "KubernetesObjects"
|
||||
cluster: string @tag(cluster, string)
|
||||
_cluster: string @tag(cluster, string)
|
||||
|
||||
apiObjectMap: foo: bar: baz
|
||||
baz: string
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
spec: components: KubernetesObjectsList: [{apiObjectMap: foo: bar: _baz}]
|
||||
|
||||
_baz: string
|
||||
|
||||
@@ -9,15 +9,17 @@ package holos
|
||||
package holos
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "KubernetesObjects"
|
||||
cluster: string @tag(cluster, string)
|
||||
kind: "BuildPlan"
|
||||
spec: components: KubernetesObjectsList: [{apiObjectMap: #APIObjects.apiObjectMap}]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
|
||||
#SecretStore: {
|
||||
kind: string
|
||||
metadata: name: string
|
||||
}
|
||||
|
||||
#APIObjects & {
|
||||
#APIObjects: {
|
||||
apiObjects: {
|
||||
SecretStore: {
|
||||
default: #SecretStore & { metadata: name: "default" }
|
||||
@@ -54,4 +56,3 @@ import "encoding/yaml"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,17 @@ package holos
|
||||
package holos
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "HelmChart"
|
||||
cluster: string @tag(cluster, string)
|
||||
kind: "BuildPlan"
|
||||
spec: components: HelmChartList: [{apiObjectMap: #APIObjects.apiObjectMap}]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
|
||||
#SecretStore: {
|
||||
kind: string
|
||||
metadata: name: string
|
||||
}
|
||||
|
||||
#APIObjects & {
|
||||
#APIObjects: {
|
||||
apiObjects: {
|
||||
SecretStore: {
|
||||
default: #SecretStore & { metadata: name: "default" }
|
||||
@@ -55,4 +57,3 @@ import "encoding/yaml"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
33
cmd/holos/testdata/issue33_helm_stderr.txt
vendored
33
cmd/holos/testdata/issue33_helm_stderr.txt
vendored
@@ -7,22 +7,27 @@ package holos
|
||||
-- zitadel.cue --
|
||||
package holos
|
||||
|
||||
cluster: string @tag(cluster, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "HelmChart"
|
||||
metadata: name: "zitadel"
|
||||
namespace: "zitadel"
|
||||
chart: {
|
||||
name: "zitadel"
|
||||
version: "7.9.0"
|
||||
release: name
|
||||
repository: {
|
||||
name: "zitadel"
|
||||
url: "https://charts.zitadel.com"
|
||||
}
|
||||
}
|
||||
kind: "BuildPlan"
|
||||
spec: components: HelmChartList: [_HelmChart]
|
||||
|
||||
_cluster: string @tag(cluster, string)
|
||||
|
||||
_HelmChart: {
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "HelmChart"
|
||||
metadata: name: "zitadel"
|
||||
namespace: "zitadel"
|
||||
chart: {
|
||||
name: "zitadel"
|
||||
version: "7.9.0"
|
||||
release: name
|
||||
repository: {
|
||||
name: "zitadel"
|
||||
url: "https://charts.zitadel.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-- vendor/zitadel/templates/secret_zitadel-masterkey.yaml --
|
||||
{{- if (or (and .Values.zitadel.masterkey .Values.zitadel.masterkeySecretName) (and (not .Values.zitadel.masterkey) (not .Values.zitadel.masterkeySecretName)) ) }}
|
||||
|
||||
@@ -9,22 +9,25 @@ package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
|
||||
cluster: string @tag(cluster, string)
|
||||
_cluster: string @tag(cluster, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "KustomizeBuild"
|
||||
metadata: name: "kstest"
|
||||
kind: "BuildPlan"
|
||||
spec: components: KustomizeBuildList: [{metadata: name: "kstest"}]
|
||||
|
||||
-- kustomization.yaml --
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: mynamespace
|
||||
resources:
|
||||
- serviceaccount.yaml
|
||||
|
||||
-- serviceaccount.yaml --
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: test
|
||||
|
||||
-- want.yaml --
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
|
||||
14
cmd/holos/testdata/issue72_disallow_unknown_fields.txt
vendored
Normal file
14
cmd/holos/testdata/issue72_disallow_unknown_fields.txt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# https://github.com/holos-run/holos/issues/72
|
||||
# Want holos to fail on unknown fields to catch typos and aid refactors
|
||||
! exec holos build .
|
||||
stderr 'unknown field \\"TypoKubernetesObjectsList\\"'
|
||||
|
||||
-- cue.mod --
|
||||
package holos
|
||||
-- component.cue --
|
||||
package holos
|
||||
_cluster: string @tag(cluster, string)
|
||||
|
||||
apiVersion: "holos.run/v1alpha1"
|
||||
kind: "BuildPlan"
|
||||
spec: components: TypoKubernetesObjectsList: []
|
||||
37
docs/examples/authpolicy.cue
Normal file
37
docs/examples/authpolicy.cue
Normal file
@@ -0,0 +1,37 @@
|
||||
package holos
|
||||
|
||||
import ap "security.istio.io/authorizationpolicy/v1"
|
||||
|
||||
// #AuthPolicyRules represents AuthorizationPolicy rules for hosts that need specialized treatment. Entries in this struct are exclused from the blank ingressauth AuthorizationPolicy governing the ingressgateway and included in a spcialized policy
|
||||
#AuthPolicyRules: {
|
||||
// AuthProxySpec represents the identity provider configuration
|
||||
AuthProxySpec: #AuthProxySpec & #Platform.authproxy
|
||||
|
||||
// Hosts are hosts that need specialized treatment
|
||||
hosts: {
|
||||
[Name=_]: {
|
||||
// name is the fully qualifed hostname, a Host: header value.
|
||||
name: Name
|
||||
// slug is the resource name prefix
|
||||
slug: string
|
||||
// Refer to https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule
|
||||
spec: ap.#AuthorizationPolicySpec & {
|
||||
action: "CUSTOM"
|
||||
provider: name: AuthProxySpec.provider
|
||||
selector: matchLabels: istio: "ingressgateway"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objects: #APIObjects & {
|
||||
for Host in hosts {
|
||||
apiObjects: {
|
||||
AuthorizationPolicy: "\(Host.slug)-custom": {
|
||||
metadata: namespace: "istio-ingress"
|
||||
metadata: name: "\(Host.slug)-custom"
|
||||
spec: Host.spec
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,189 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-platform-argocd/prod-platform-argocd.gen.yaml
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import "strings"
|
||||
|
||||
// AppProject provides a logical grouping of applications,
|
||||
// providing controls for: * where the apps may deploy to
|
||||
// (cluster whitelist) * what may be deployed (repository
|
||||
// whitelist, resource whitelist/blacklist) * who can access
|
||||
// these applications (roles, OIDC group claims bindings) * and
|
||||
// what they can do (RBAC policies) * automation access to these
|
||||
// roles (JWT tokens)
|
||||
#AppProject: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "argoproj.io/v1alpha1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "AppProject"
|
||||
metadata: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// AppProjectSpec is the specification of an AppProject
|
||||
spec!: #AppProjectSpec
|
||||
}
|
||||
|
||||
// AppProjectSpec is the specification of an AppProject
|
||||
#AppProjectSpec: {
|
||||
// ClusterResourceBlacklist contains list of blacklisted cluster
|
||||
// level resources
|
||||
clusterResourceBlacklist?: [...{
|
||||
group: string
|
||||
kind: string
|
||||
}]
|
||||
|
||||
// ClusterResourceWhitelist contains list of whitelisted cluster
|
||||
// level resources
|
||||
clusterResourceWhitelist?: [...{
|
||||
group: string
|
||||
kind: string
|
||||
}]
|
||||
|
||||
// Description contains optional project description
|
||||
description?: string
|
||||
|
||||
// Destinations contains list of destinations available for
|
||||
// deployment
|
||||
destinations?: [...{
|
||||
// Name is an alternate way of specifying the target cluster by
|
||||
// its symbolic name. This must be set if Server is not set.
|
||||
name?: string
|
||||
|
||||
// Namespace specifies the target namespace for the application's
|
||||
// resources. The namespace will only be set for namespace-scoped
|
||||
// resources that have not set a value for .metadata.namespace
|
||||
namespace?: string
|
||||
|
||||
// Server specifies the URL of the target cluster's Kubernetes
|
||||
// control plane API. This must be set if Name is not set.
|
||||
server?: string
|
||||
}]
|
||||
|
||||
// NamespaceResourceBlacklist contains list of blacklisted
|
||||
// namespace level resources
|
||||
namespaceResourceBlacklist?: [...{
|
||||
group: string
|
||||
kind: string
|
||||
}]
|
||||
|
||||
// NamespaceResourceWhitelist contains list of whitelisted
|
||||
// namespace level resources
|
||||
namespaceResourceWhitelist?: [...{
|
||||
group: string
|
||||
kind: string
|
||||
}]
|
||||
|
||||
// OrphanedResources specifies if controller should monitor
|
||||
// orphaned resources of apps in this project
|
||||
orphanedResources?: {
|
||||
// Ignore contains a list of resources that are to be excluded
|
||||
// from orphaned resources monitoring
|
||||
ignore?: [...{
|
||||
group?: string
|
||||
kind?: string
|
||||
name?: string
|
||||
}]
|
||||
|
||||
// Warn indicates if warning condition should be created for apps
|
||||
// which have orphaned resources
|
||||
warn?: bool
|
||||
}
|
||||
|
||||
// PermitOnlyProjectScopedClusters determines whether destinations
|
||||
// can only reference clusters which are project-scoped
|
||||
permitOnlyProjectScopedClusters?: bool
|
||||
|
||||
// Roles are user defined RBAC roles associated with this project
|
||||
roles?: [...{
|
||||
// Description is a description of the role
|
||||
description?: string
|
||||
|
||||
// Groups are a list of OIDC group claims bound to this role
|
||||
groups?: [...string]
|
||||
|
||||
// JWTTokens are a list of generated JWT tokens bound to this role
|
||||
jwtTokens?: [...{
|
||||
exp?: int
|
||||
iat: int
|
||||
id?: string
|
||||
}]
|
||||
|
||||
// Name is a name for this role
|
||||
name: string
|
||||
|
||||
// Policies Stores a list of casbin formatted strings that define
|
||||
// access policies for the role in the project
|
||||
policies?: [...string]
|
||||
}]
|
||||
|
||||
// SignatureKeys contains a list of PGP key IDs that commits in
|
||||
// Git must be signed with in order to be allowed for sync
|
||||
signatureKeys?: [...{
|
||||
// The ID of the key in hexadecimal notation
|
||||
keyID: string
|
||||
}]
|
||||
|
||||
// SourceNamespaces defines the namespaces application resources
|
||||
// are allowed to be created in
|
||||
sourceNamespaces?: [...string]
|
||||
|
||||
// SourceRepos contains list of repository URLs which can be used
|
||||
// for deployment
|
||||
sourceRepos?: [...string]
|
||||
|
||||
// SyncWindows controls when syncs can be run for apps in this
|
||||
// project
|
||||
syncWindows?: [...{
|
||||
// Applications contains a list of applications that the window
|
||||
// will apply to
|
||||
applications?: [...string]
|
||||
|
||||
// Clusters contains a list of clusters that the window will apply
|
||||
// to
|
||||
clusters?: [...string]
|
||||
|
||||
// Duration is the amount of time the sync window will be open
|
||||
duration?: string
|
||||
|
||||
// Kind defines if the window allows or blocks syncs
|
||||
kind?: string
|
||||
|
||||
// ManualSync enables manual syncs when they would otherwise be
|
||||
// blocked
|
||||
manualSync?: bool
|
||||
|
||||
// Namespaces contains a list of namespaces that the window will
|
||||
// apply to
|
||||
namespaces?: [...string]
|
||||
|
||||
// Schedule is the time the window will begin, specified in cron
|
||||
// format
|
||||
schedule?: string
|
||||
|
||||
// TimeZone of the sync that will be applied to the schedule
|
||||
timeZone?: string
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// BuildPlan is the primary interface between CUE and the Holos cli.
|
||||
#BuildPlan: {
|
||||
#TypeMeta
|
||||
|
||||
// Metadata represents the holos component name
|
||||
metadata?: #ObjectMeta @go(Metadata)
|
||||
spec?: #BuildPlanSpec @go(Spec)
|
||||
}
|
||||
|
||||
#BuildPlanSpec: {
|
||||
disabled?: bool @go(Disabled)
|
||||
components?: #BuildPlanComponents @go(Components)
|
||||
}
|
||||
|
||||
#BuildPlanComponents: {
|
||||
helmChartList?: [...#HelmChart] @go(HelmChartList,[]HelmChart)
|
||||
kubernetesObjectsList?: [...#KubernetesObjects] @go(KubernetesObjectsList,[]KubernetesObjects)
|
||||
kustomizeBuildList?: [...#KustomizeBuild] @go(KustomizeBuildList,[]KustomizeBuild)
|
||||
resources?: {[string]: #KubernetesObjects} @go(Resources,map[string]KubernetesObjects)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// HolosComponent defines the fields common to all holos component kinds including the Render Result.
|
||||
#HolosComponent: {
|
||||
#TypeMeta
|
||||
|
||||
// Metadata represents the holos component name
|
||||
metadata?: #ObjectMeta @go(Metadata)
|
||||
|
||||
// APIObjectMap holds the marshalled representation of api objects. Think of
|
||||
// these as resources overlaid at the back of the render pipeline.
|
||||
apiObjectMap?: #APIObjectMap @go(APIObjectMap)
|
||||
|
||||
#Kustomization
|
||||
|
||||
#Kustomize
|
||||
|
||||
// Skip causes holos to take no action regarding the component.
|
||||
Skip: bool
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
#APIVersion: "holos.run/v1alpha1"
|
||||
#BuildPlanKind: "BuildPlan"
|
||||
#HelmChartKind: "HelmChart"
|
||||
|
||||
// ChartDir is the directory name created in the holos component directory to cache a chart.
|
||||
#ChartDir: "vendor"
|
||||
|
||||
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
|
||||
#ResourcesFile: "resources.yaml"
|
||||
@@ -0,0 +1,6 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
// Package v1alpha1 defines the api boundary between CUE and Holos.
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,28 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// A HelmChart represents a helm command to provide chart values in order to render kubernetes api objects.
|
||||
#HelmChart: {
|
||||
#HolosComponent
|
||||
|
||||
// Namespace is the namespace to install into. TODO: Use metadata.namespace instead.
|
||||
namespace: string @go(Namespace)
|
||||
chart: #Chart @go(Chart)
|
||||
valuesContent: string @go(ValuesContent)
|
||||
enableHooks: bool @go(EnableHooks)
|
||||
}
|
||||
|
||||
#Chart: {
|
||||
name: string @go(Name)
|
||||
version: string @go(Version)
|
||||
release: string @go(Release)
|
||||
repository?: #Repository @go(Repository)
|
||||
}
|
||||
|
||||
#Repository: {
|
||||
name: string @go(Name)
|
||||
url: string @go(URL)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
#KubernetesObjectsKind: "KubernetesObjects"
|
||||
|
||||
// KubernetesObjects represents CUE output which directly provides Kubernetes api objects to holos.
|
||||
#KubernetesObjects: {
|
||||
#HolosComponent
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// Kustomization holds the rendered flux kustomization api object content for git ops.
|
||||
#Kustomization: {
|
||||
// KsContent is the yaml representation of the flux kustomization for gitops.
|
||||
ksContent?: string @go(KsContent)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
#KustomizeBuildKind: "KustomizeBuild"
|
||||
|
||||
// Kustomize represents resources necessary to execute a kustomize build.
|
||||
// Intended for at least two use cases:
|
||||
//
|
||||
// 1. Process raw yaml file resources in a holos component directory.
|
||||
// 2. Post process a HelmChart to inject istio, add custom labels, etc...
|
||||
#Kustomize: {
|
||||
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
|
||||
kustomizeFiles?: #FileContentMap @go(KustomizeFiles)
|
||||
|
||||
// ResourcesFile is the file name used for api objects in kustomization.yaml
|
||||
resourcesFile?: string @go(ResourcesFile)
|
||||
}
|
||||
|
||||
// KustomizeBuild renders plain yaml files in the holos component directory using kubectl kustomize build.
|
||||
#KustomizeBuild: {
|
||||
#HolosComponent
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
#KustomizeBuildKind: "KustomizeBuild"
|
||||
|
||||
// KustomizeBuild
|
||||
#KustomizeBuild: {
|
||||
#HolosComponent
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// Label is an arbitrary unique identifier. Defined as a type for clarity and type checking.
|
||||
#Label: string
|
||||
|
||||
// Kind is a kubernetes api object kind. Defined as a type for clarity and type checking.
|
||||
#Kind: string
|
||||
|
||||
// APIObjectMap is the shape of marshalled api objects returned from cue to the
|
||||
// holos cli. A map is used to improve the clarity of error messages from cue.
|
||||
#APIObjectMap: {[string]: [string]: string}
|
||||
|
||||
// FileContentMap is a map of file names to file contents.
|
||||
#FileContentMap: {[string]: string}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// ObjectMeta represents metadata of a holos component object. The fields are a
|
||||
// copy of upstream kubernetes api machinery but are by holos objects distinct
|
||||
// from kubernetes api objects.
|
||||
#ObjectMeta: {
|
||||
// Name uniquely identifies the holos component instance and must be suitable as a file name.
|
||||
name?: string @go(Name)
|
||||
|
||||
// Namespace confines a holos component to a single namespace via kustomize if set.
|
||||
namespace?: string @go(Namespace)
|
||||
|
||||
// Labels are not used but are copied from api machinery ObjectMeta for completeness.
|
||||
labels?: {[string]: string} @go(Labels,map[string]string)
|
||||
|
||||
// Annotations are not used but are copied from api machinery ObjectMeta for completeness.
|
||||
annotations?: {[string]: string} @go(Annotations,map[string]string)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
#Renderer: _
|
||||
@@ -0,0 +1,10 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// Result is the build result for display or writing. Holos components Render the Result as a data pipeline.
|
||||
#Result: {
|
||||
HolosComponent: #HolosComponent
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Code generated by cue get go. DO NOT EDIT.
|
||||
|
||||
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
|
||||
|
||||
package v1alpha1
|
||||
|
||||
#TypeMeta: {
|
||||
kind?: string @go(Kind)
|
||||
apiVersion?: string @go(APIVersion)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,546 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-platform-monitoring/prod-platform-monitoring.gen.yaml
|
||||
|
||||
package v1
|
||||
|
||||
import "strings"
|
||||
|
||||
// PodMonitor defines monitoring for a set of pods.
|
||||
#PodMonitor: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "monitoring.coreos.com/v1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "PodMonitor"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Specification of desired Pod selection for target discovery by
|
||||
// Prometheus.
|
||||
spec!: #PodMonitorSpec
|
||||
}
|
||||
|
||||
// Specification of desired Pod selection for target discovery by
|
||||
// Prometheus.
|
||||
#PodMonitorSpec: {
|
||||
attachMetadata?: {
|
||||
// When set to true, Prometheus must have the `get` permission on
|
||||
// the `Nodes` objects.
|
||||
node?: bool
|
||||
}
|
||||
|
||||
// The label to use to retrieve the job name from. `jobLabel`
|
||||
// selects the label from the associated Kubernetes `Pod` object
|
||||
// which will be used as the `job` label for all metrics.
|
||||
// For example if `jobLabel` is set to `foo` and the Kubernetes
|
||||
// `Pod` object is labeled with `foo: bar`, then Prometheus adds
|
||||
// the `job="bar"` label to all ingested metrics.
|
||||
// If the value of this field is empty, the `job` label of the
|
||||
// metrics defaults to the namespace and name of the PodMonitor
|
||||
// object (e.g. `<namespace>/<name>`).
|
||||
jobLabel?: string
|
||||
|
||||
// Per-scrape limit on the number of targets dropped by relabeling
|
||||
// that will be kept in memory. 0 means no limit.
|
||||
// It requires Prometheus >= v2.47.0.
|
||||
keepDroppedTargets?: int
|
||||
|
||||
// Per-scrape limit on number of labels that will be accepted for
|
||||
// a sample.
|
||||
// It requires Prometheus >= v2.27.0.
|
||||
labelLimit?: int
|
||||
|
||||
// Per-scrape limit on length of labels name that will be accepted
|
||||
// for a sample.
|
||||
// It requires Prometheus >= v2.27.0.
|
||||
labelNameLengthLimit?: int
|
||||
|
||||
// Per-scrape limit on length of labels value that will be
|
||||
// accepted for a sample.
|
||||
// It requires Prometheus >= v2.27.0.
|
||||
labelValueLengthLimit?: int
|
||||
|
||||
// Selector to select which namespaces the Kubernetes `Pods`
|
||||
// objects are discovered from.
|
||||
namespaceSelector?: {
|
||||
// Boolean describing whether all namespaces are selected in
|
||||
// contrast to a list restricting them.
|
||||
any?: bool
|
||||
|
||||
// List of namespace names to select from.
|
||||
matchNames?: [...string]
|
||||
}
|
||||
|
||||
// List of endpoints part of this PodMonitor.
|
||||
podMetricsEndpoints?: [...{
|
||||
// `authorization` configures the Authorization header credentials
|
||||
// to use when scraping the target.
|
||||
// Cannot be set at the same time as `basicAuth`, or `oauth2`.
|
||||
authorization?: {
|
||||
// Selects a key of a Secret in the namespace that contains the
|
||||
// credentials for authentication.
|
||||
credentials?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Defines the authentication type. The value is case-insensitive.
|
||||
// "Basic" is not a supported value.
|
||||
// Default: "Bearer"
|
||||
type?: string
|
||||
}
|
||||
|
||||
// `basicAuth` configures the Basic Authentication credentials to
|
||||
// use when scraping the target.
|
||||
// Cannot be set at the same time as `authorization`, or `oauth2`.
|
||||
basicAuth?: {
|
||||
// `password` specifies a key of a Secret containing the password
|
||||
// for authentication.
|
||||
password?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// `username` specifies a key of a Secret containing the username
|
||||
// for authentication.
|
||||
username?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// `bearerTokenSecret` specifies a key of a Secret containing the
|
||||
// bearer token for scraping targets. The secret needs to be in
|
||||
// the same namespace as the PodMonitor object and readable by
|
||||
// the Prometheus Operator.
|
||||
// Deprecated: use `authorization` instead.
|
||||
bearerTokenSecret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// `enableHttp2` can be used to disable HTTP2 when scraping the
|
||||
// target.
|
||||
enableHttp2?: bool
|
||||
|
||||
// When true, the pods which are not running (e.g. either in
|
||||
// Failed or Succeeded state) are dropped during the target
|
||||
// discovery.
|
||||
// If unset, the filtering is enabled.
|
||||
// More info:
|
||||
// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
|
||||
filterRunning?: bool
|
||||
|
||||
// `followRedirects` defines whether the scrape requests should
|
||||
// follow HTTP 3xx redirects.
|
||||
followRedirects?: bool
|
||||
|
||||
// When true, `honorLabels` preserves the metric's labels when
|
||||
// they collide with the target's labels.
|
||||
honorLabels?: bool
|
||||
|
||||
// `honorTimestamps` controls whether Prometheus preserves the
|
||||
// timestamps when exposed by the target.
|
||||
honorTimestamps?: bool
|
||||
|
||||
// Interval at which Prometheus scrapes the metrics from the
|
||||
// target.
|
||||
// If empty, Prometheus uses the global scrape interval.
|
||||
interval?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
|
||||
// `metricRelabelings` configures the relabeling rules to apply to
|
||||
// the samples before ingestion.
|
||||
metricRelabelings?: [...{
|
||||
// Action to perform based on the regex matching.
|
||||
// `Uppercase` and `Lowercase` actions require Prometheus >=
|
||||
// v2.36.0. `DropEqual` and `KeepEqual` actions require
|
||||
// Prometheus >= v2.41.0.
|
||||
// Default: "Replace"
|
||||
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
|
||||
|
||||
// Modulus to take of the hash of the source label values.
|
||||
// Only applicable when the action is `HashMod`.
|
||||
modulus?: int
|
||||
|
||||
// Regular expression against which the extracted value is
|
||||
// matched.
|
||||
regex?: string
|
||||
|
||||
// Replacement value against which a Replace action is performed
|
||||
// if the regular expression matches.
|
||||
// Regex capture groups are available.
|
||||
replacement?: string
|
||||
|
||||
// Separator is the string between concatenated SourceLabels.
|
||||
separator?: string
|
||||
|
||||
// The source labels select values from existing labels. Their
|
||||
// content is concatenated using the configured Separator and
|
||||
// matched against the configured regular expression.
|
||||
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
|
||||
|
||||
// Label to which the resulting string is written in a
|
||||
// replacement.
|
||||
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
|
||||
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
|
||||
// Regex capture groups are available.
|
||||
targetLabel?: string
|
||||
}]
|
||||
|
||||
// `oauth2` configures the OAuth2 settings to use when scraping
|
||||
// the target.
|
||||
// It requires Prometheus >= 2.27.0.
|
||||
// Cannot be set at the same time as `authorization`, or
|
||||
// `basicAuth`.
|
||||
oauth2?: {
|
||||
// `clientId` specifies a key of a Secret or ConfigMap containing
|
||||
// the OAuth2 client's ID.
|
||||
clientId: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// `clientSecret` specifies a key of a Secret containing the
|
||||
// OAuth2 client's secret.
|
||||
clientSecret: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// `endpointParams` configures the HTTP parameters to append to
|
||||
// the token URL.
|
||||
endpointParams?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// `scopes` defines the OAuth2 scopes used for the token request.
|
||||
scopes?: [...string]
|
||||
|
||||
// `tokenURL` configures the URL to fetch the token from.
|
||||
tokenUrl: strings.MinRunes(1)
|
||||
}
|
||||
|
||||
// `params` define optional HTTP URL parameters.
|
||||
params?: {
|
||||
[string]: [...string]
|
||||
}
|
||||
|
||||
// HTTP path from which to scrape for metrics.
|
||||
// If empty, Prometheus uses the default value (e.g. `/metrics`).
|
||||
path?: string
|
||||
|
||||
// Name of the Pod port which this endpoint refers to.
|
||||
// It takes precedence over `targetPort`.
|
||||
port?: string
|
||||
|
||||
// `proxyURL` configures the HTTP Proxy URL (e.g.
|
||||
// "http://proxyserver:2195") to go through when scraping the
|
||||
// target.
|
||||
proxyUrl?: string
|
||||
|
||||
// `relabelings` configures the relabeling rules to apply the
|
||||
// target's metadata labels.
|
||||
// The Operator automatically adds relabelings for a few standard
|
||||
// Kubernetes fields.
|
||||
// The original scrape job's name is available via the
|
||||
// `__tmp_prometheus_job_name` label.
|
||||
// More info:
|
||||
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||
relabelings?: [...{
|
||||
// Action to perform based on the regex matching.
|
||||
// `Uppercase` and `Lowercase` actions require Prometheus >=
|
||||
// v2.36.0. `DropEqual` and `KeepEqual` actions require
|
||||
// Prometheus >= v2.41.0.
|
||||
// Default: "Replace"
|
||||
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
|
||||
|
||||
// Modulus to take of the hash of the source label values.
|
||||
// Only applicable when the action is `HashMod`.
|
||||
modulus?: int
|
||||
|
||||
// Regular expression against which the extracted value is
|
||||
// matched.
|
||||
regex?: string
|
||||
|
||||
// Replacement value against which a Replace action is performed
|
||||
// if the regular expression matches.
|
||||
// Regex capture groups are available.
|
||||
replacement?: string
|
||||
|
||||
// Separator is the string between concatenated SourceLabels.
|
||||
separator?: string
|
||||
|
||||
// The source labels select values from existing labels. Their
|
||||
// content is concatenated using the configured Separator and
|
||||
// matched against the configured regular expression.
|
||||
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
|
||||
|
||||
// Label to which the resulting string is written in a
|
||||
// replacement.
|
||||
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
|
||||
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
|
||||
// Regex capture groups are available.
|
||||
targetLabel?: string
|
||||
}]
|
||||
|
||||
// HTTP scheme to use for scraping.
|
||||
// `http` and `https` are the expected values unless you rewrite
|
||||
// the `__scheme__` label via relabeling.
|
||||
// If empty, Prometheus uses the default value `http`.
|
||||
scheme?: "http" | "https"
|
||||
|
||||
// Timeout after which Prometheus considers the scrape to be
|
||||
// failed.
|
||||
// If empty, Prometheus uses the global scrape timeout unless it
|
||||
// is less than the target's scrape interval value in which the
|
||||
// latter is used.
|
||||
scrapeTimeout?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
|
||||
// Name or number of the target port of the `Pod` object behind
|
||||
// the Service, the port must be specified with container port
|
||||
// property.
|
||||
// Deprecated: use 'port' instead.
|
||||
targetPort?: (int | string) & {
|
||||
string
|
||||
}
|
||||
|
||||
// TLS configuration to use when scraping the target.
|
||||
tlsConfig?: {
|
||||
// Certificate authority used when verifying server certificates.
|
||||
ca?: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// Client certificate to present when doing client-authentication.
|
||||
cert?: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// Disable target certificate validation.
|
||||
insecureSkipVerify?: bool
|
||||
|
||||
// Secret containing the client key file for the targets.
|
||||
keySecret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Used to verify the hostname for the targets.
|
||||
serverName?: string
|
||||
}
|
||||
|
||||
// `trackTimestampsStaleness` defines whether Prometheus tracks
|
||||
// staleness of the metrics that have an explicit timestamp
|
||||
// present in scraped data. Has no effect if `honorTimestamps` is
|
||||
// false.
|
||||
// It requires Prometheus >= v2.48.0.
|
||||
trackTimestampsStaleness?: bool
|
||||
}]
|
||||
|
||||
// `podTargetLabels` defines the labels which are transferred from
|
||||
// the associated Kubernetes `Pod` object onto the ingested
|
||||
// metrics.
|
||||
podTargetLabels?: [...string]
|
||||
|
||||
// `sampleLimit` defines a per-scrape limit on the number of
|
||||
// scraped samples that will be accepted.
|
||||
sampleLimit?: int
|
||||
|
||||
// The scrape class to apply.
|
||||
scrapeClass?: strings.MinRunes(1)
|
||||
|
||||
// `scrapeProtocols` defines the protocols to negotiate during a
|
||||
// scrape. It tells clients the protocols supported by Prometheus
|
||||
// in order of preference (from most to least preferred).
|
||||
// If unset, Prometheus uses its default value.
|
||||
// It requires Prometheus >= v2.49.0.
|
||||
scrapeProtocols?: [..."PrometheusProto" | "OpenMetricsText0.0.1" | "OpenMetricsText1.0.0" | "PrometheusText0.0.4"]
|
||||
|
||||
// Label selector to select the Kubernetes `Pod` objects.
|
||||
selector: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// `targetLimit` defines a limit on the number of scraped targets
|
||||
// that will be accepted.
|
||||
targetLimit?: int
|
||||
}
|
||||
@@ -0,0 +1,536 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-platform-monitoring/prod-platform-monitoring.gen.yaml
|
||||
|
||||
package v1
|
||||
|
||||
import "strings"
|
||||
|
||||
// Probe defines monitoring for a set of static targets or
|
||||
// ingresses.
|
||||
#Probe: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "monitoring.coreos.com/v1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "Probe"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Specification of desired Ingress selection for target discovery
|
||||
// by Prometheus.
|
||||
spec!: #ProbeSpec
|
||||
}
|
||||
|
||||
// Specification of desired Ingress selection for target discovery
|
||||
// by Prometheus.
|
||||
#ProbeSpec: {
|
||||
// Authorization section for this endpoint
|
||||
authorization?: {
|
||||
// Selects a key of a Secret in the namespace that contains the
|
||||
// credentials for authentication.
|
||||
credentials?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Defines the authentication type. The value is case-insensitive.
|
||||
// "Basic" is not a supported value.
|
||||
// Default: "Bearer"
|
||||
type?: string
|
||||
}
|
||||
|
||||
// BasicAuth allow an endpoint to authenticate over basic
|
||||
// authentication. More info:
|
||||
// https://prometheus.io/docs/operating/configuration/#endpoint
|
||||
basicAuth?: {
|
||||
// `password` specifies a key of a Secret containing the password
|
||||
// for authentication.
|
||||
password?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// `username` specifies a key of a Secret containing the username
|
||||
// for authentication.
|
||||
username?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// Secret to mount to read bearer token for scraping targets. The
|
||||
// secret needs to be in the same namespace as the probe and
|
||||
// accessible by the Prometheus Operator.
|
||||
bearerTokenSecret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Interval at which targets are probed using the configured
|
||||
// prober. If not specified Prometheus' global scrape interval is
|
||||
// used.
|
||||
interval?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
|
||||
// The job name assigned to scraped metrics by default.
|
||||
jobName?: string
|
||||
|
||||
// Per-scrape limit on the number of targets dropped by relabeling
|
||||
// that will be kept in memory. 0 means no limit.
|
||||
// It requires Prometheus >= v2.47.0.
|
||||
keepDroppedTargets?: int
|
||||
|
||||
// Per-scrape limit on number of labels that will be accepted for
|
||||
// a sample. Only valid in Prometheus versions 2.27.0 and newer.
|
||||
labelLimit?: int
|
||||
|
||||
// Per-scrape limit on length of labels name that will be accepted
|
||||
// for a sample. Only valid in Prometheus versions 2.27.0 and
|
||||
// newer.
|
||||
labelNameLengthLimit?: int
|
||||
|
||||
// Per-scrape limit on length of labels value that will be
|
||||
// accepted for a sample. Only valid in Prometheus versions
|
||||
// 2.27.0 and newer.
|
||||
labelValueLengthLimit?: int
|
||||
|
||||
// MetricRelabelConfigs to apply to samples before ingestion.
|
||||
metricRelabelings?: [...{
|
||||
// Action to perform based on the regex matching.
|
||||
// `Uppercase` and `Lowercase` actions require Prometheus >=
|
||||
// v2.36.0. `DropEqual` and `KeepEqual` actions require
|
||||
// Prometheus >= v2.41.0.
|
||||
// Default: "Replace"
|
||||
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
|
||||
|
||||
// Modulus to take of the hash of the source label values.
|
||||
// Only applicable when the action is `HashMod`.
|
||||
modulus?: int
|
||||
|
||||
// Regular expression against which the extracted value is
|
||||
// matched.
|
||||
regex?: string
|
||||
|
||||
// Replacement value against which a Replace action is performed
|
||||
// if the regular expression matches.
|
||||
// Regex capture groups are available.
|
||||
replacement?: string
|
||||
|
||||
// Separator is the string between concatenated SourceLabels.
|
||||
separator?: string
|
||||
|
||||
// The source labels select values from existing labels. Their
|
||||
// content is concatenated using the configured Separator and
|
||||
// matched against the configured regular expression.
|
||||
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
|
||||
|
||||
// Label to which the resulting string is written in a
|
||||
// replacement.
|
||||
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
|
||||
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
|
||||
// Regex capture groups are available.
|
||||
targetLabel?: string
|
||||
}]
|
||||
|
||||
// The module to use for probing specifying how to probe the
|
||||
// target. Example module configuring in the blackbox exporter:
|
||||
// https://github.com/prometheus/blackbox_exporter/blob/master/example.yml
|
||||
module?: string
|
||||
|
||||
// OAuth2 for the URL. Only valid in Prometheus versions 2.27.0
|
||||
// and newer.
|
||||
oauth2?: {
|
||||
// `clientId` specifies a key of a Secret or ConfigMap containing
|
||||
// the OAuth2 client's ID.
|
||||
clientId: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// `clientSecret` specifies a key of a Secret containing the
|
||||
// OAuth2 client's secret.
|
||||
clientSecret: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// `endpointParams` configures the HTTP parameters to append to
|
||||
// the token URL.
|
||||
endpointParams?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// `scopes` defines the OAuth2 scopes used for the token request.
|
||||
scopes?: [...string]
|
||||
|
||||
// `tokenURL` configures the URL to fetch the token from.
|
||||
tokenUrl: strings.MinRunes(1)
|
||||
}
|
||||
|
||||
// Specification for the prober to use for probing targets. The
|
||||
// prober.URL parameter is required. Targets cannot be probed if
|
||||
// left empty.
|
||||
prober?: {
|
||||
// Path to collect metrics from. Defaults to `/probe`.
|
||||
path?: string | *"/probe"
|
||||
|
||||
// Optional ProxyURL.
|
||||
proxyUrl?: string
|
||||
|
||||
// HTTP scheme to use for scraping. `http` and `https` are the
|
||||
// expected values unless you rewrite the `__scheme__` label via
|
||||
// relabeling. If empty, Prometheus uses the default value
|
||||
// `http`.
|
||||
scheme?: "http" | "https"
|
||||
|
||||
// Mandatory URL of the prober.
|
||||
url: string
|
||||
}
|
||||
|
||||
// SampleLimit defines per-scrape limit on number of scraped
|
||||
// samples that will be accepted.
|
||||
sampleLimit?: int
|
||||
|
||||
// The scrape class to apply.
|
||||
scrapeClass?: strings.MinRunes(1)
|
||||
|
||||
// `scrapeProtocols` defines the protocols to negotiate during a
|
||||
// scrape. It tells clients the protocols supported by Prometheus
|
||||
// in order of preference (from most to least preferred).
|
||||
// If unset, Prometheus uses its default value.
|
||||
// It requires Prometheus >= v2.49.0.
|
||||
scrapeProtocols?: [..."PrometheusProto" | "OpenMetricsText0.0.1" | "OpenMetricsText1.0.0" | "PrometheusText0.0.4"]
|
||||
|
||||
// Timeout for scraping metrics from the Prometheus exporter. If
|
||||
// not specified, the Prometheus global scrape timeout is used.
|
||||
scrapeTimeout?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
|
||||
// TargetLimit defines a limit on the number of scraped targets
|
||||
// that will be accepted.
|
||||
targetLimit?: int
|
||||
|
||||
// Targets defines a set of static or dynamically discovered
|
||||
// targets to probe.
|
||||
targets?: {
|
||||
// ingress defines the Ingress objects to probe and the relabeling
|
||||
// configuration. If `staticConfig` is also defined,
|
||||
// `staticConfig` takes precedence.
|
||||
ingress?: {
|
||||
// From which namespaces to select Ingress objects.
|
||||
namespaceSelector?: {
|
||||
// Boolean describing whether all namespaces are selected in
|
||||
// contrast to a list restricting them.
|
||||
any?: bool
|
||||
|
||||
// List of namespace names to select from.
|
||||
matchNames?: [...string]
|
||||
}
|
||||
|
||||
// RelabelConfigs to apply to the label set of the target before
|
||||
// it gets scraped. The original ingress address is available via
|
||||
// the `__tmp_prometheus_ingress_address` label. It can be used
|
||||
// to customize the probed URL. The original scrape job's name is
|
||||
// available via the `__tmp_prometheus_job_name` label. More
|
||||
// info:
|
||||
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||
relabelingConfigs?: [...{
|
||||
// Action to perform based on the regex matching.
|
||||
// `Uppercase` and `Lowercase` actions require Prometheus >=
|
||||
// v2.36.0. `DropEqual` and `KeepEqual` actions require
|
||||
// Prometheus >= v2.41.0.
|
||||
// Default: "Replace"
|
||||
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
|
||||
|
||||
// Modulus to take of the hash of the source label values.
|
||||
// Only applicable when the action is `HashMod`.
|
||||
modulus?: int
|
||||
|
||||
// Regular expression against which the extracted value is
|
||||
// matched.
|
||||
regex?: string
|
||||
|
||||
// Replacement value against which a Replace action is performed
|
||||
// if the regular expression matches.
|
||||
// Regex capture groups are available.
|
||||
replacement?: string
|
||||
|
||||
// Separator is the string between concatenated SourceLabels.
|
||||
separator?: string
|
||||
|
||||
// The source labels select values from existing labels. Their
|
||||
// content is concatenated using the configured Separator and
|
||||
// matched against the configured regular expression.
|
||||
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
|
||||
|
||||
// Label to which the resulting string is written in a
|
||||
// replacement.
|
||||
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
|
||||
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
|
||||
// Regex capture groups are available.
|
||||
targetLabel?: string
|
||||
}]
|
||||
|
||||
// Selector to select the Ingress objects.
|
||||
selector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// staticConfig defines the static list of targets to probe and
|
||||
// the relabeling configuration. If `ingress` is also defined,
|
||||
// `staticConfig` takes precedence. More info:
|
||||
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#static_config.
|
||||
staticConfig?: {
|
||||
// Labels assigned to all metrics scraped from the targets.
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// RelabelConfigs to apply to the label set of the targets before
|
||||
// it gets scraped. More info:
|
||||
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||
relabelingConfigs?: [...{
|
||||
// Action to perform based on the regex matching.
|
||||
// `Uppercase` and `Lowercase` actions require Prometheus >=
|
||||
// v2.36.0. `DropEqual` and `KeepEqual` actions require
|
||||
// Prometheus >= v2.41.0.
|
||||
// Default: "Replace"
|
||||
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
|
||||
|
||||
// Modulus to take of the hash of the source label values.
|
||||
// Only applicable when the action is `HashMod`.
|
||||
modulus?: int
|
||||
|
||||
// Regular expression against which the extracted value is
|
||||
// matched.
|
||||
regex?: string
|
||||
|
||||
// Replacement value against which a Replace action is performed
|
||||
// if the regular expression matches.
|
||||
// Regex capture groups are available.
|
||||
replacement?: string
|
||||
|
||||
// Separator is the string between concatenated SourceLabels.
|
||||
separator?: string
|
||||
|
||||
// The source labels select values from existing labels. Their
|
||||
// content is concatenated using the configured Separator and
|
||||
// matched against the configured regular expression.
|
||||
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
|
||||
|
||||
// Label to which the resulting string is written in a
|
||||
// replacement.
|
||||
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
|
||||
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
|
||||
// Regex capture groups are available.
|
||||
targetLabel?: string
|
||||
}]
|
||||
|
||||
// The list of hosts to probe.
|
||||
static?: [...string]
|
||||
}
|
||||
}
|
||||
|
||||
// TLS configuration to use when scraping the endpoint.
|
||||
tlsConfig?: {
|
||||
// Certificate authority used when verifying server certificates.
|
||||
ca?: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// Client certificate to present when doing client-authentication.
|
||||
cert?: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// Disable target certificate validation.
|
||||
insecureSkipVerify?: bool
|
||||
|
||||
// Secret containing the client key file for the targets.
|
||||
keySecret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Used to verify the hostname for the targets.
|
||||
serverName?: string
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-platform-monitoring/prod-platform-monitoring.gen.yaml
|
||||
|
||||
package v1
|
||||
|
||||
import "strings"
|
||||
|
||||
// PrometheusRule defines recording and alerting rules for a
|
||||
// Prometheus instance
|
||||
#PrometheusRule: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "monitoring.coreos.com/v1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "PrometheusRule"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Specification of desired alerting rule definitions for
|
||||
// Prometheus.
|
||||
spec!: #PrometheusRuleSpec
|
||||
}
|
||||
#PrometheusRuleSpec: {
|
||||
// Content of Prometheus rule file
|
||||
groups?: [...{
|
||||
// Interval determines how often rules in the group are evaluated.
|
||||
interval?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
|
||||
// Limit the number of alerts an alerting rule and series a
|
||||
// recording rule can produce. Limit is supported starting with
|
||||
// Prometheus >= 2.31 and Thanos Ruler >= 0.24.
|
||||
limit?: int
|
||||
|
||||
// Name of the rule group.
|
||||
name: strings.MinRunes(1)
|
||||
|
||||
// PartialResponseStrategy is only used by ThanosRuler and will be
|
||||
// ignored by Prometheus instances. More info:
|
||||
// https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response
|
||||
partial_response_strategy?: =~"^(?i)(abort|warn)?$"
|
||||
|
||||
// List of alerting and recording rules.
|
||||
rules?: [...{
|
||||
// Name of the alert. Must be a valid label value. Only one of
|
||||
// `record` and `alert` must be set.
|
||||
alert?: string
|
||||
|
||||
// Annotations to add to each alert. Only valid for alerting
|
||||
// rules.
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// PromQL expression to evaluate.
|
||||
expr: (int | string) & {
|
||||
string
|
||||
}
|
||||
|
||||
// Alerts are considered firing once they have been returned for
|
||||
// this long.
|
||||
for?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
|
||||
// KeepFiringFor defines how long an alert will continue firing
|
||||
// after the condition that triggered it has cleared.
|
||||
keep_firing_for?: strings.MinRunes(1) & {
|
||||
=~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
}
|
||||
|
||||
// Labels to add or overwrite.
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// Name of the time series to output to. Must be a valid metric
|
||||
// name. Only one of `record` and `alert` must be set.
|
||||
record?: string
|
||||
}]
|
||||
}]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,566 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/k2/components/prod-platform-monitoring/prod-platform-monitoring.gen.yaml
|
||||
|
||||
package v1
|
||||
|
||||
import "strings"
|
||||
|
||||
// ServiceMonitor defines monitoring for a set of services.
|
||||
#ServiceMonitor: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "monitoring.coreos.com/v1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "ServiceMonitor"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Specification of desired Service selection for target discovery
|
||||
// by Prometheus.
|
||||
spec!: #ServiceMonitorSpec
|
||||
}
|
||||
|
||||
// Specification of desired Service selection for target discovery
|
||||
// by Prometheus.
|
||||
#ServiceMonitorSpec: {
|
||||
attachMetadata?: {
|
||||
// When set to true, Prometheus must have the `get` permission on
|
||||
// the `Nodes` objects.
|
||||
node?: bool
|
||||
}
|
||||
|
||||
// List of endpoints part of this ServiceMonitor.
|
||||
endpoints?: [...{
|
||||
// `authorization` configures the Authorization header credentials
|
||||
// to use when scraping the target.
|
||||
// Cannot be set at the same time as `basicAuth`, or `oauth2`.
|
||||
authorization?: {
|
||||
// Selects a key of a Secret in the namespace that contains the
|
||||
// credentials for authentication.
|
||||
credentials?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Defines the authentication type. The value is case-insensitive.
|
||||
// "Basic" is not a supported value.
|
||||
// Default: "Bearer"
|
||||
type?: string
|
||||
}
|
||||
|
||||
// `basicAuth` configures the Basic Authentication credentials to
|
||||
// use when scraping the target.
|
||||
// Cannot be set at the same time as `authorization`, or `oauth2`.
|
||||
basicAuth?: {
|
||||
// `password` specifies a key of a Secret containing the password
|
||||
// for authentication.
|
||||
password?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// `username` specifies a key of a Secret containing the username
|
||||
// for authentication.
|
||||
username?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// File to read bearer token for scraping the target.
|
||||
// Deprecated: use `authorization` instead.
|
||||
bearerTokenFile?: string
|
||||
|
||||
// `bearerTokenSecret` specifies a key of a Secret containing the
|
||||
// bearer token for scraping targets. The secret needs to be in
|
||||
// the same namespace as the ServiceMonitor object and readable
|
||||
// by the Prometheus Operator.
|
||||
// Deprecated: use `authorization` instead.
|
||||
bearerTokenSecret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// `enableHttp2` can be used to disable HTTP2 when scraping the
|
||||
// target.
|
||||
enableHttp2?: bool
|
||||
|
||||
// When true, the pods which are not running (e.g. either in
|
||||
// Failed or Succeeded state) are dropped during the target
|
||||
// discovery.
|
||||
// If unset, the filtering is enabled.
|
||||
// More info:
|
||||
// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
|
||||
filterRunning?: bool
|
||||
|
||||
// `followRedirects` defines whether the scrape requests should
|
||||
// follow HTTP 3xx redirects.
|
||||
followRedirects?: bool
|
||||
|
||||
// When true, `honorLabels` preserves the metric's labels when
|
||||
// they collide with the target's labels.
|
||||
honorLabels?: bool
|
||||
|
||||
// `honorTimestamps` controls whether Prometheus preserves the
|
||||
// timestamps when exposed by the target.
|
||||
honorTimestamps?: bool
|
||||
|
||||
// Interval at which Prometheus scrapes the metrics from the
|
||||
// target.
|
||||
// If empty, Prometheus uses the global scrape interval.
|
||||
interval?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
|
||||
// `metricRelabelings` configures the relabeling rules to apply to
|
||||
// the samples before ingestion.
|
||||
metricRelabelings?: [...{
|
||||
// Action to perform based on the regex matching.
|
||||
// `Uppercase` and `Lowercase` actions require Prometheus >=
|
||||
// v2.36.0. `DropEqual` and `KeepEqual` actions require
|
||||
// Prometheus >= v2.41.0.
|
||||
// Default: "Replace"
|
||||
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
|
||||
|
||||
// Modulus to take of the hash of the source label values.
|
||||
// Only applicable when the action is `HashMod`.
|
||||
modulus?: int
|
||||
|
||||
// Regular expression against which the extracted value is
|
||||
// matched.
|
||||
regex?: string
|
||||
|
||||
// Replacement value against which a Replace action is performed
|
||||
// if the regular expression matches.
|
||||
// Regex capture groups are available.
|
||||
replacement?: string
|
||||
|
||||
// Separator is the string between concatenated SourceLabels.
|
||||
separator?: string
|
||||
|
||||
// The source labels select values from existing labels. Their
|
||||
// content is concatenated using the configured Separator and
|
||||
// matched against the configured regular expression.
|
||||
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
|
||||
|
||||
// Label to which the resulting string is written in a
|
||||
// replacement.
|
||||
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
|
||||
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
|
||||
// Regex capture groups are available.
|
||||
targetLabel?: string
|
||||
}]
|
||||
|
||||
// `oauth2` configures the OAuth2 settings to use when scraping
|
||||
// the target.
|
||||
// It requires Prometheus >= 2.27.0.
|
||||
// Cannot be set at the same time as `authorization`, or
|
||||
// `basicAuth`.
|
||||
oauth2?: {
|
||||
// `clientId` specifies a key of a Secret or ConfigMap containing
|
||||
// the OAuth2 client's ID.
|
||||
clientId: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// `clientSecret` specifies a key of a Secret containing the
|
||||
// OAuth2 client's secret.
|
||||
clientSecret: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// `endpointParams` configures the HTTP parameters to append to
|
||||
// the token URL.
|
||||
endpointParams?: {
|
||||
[string]: string
|
||||
}
|
||||
|
||||
// `scopes` defines the OAuth2 scopes used for the token request.
|
||||
scopes?: [...string]
|
||||
|
||||
// `tokenURL` configures the URL to fetch the token from.
|
||||
tokenUrl: strings.MinRunes(1)
|
||||
}
|
||||
|
||||
// params define optional HTTP URL parameters.
|
||||
params?: {
|
||||
[string]: [...string]
|
||||
}
|
||||
|
||||
// HTTP path from which to scrape for metrics.
|
||||
// If empty, Prometheus uses the default value (e.g. `/metrics`).
|
||||
path?: string
|
||||
|
||||
// Name of the Service port which this endpoint refers to.
|
||||
// It takes precedence over `targetPort`.
|
||||
port?: string
|
||||
|
||||
// `proxyURL` configures the HTTP Proxy URL (e.g.
|
||||
// "http://proxyserver:2195") to go through when scraping the
|
||||
// target.
|
||||
proxyUrl?: string
|
||||
|
||||
// `relabelings` configures the relabeling rules to apply the
|
||||
// target's metadata labels.
|
||||
// The Operator automatically adds relabelings for a few standard
|
||||
// Kubernetes fields.
|
||||
// The original scrape job's name is available via the
|
||||
// `__tmp_prometheus_job_name` label.
|
||||
// More info:
|
||||
// https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||
relabelings?: [...{
|
||||
// Action to perform based on the regex matching.
|
||||
// `Uppercase` and `Lowercase` actions require Prometheus >=
|
||||
// v2.36.0. `DropEqual` and `KeepEqual` actions require
|
||||
// Prometheus >= v2.41.0.
|
||||
// Default: "Replace"
|
||||
action?: "replace" | "Replace" | "keep" | "Keep" | "drop" | "Drop" | "hashmod" | "HashMod" | "labelmap" | "LabelMap" | "labeldrop" | "LabelDrop" | "labelkeep" | "LabelKeep" | "lowercase" | "Lowercase" | "uppercase" | "Uppercase" | "keepequal" | "KeepEqual" | "dropequal" | "DropEqual" | *"replace"
|
||||
|
||||
// Modulus to take of the hash of the source label values.
|
||||
// Only applicable when the action is `HashMod`.
|
||||
modulus?: int
|
||||
|
||||
// Regular expression against which the extracted value is
|
||||
// matched.
|
||||
regex?: string
|
||||
|
||||
// Replacement value against which a Replace action is performed
|
||||
// if the regular expression matches.
|
||||
// Regex capture groups are available.
|
||||
replacement?: string
|
||||
|
||||
// Separator is the string between concatenated SourceLabels.
|
||||
separator?: string
|
||||
|
||||
// The source labels select values from existing labels. Their
|
||||
// content is concatenated using the configured Separator and
|
||||
// matched against the configured regular expression.
|
||||
sourceLabels?: [...=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]
|
||||
|
||||
// Label to which the resulting string is written in a
|
||||
// replacement.
|
||||
// It is mandatory for `Replace`, `HashMod`, `Lowercase`,
|
||||
// `Uppercase`, `KeepEqual` and `DropEqual` actions.
|
||||
// Regex capture groups are available.
|
||||
targetLabel?: string
|
||||
}]
|
||||
|
||||
// HTTP scheme to use for scraping.
|
||||
// `http` and `https` are the expected values unless you rewrite
|
||||
// the `__scheme__` label via relabeling.
|
||||
// If empty, Prometheus uses the default value `http`.
|
||||
scheme?: "http" | "https"
|
||||
|
||||
// Timeout after which Prometheus considers the scrape to be
|
||||
// failed.
|
||||
// If empty, Prometheus uses the global scrape timeout unless it
|
||||
// is less than the target's scrape interval value in which the
|
||||
// latter is used.
|
||||
scrapeTimeout?: =~"^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$"
|
||||
|
||||
// Name or number of the target port of the `Pod` object behind
|
||||
// the Service. The port must be specified with the container's
|
||||
// port property.
|
||||
targetPort?: (int | string) & {
|
||||
string
|
||||
}
|
||||
|
||||
// TLS configuration to use when scraping the target.
|
||||
tlsConfig?: {
|
||||
// Certificate authority used when verifying server certificates.
|
||||
ca?: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// Path to the CA cert in the Prometheus container to use for the
|
||||
// targets.
|
||||
caFile?: string
|
||||
|
||||
// Client certificate to present when doing client-authentication.
|
||||
cert?: {
|
||||
// ConfigMap containing data to use for the targets.
|
||||
configMap?: {
|
||||
// The key to select.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the ConfigMap or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Secret containing data to use for the targets.
|
||||
secret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
}
|
||||
|
||||
// Path to the client cert file in the Prometheus container for
|
||||
// the targets.
|
||||
certFile?: string
|
||||
|
||||
// Disable target certificate validation.
|
||||
insecureSkipVerify?: bool
|
||||
|
||||
// Path to the client key file in the Prometheus container for the
|
||||
// targets.
|
||||
keyFile?: string
|
||||
|
||||
// Secret containing the client key file for the targets.
|
||||
keySecret?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
// TODO: Add other useful fields. apiVersion, kind, uid?
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Used to verify the hostname for the targets.
|
||||
serverName?: string
|
||||
}
|
||||
|
||||
// `trackTimestampsStaleness` defines whether Prometheus tracks
|
||||
// staleness of the metrics that have an explicit timestamp
|
||||
// present in scraped data. Has no effect if `honorTimestamps` is
|
||||
// false.
|
||||
// It requires Prometheus >= v2.48.0.
|
||||
trackTimestampsStaleness?: bool
|
||||
}]
|
||||
|
||||
// `jobLabel` selects the label from the associated Kubernetes
|
||||
// `Service` object which will be used as the `job` label for all
|
||||
// metrics.
|
||||
// For example if `jobLabel` is set to `foo` and the Kubernetes
|
||||
// `Service` object is labeled with `foo: bar`, then Prometheus
|
||||
// adds the `job="bar"` label to all ingested metrics.
|
||||
// If the value of this field is empty or if the label doesn't
|
||||
// exist for the given Service, the `job` label of the metrics
|
||||
// defaults to the name of the associated Kubernetes `Service`.
|
||||
jobLabel?: string
|
||||
|
||||
// Per-scrape limit on the number of targets dropped by relabeling
|
||||
// that will be kept in memory. 0 means no limit.
|
||||
// It requires Prometheus >= v2.47.0.
|
||||
keepDroppedTargets?: int
|
||||
|
||||
// Per-scrape limit on number of labels that will be accepted for
|
||||
// a sample.
|
||||
// It requires Prometheus >= v2.27.0.
|
||||
labelLimit?: int
|
||||
|
||||
// Per-scrape limit on length of labels name that will be accepted
|
||||
// for a sample.
|
||||
// It requires Prometheus >= v2.27.0.
|
||||
labelNameLengthLimit?: int
|
||||
|
||||
// Per-scrape limit on length of labels value that will be
|
||||
// accepted for a sample.
|
||||
// It requires Prometheus >= v2.27.0.
|
||||
labelValueLengthLimit?: int
|
||||
|
||||
// Selector to select which namespaces the Kubernetes `Endpoints`
|
||||
// objects are discovered from.
|
||||
namespaceSelector?: {
|
||||
// Boolean describing whether all namespaces are selected in
|
||||
// contrast to a list restricting them.
|
||||
any?: bool
|
||||
|
||||
// List of namespace names to select from.
|
||||
matchNames?: [...string]
|
||||
}
|
||||
|
||||
// `podTargetLabels` defines the labels which are transferred from
|
||||
// the associated Kubernetes `Pod` object onto the ingested
|
||||
// metrics.
|
||||
podTargetLabels?: [...string]
|
||||
|
||||
// `sampleLimit` defines a per-scrape limit on the number of
|
||||
// scraped samples that will be accepted.
|
||||
sampleLimit?: int
|
||||
|
||||
// The scrape class to apply.
|
||||
scrapeClass?: strings.MinRunes(1)
|
||||
|
||||
// `scrapeProtocols` defines the protocols to negotiate during a
|
||||
// scrape. It tells clients the protocols supported by Prometheus
|
||||
// in order of preference (from most to least preferred).
|
||||
// If unset, Prometheus uses its default value.
|
||||
// It requires Prometheus >= v2.49.0.
|
||||
scrapeProtocols?: [..."PrometheusProto" | "OpenMetricsText0.0.1" | "OpenMetricsText1.0.0" | "PrometheusText0.0.4"]
|
||||
|
||||
// Label selector to select the Kubernetes `Endpoints` objects.
|
||||
selector: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// `targetLabels` defines the labels which are transferred from
|
||||
// the associated Kubernetes `Service` object onto the ingested
|
||||
// metrics.
|
||||
targetLabels?: [...string]
|
||||
|
||||
// `targetLimit` defines a limit on the number of scraped targets
|
||||
// that will be accepted.
|
||||
targetLimit?: int
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -306,19 +306,10 @@ import "strings"
|
||||
// "value"` for prefix-based match - `regex: "value"` for RE2
|
||||
// style regex-based match
|
||||
// (https://github.com/google/re2/wiki/Syntax).
|
||||
uri?: ({} | {
|
||||
exact: _
|
||||
} | {
|
||||
prefix: _
|
||||
} | {
|
||||
regex: _
|
||||
}) & {
|
||||
uri?: {
|
||||
exact?: string
|
||||
prefix?: string
|
||||
|
||||
// RE2 style regex-based match
|
||||
// (https://github.com/google/re2/wiki/Syntax).
|
||||
regex?: string
|
||||
regex?: string
|
||||
}
|
||||
|
||||
// withoutHeader has the same syntax with the header, but has
|
||||
|
||||
@@ -0,0 +1,975 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/core2/components/prod-pgo-crds/prod-pgo-crds.gen.yaml
|
||||
|
||||
package v1beta1
|
||||
|
||||
import "strings"
|
||||
|
||||
// PGAdmin is the Schema for the pgadmins API
|
||||
#PGAdmin: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "postgres-operator.crunchydata.com/v1beta1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "PGAdmin"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// PGAdminSpec defines the desired state of PGAdmin
|
||||
spec!: #PGAdminSpec
|
||||
}
|
||||
|
||||
// PGAdminSpec defines the desired state of PGAdmin
|
||||
#PGAdminSpec: {
|
||||
// Scheduling constraints of the PGAdmin pod. More info:
|
||||
// https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node
|
||||
affinity?: {
|
||||
// Describes node affinity scheduling rules for the pod.
|
||||
nodeAffinity?: {
|
||||
// The scheduler will prefer to schedule pods to nodes that
|
||||
// satisfy the affinity expressions specified by this field, but
|
||||
// it may choose a node that violates one or more of the
|
||||
// expressions. The node that is most preferred is the one with
|
||||
// the greatest sum of weights, i.e. for each node that meets all
|
||||
// of the scheduling requirements (resource request,
|
||||
// requiredDuringScheduling affinity expressions, etc.), compute
|
||||
// a sum by iterating through the elements of this field and
|
||||
// adding "weight" to the sum if the node matches the
|
||||
// corresponding matchExpressions; the node(s) with the highest
|
||||
// sum are the most preferred.
|
||||
preferredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// A node selector term, associated with the corresponding weight.
|
||||
preference: {
|
||||
// A list of node selector requirements by node's labels.
|
||||
matchExpressions?: [...{
|
||||
// The label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// Represents a key's relationship to a set of values. Valid
|
||||
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
operator: string
|
||||
|
||||
// An array of string values. If the operator is In or NotIn, the
|
||||
// values array must be non-empty. If the operator is Exists or
|
||||
// DoesNotExist, the values array must be empty. If the operator
|
||||
// is Gt or Lt, the values array must have a single element,
|
||||
// which will be interpreted as an integer. This array is
|
||||
// replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// A list of node selector requirements by node's fields.
|
||||
matchFields?: [...{
|
||||
// The label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// Represents a key's relationship to a set of values. Valid
|
||||
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
operator: string
|
||||
|
||||
// An array of string values. If the operator is In or NotIn, the
|
||||
// values array must be non-empty. If the operator is Exists or
|
||||
// DoesNotExist, the values array must be empty. If the operator
|
||||
// is Gt or Lt, the values array must have a single element,
|
||||
// which will be interpreted as an integer. This array is
|
||||
// replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
}
|
||||
|
||||
// Weight associated with matching the corresponding
|
||||
// nodeSelectorTerm, in the range 1-100.
|
||||
weight: int
|
||||
}]
|
||||
requiredDuringSchedulingIgnoredDuringExecution?: {
|
||||
// Required. A list of node selector terms. The terms are ORed.
|
||||
nodeSelectorTerms: [...{
|
||||
// A list of node selector requirements by node's labels.
|
||||
matchExpressions?: [...{
|
||||
// The label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// Represents a key's relationship to a set of values. Valid
|
||||
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
operator: string
|
||||
|
||||
// An array of string values. If the operator is In or NotIn, the
|
||||
// values array must be non-empty. If the operator is Exists or
|
||||
// DoesNotExist, the values array must be empty. If the operator
|
||||
// is Gt or Lt, the values array must have a single element,
|
||||
// which will be interpreted as an integer. This array is
|
||||
// replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// A list of node selector requirements by node's fields.
|
||||
matchFields?: [...{
|
||||
// The label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// Represents a key's relationship to a set of values. Valid
|
||||
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
operator: string
|
||||
|
||||
// An array of string values. If the operator is In or NotIn, the
|
||||
// values array must be non-empty. If the operator is Exists or
|
||||
// DoesNotExist, the values array must be empty. If the operator
|
||||
// is Gt or Lt, the values array must have a single element,
|
||||
// which will be interpreted as an integer. This array is
|
||||
// replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
// Describes pod affinity scheduling rules (e.g. co-locate this
|
||||
// pod in the same node, zone, etc. as some other pod(s)).
|
||||
podAffinity?: {
|
||||
// The scheduler will prefer to schedule pods to nodes that
|
||||
// satisfy the affinity expressions specified by this field, but
|
||||
// it may choose a node that violates one or more of the
|
||||
// expressions. The node that is most preferred is the one with
|
||||
// the greatest sum of weights, i.e. for each node that meets all
|
||||
// of the scheduling requirements (resource request,
|
||||
// requiredDuringScheduling affinity expressions, etc.), compute
|
||||
// a sum by iterating through the elements of this field and
|
||||
// adding "weight" to the sum if the node has pods which matches
|
||||
// the corresponding podAffinityTerm; the node(s) with the
|
||||
// highest sum are the most preferred.
|
||||
preferredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// Required. A pod affinity term, associated with the
|
||||
// corresponding weight.
|
||||
podAffinityTerm: {
|
||||
// A label query over a set of resources, in this case pods.
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A label query over the set of namespaces that the term applies
|
||||
// to. The term is applied to the union of the namespaces
|
||||
// selected by this field and the ones listed in the namespaces
|
||||
// field. null selector and null or empty namespaces list means
|
||||
// "this pod's namespace". An empty selector ({}) matches all
|
||||
// namespaces.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// namespaces specifies a static list of namespace names that the
|
||||
// term applies to. The term is applied to the union of the
|
||||
// namespaces listed in this field and the ones selected by
|
||||
// namespaceSelector. null or empty namespaces list and null
|
||||
// namespaceSelector means "this pod's namespace".
|
||||
namespaces?: [...string]
|
||||
|
||||
// This pod should be co-located (affinity) or not co-located
|
||||
// (anti-affinity) with the pods matching the labelSelector in
|
||||
// the specified namespaces, where co-located is defined as
|
||||
// running on a node whose value of the label with key
|
||||
// topologyKey matches that of any node on which any of the
|
||||
// selected pods is running. Empty topologyKey is not allowed.
|
||||
topologyKey: string
|
||||
}
|
||||
|
||||
// weight associated with matching the corresponding
|
||||
// podAffinityTerm, in the range 1-100.
|
||||
weight: int
|
||||
}]
|
||||
|
||||
// If the affinity requirements specified by this field are not
|
||||
// met at scheduling time, the pod will not be scheduled onto the
|
||||
// node. If the affinity requirements specified by this field
|
||||
// cease to be met at some point during pod execution (e.g. due
|
||||
// to a pod label update), the system may or may not try to
|
||||
// eventually evict the pod from its node. When there are
|
||||
// multiple elements, the lists of nodes corresponding to each
|
||||
// podAffinityTerm are intersected, i.e. all terms must be
|
||||
// satisfied.
|
||||
requiredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// A label query over a set of resources, in this case pods.
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A label query over the set of namespaces that the term applies
|
||||
// to. The term is applied to the union of the namespaces
|
||||
// selected by this field and the ones listed in the namespaces
|
||||
// field. null selector and null or empty namespaces list means
|
||||
// "this pod's namespace". An empty selector ({}) matches all
|
||||
// namespaces.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// namespaces specifies a static list of namespace names that the
|
||||
// term applies to. The term is applied to the union of the
|
||||
// namespaces listed in this field and the ones selected by
|
||||
// namespaceSelector. null or empty namespaces list and null
|
||||
// namespaceSelector means "this pod's namespace".
|
||||
namespaces?: [...string]
|
||||
|
||||
// This pod should be co-located (affinity) or not co-located
|
||||
// (anti-affinity) with the pods matching the labelSelector in
|
||||
// the specified namespaces, where co-located is defined as
|
||||
// running on a node whose value of the label with key
|
||||
// topologyKey matches that of any node on which any of the
|
||||
// selected pods is running. Empty topologyKey is not allowed.
|
||||
topologyKey: string
|
||||
}]
|
||||
}
|
||||
|
||||
// Describes pod anti-affinity scheduling rules (e.g. avoid
|
||||
// putting this pod in the same node, zone, etc. as some other
|
||||
// pod(s)).
|
||||
podAntiAffinity?: {
|
||||
// The scheduler will prefer to schedule pods to nodes that
|
||||
// satisfy the anti-affinity expressions specified by this field,
|
||||
// but it may choose a node that violates one or more of the
|
||||
// expressions. The node that is most preferred is the one with
|
||||
// the greatest sum of weights, i.e. for each node that meets all
|
||||
// of the scheduling requirements (resource request,
|
||||
// requiredDuringScheduling anti-affinity expressions, etc.),
|
||||
// compute a sum by iterating through the elements of this field
|
||||
// and adding "weight" to the sum if the node has pods which
|
||||
// matches the corresponding podAffinityTerm; the node(s) with
|
||||
// the highest sum are the most preferred.
|
||||
preferredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// Required. A pod affinity term, associated with the
|
||||
// corresponding weight.
|
||||
podAffinityTerm: {
|
||||
// A label query over a set of resources, in this case pods.
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A label query over the set of namespaces that the term applies
|
||||
// to. The term is applied to the union of the namespaces
|
||||
// selected by this field and the ones listed in the namespaces
|
||||
// field. null selector and null or empty namespaces list means
|
||||
// "this pod's namespace". An empty selector ({}) matches all
|
||||
// namespaces.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// namespaces specifies a static list of namespace names that the
|
||||
// term applies to. The term is applied to the union of the
|
||||
// namespaces listed in this field and the ones selected by
|
||||
// namespaceSelector. null or empty namespaces list and null
|
||||
// namespaceSelector means "this pod's namespace".
|
||||
namespaces?: [...string]
|
||||
|
||||
// This pod should be co-located (affinity) or not co-located
|
||||
// (anti-affinity) with the pods matching the labelSelector in
|
||||
// the specified namespaces, where co-located is defined as
|
||||
// running on a node whose value of the label with key
|
||||
// topologyKey matches that of any node on which any of the
|
||||
// selected pods is running. Empty topologyKey is not allowed.
|
||||
topologyKey: string
|
||||
}
|
||||
|
||||
// weight associated with matching the corresponding
|
||||
// podAffinityTerm, in the range 1-100.
|
||||
weight: int
|
||||
}]
|
||||
|
||||
// If the anti-affinity requirements specified by this field are
|
||||
// not met at scheduling time, the pod will not be scheduled onto
|
||||
// the node. If the anti-affinity requirements specified by this
|
||||
// field cease to be met at some point during pod execution (e.g.
|
||||
// due to a pod label update), the system may or may not try to
|
||||
// eventually evict the pod from its node. When there are
|
||||
// multiple elements, the lists of nodes corresponding to each
|
||||
// podAffinityTerm are intersected, i.e. all terms must be
|
||||
// satisfied.
|
||||
requiredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// A label query over a set of resources, in this case pods.
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A label query over the set of namespaces that the term applies
|
||||
// to. The term is applied to the union of the namespaces
|
||||
// selected by this field and the ones listed in the namespaces
|
||||
// field. null selector and null or empty namespaces list means
|
||||
// "this pod's namespace". An empty selector ({}) matches all
|
||||
// namespaces.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// namespaces specifies a static list of namespace names that the
|
||||
// term applies to. The term is applied to the union of the
|
||||
// namespaces listed in this field and the ones selected by
|
||||
// namespaceSelector. null or empty namespaces list and null
|
||||
// namespaceSelector means "this pod's namespace".
|
||||
namespaces?: [...string]
|
||||
|
||||
// This pod should be co-located (affinity) or not co-located
|
||||
// (anti-affinity) with the pods matching the labelSelector in
|
||||
// the specified namespaces, where co-located is defined as
|
||||
// running on a node whose value of the label with key
|
||||
// topologyKey matches that of any node on which any of the
|
||||
// selected pods is running. Empty topologyKey is not allowed.
|
||||
topologyKey: string
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
// Configuration settings for the pgAdmin process. Changes to any
|
||||
// of these values will be loaded without validation. Be careful,
|
||||
// as you may put pgAdmin into an unusable state.
|
||||
config?: {
|
||||
// Files allows the user to mount projected volumes into the
|
||||
// pgAdmin container so that files can be referenced by pgAdmin
|
||||
// as needed.
|
||||
files?: [...{
|
||||
// configMap information about the configMap data to project
|
||||
configMap?: {
|
||||
// items if unspecified, each key-value pair in the Data field of
|
||||
// the referenced ConfigMap will be projected into the volume as
|
||||
// a file whose name is the key and content is the value. If
|
||||
// specified, the listed keys will be projected into the
|
||||
// specified paths, and unlisted keys will not be present. If a
|
||||
// key is specified which is not present in the ConfigMap, the
|
||||
// volume setup will error unless it is marked optional. Paths
|
||||
// must be relative and may not contain the '..' path or start
|
||||
// with '..'.
|
||||
items?: [...{
|
||||
// key is the key to project.
|
||||
key: string
|
||||
|
||||
// mode is Optional: mode bits used to set permissions on this
|
||||
// file. Must be an octal value between 0000 and 0777 or a
|
||||
// decimal value between 0 and 511. YAML accepts both octal and
|
||||
// decimal values, JSON requires decimal values for mode bits. If
|
||||
// not specified, the volume defaultMode will be used. This might
|
||||
// be in conflict with other options that affect the file mode,
|
||||
// like fsGroup, and the result can be other mode bits set.
|
||||
mode?: int
|
||||
|
||||
// path is the relative path of the file to map the key to. May
|
||||
// not be an absolute path. May not contain the path element
|
||||
// '..'. May not start with the string '..'.
|
||||
path: string
|
||||
}]
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
name?: string
|
||||
|
||||
// optional specify whether the ConfigMap or its keys must be
|
||||
// defined
|
||||
optional?: bool
|
||||
}
|
||||
downwardAPI?: {
|
||||
// Items is a list of DownwardAPIVolume file
|
||||
items?: [...{
|
||||
// Required: Selects a field of the pod: only annotations, labels,
|
||||
// name and namespace are supported.
|
||||
fieldRef?: {
|
||||
// Version of the schema the FieldPath is written in terms of,
|
||||
// defaults to "v1".
|
||||
apiVersion?: string
|
||||
|
||||
// Path of the field to select in the specified API version.
|
||||
fieldPath: string
|
||||
}
|
||||
|
||||
// Optional: mode bits used to set permissions on this file, must
|
||||
// be an octal value between 0000 and 0777 or a decimal value
|
||||
// between 0 and 511. YAML accepts both octal and decimal values,
|
||||
// JSON requires decimal values for mode bits. If not specified,
|
||||
// the volume defaultMode will be used. This might be in conflict
|
||||
// with other options that affect the file mode, like fsGroup,
|
||||
// and the result can be other mode bits set.
|
||||
mode?: int
|
||||
|
||||
// Required: Path is the relative path name of the file to be
|
||||
// created. Must not be absolute or contain the '..' path. Must
|
||||
// be utf-8 encoded. The first item of the relative path must not
|
||||
// start with '..'
|
||||
path: string
|
||||
|
||||
// Selects a resource of the container: only resources limits and
|
||||
// requests (limits.cpu, limits.memory, requests.cpu and
|
||||
// requests.memory) are currently supported.
|
||||
resourceFieldRef?: {
|
||||
// Container name: required for volumes, optional for env vars
|
||||
containerName?: string
|
||||
|
||||
// Specifies the output format of the exposed resources, defaults
|
||||
// to "1"
|
||||
divisor?: (int | string) & {
|
||||
=~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
|
||||
}
|
||||
|
||||
// Required: resource to select
|
||||
resource: string
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
// secret information about the secret data to project
|
||||
secret?: {
|
||||
// items if unspecified, each key-value pair in the Data field of
|
||||
// the referenced Secret will be projected into the volume as a
|
||||
// file whose name is the key and content is the value. If
|
||||
// specified, the listed keys will be projected into the
|
||||
// specified paths, and unlisted keys will not be present. If a
|
||||
// key is specified which is not present in the Secret, the
|
||||
// volume setup will error unless it is marked optional. Paths
|
||||
// must be relative and may not contain the '..' path or start
|
||||
// with '..'.
|
||||
items?: [...{
|
||||
// key is the key to project.
|
||||
key: string
|
||||
|
||||
// mode is Optional: mode bits used to set permissions on this
|
||||
// file. Must be an octal value between 0000 and 0777 or a
|
||||
// decimal value between 0 and 511. YAML accepts both octal and
|
||||
// decimal values, JSON requires decimal values for mode bits. If
|
||||
// not specified, the volume defaultMode will be used. This might
|
||||
// be in conflict with other options that affect the file mode,
|
||||
// like fsGroup, and the result can be other mode bits set.
|
||||
mode?: int
|
||||
|
||||
// path is the relative path of the file to map the key to. May
|
||||
// not be an absolute path. May not contain the path element
|
||||
// '..'. May not start with the string '..'.
|
||||
path: string
|
||||
}]
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
name?: string
|
||||
|
||||
// optional field specify whether the Secret or its key must be
|
||||
// defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// serviceAccountToken is information about the
|
||||
// serviceAccountToken data to project
|
||||
serviceAccountToken?: {
|
||||
// audience is the intended audience of the token. A recipient of
|
||||
// a token must identify itself with an identifier specified in
|
||||
// the audience of the token, and otherwise should reject the
|
||||
// token. The audience defaults to the identifier of the
|
||||
// apiserver.
|
||||
audience?: string
|
||||
|
||||
// expirationSeconds is the requested duration of validity of the
|
||||
// service account token. As the token approaches expiration, the
|
||||
// kubelet volume plugin will proactively rotate the service
|
||||
// account token. The kubelet will start trying to rotate the
|
||||
// token if the token is older than 80 percent of its time to
|
||||
// live or if the token is older than 24 hours.Defaults to 1 hour
|
||||
// and must be at least 10 minutes.
|
||||
expirationSeconds?: int
|
||||
|
||||
// path is the path relative to the mount point of the file to
|
||||
// project the token into.
|
||||
path: string
|
||||
}
|
||||
}]
|
||||
|
||||
// A Secret containing the value for the LDAP_BIND_PASSWORD
|
||||
// setting. More info:
|
||||
// https://www.pgadmin.org/docs/pgadmin4/latest/ldap.html
|
||||
ldapBindPassword?: {
|
||||
// The key of the secret to select from. Must be a valid secret
|
||||
// key.
|
||||
key: string
|
||||
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
name?: string
|
||||
|
||||
// Specify whether the Secret or its key must be defined
|
||||
optional?: bool
|
||||
}
|
||||
|
||||
// Settings for the pgAdmin server process. Keys should be
|
||||
// uppercase and values must be constants. More info:
|
||||
// https://www.pgadmin.org/docs/pgadmin4/latest/config_py.html
|
||||
settings?: {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
// Defines a PersistentVolumeClaim for pgAdmin data. More info:
|
||||
// https://kubernetes.io/docs/concepts/storage/persistent-volumes
|
||||
dataVolumeClaimSpec: {
|
||||
// accessModes contains the desired access modes the volume should
|
||||
// have. More info:
|
||||
// https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
|
||||
accessModes?: [...string]
|
||||
|
||||
// dataSource field can be used to specify either: * An existing
|
||||
// VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
|
||||
// * An existing PVC (PersistentVolumeClaim) If the provisioner
|
||||
// or an external controller can support the specified data
|
||||
// source, it will create a new volume based on the contents of
|
||||
// the specified data source. If the AnyVolumeDataSource feature
|
||||
// gate is enabled, this field will always have the same contents
|
||||
// as the DataSourceRef field.
|
||||
dataSource?: {
|
||||
// APIGroup is the group for the resource being referenced. If
|
||||
// APIGroup is not specified, the specified Kind must be in the
|
||||
// core API group. For any other third-party types, APIGroup is
|
||||
// required.
|
||||
apiGroup?: string
|
||||
|
||||
// Kind is the type of resource being referenced
|
||||
kind: string
|
||||
|
||||
// Name is the name of resource being referenced
|
||||
name: string
|
||||
}
|
||||
|
||||
// dataSourceRef specifies the object from which to populate the
|
||||
// volume with data, if a non-empty volume is desired. This may
|
||||
// be any local object from a non-empty API group (non core
|
||||
// object) or a PersistentVolumeClaim object. When this field is
|
||||
// specified, volume binding will only succeed if the type of the
|
||||
// specified object matches some installed volume populator or
|
||||
// dynamic provisioner. This field will replace the functionality
|
||||
// of the DataSource field and as such if both fields are
|
||||
// non-empty, they must have the same value. For backwards
|
||||
// compatibility, both fields (DataSource and DataSourceRef) will
|
||||
// be set to the same value automatically if one of them is empty
|
||||
// and the other is non-empty. There are two important
|
||||
// differences between DataSource and DataSourceRef: * While
|
||||
// DataSource only allows two specific types of objects,
|
||||
// DataSourceRef allows any non-core object, as well as
|
||||
// PersistentVolumeClaim objects. * While DataSource ignores
|
||||
// disallowed values (dropping them), DataSourceRef preserves all
|
||||
// values, and generates an error if a disallowed value is
|
||||
// specified. (Beta) Using this field requires the
|
||||
// AnyVolumeDataSource feature gate to be enabled.
|
||||
dataSourceRef?: {
|
||||
// APIGroup is the group for the resource being referenced. If
|
||||
// APIGroup is not specified, the specified Kind must be in the
|
||||
// core API group. For any other third-party types, APIGroup is
|
||||
// required.
|
||||
apiGroup?: string
|
||||
|
||||
// Kind is the type of resource being referenced
|
||||
kind: string
|
||||
|
||||
// Name is the name of resource being referenced
|
||||
name: string
|
||||
}
|
||||
|
||||
// resources represents the minimum resources the volume should
|
||||
// have. If RecoverVolumeExpansionFailure feature is enabled
|
||||
// users are allowed to specify resource requirements that are
|
||||
// lower than previous value but must still be higher than
|
||||
// capacity recorded in the status field of the claim. More info:
|
||||
// https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
|
||||
resources?: {
|
||||
// Limits describes the maximum amount of compute resources
|
||||
// allowed. More info:
|
||||
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
limits?: {
|
||||
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
|
||||
}
|
||||
|
||||
// Requests describes the minimum amount of compute resources
|
||||
// required. If Requests is omitted for a container, it defaults
|
||||
// to Limits if that is explicitly specified, otherwise to an
|
||||
// implementation-defined value. More info:
|
||||
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
requests?: {
|
||||
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
|
||||
}
|
||||
}
|
||||
|
||||
// selector is a label query over volumes to consider for binding.
|
||||
selector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// storageClassName is the name of the StorageClass required by
|
||||
// the claim. More info:
|
||||
// https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
|
||||
storageClassName?: string
|
||||
|
||||
// volumeMode defines what type of volume is required by the
|
||||
// claim. Value of Filesystem is implied when not included in
|
||||
// claim spec.
|
||||
volumeMode?: string
|
||||
|
||||
// volumeName is the binding reference to the PersistentVolume
|
||||
// backing this claim.
|
||||
volumeName?: string
|
||||
}
|
||||
|
||||
// The image name to use for pgAdmin instance.
|
||||
image?: string
|
||||
|
||||
// ImagePullPolicy is used to determine when Kubernetes will
|
||||
// attempt to pull (download) container images. More info:
|
||||
// https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy
|
||||
imagePullPolicy?: "Always" | "Never" | "IfNotPresent"
|
||||
|
||||
// The image pull secrets used to pull from a private registry.
|
||||
// Changing this value causes all running PGAdmin pods to
|
||||
// restart.
|
||||
// https://k8s.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
||||
imagePullSecrets?: [...{
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
name?: string
|
||||
}]
|
||||
|
||||
// Metadata contains metadata for custom resources
|
||||
metadata?: {
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// Priority class name for the PGAdmin pod. Changing this value
|
||||
// causes PGAdmin pod to restart. More info:
|
||||
// https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/
|
||||
priorityClassName?: string
|
||||
|
||||
// Resource requirements for the PGAdmin container.
|
||||
resources?: {
|
||||
// Limits describes the maximum amount of compute resources
|
||||
// allowed. More info:
|
||||
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
limits?: {
|
||||
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
|
||||
}
|
||||
|
||||
// Requests describes the minimum amount of compute resources
|
||||
// required. If Requests is omitted for a container, it defaults
|
||||
// to Limits if that is explicitly specified, otherwise to an
|
||||
// implementation-defined value. More info:
|
||||
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
requests?: {
|
||||
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
|
||||
}
|
||||
}
|
||||
|
||||
// ServerGroups for importing PostgresClusters to pgAdmin. To
|
||||
// create a pgAdmin with no selectors, leave this field empty. A
|
||||
// pgAdmin created with no `ServerGroups` will not automatically
|
||||
// add any servers through discovery. PostgresClusters can still
|
||||
// be added manually.
|
||||
serverGroups?: [...{
|
||||
// The name for the ServerGroup in pgAdmin. Must be unique in the
|
||||
// pgAdmin's ServerGroups since it becomes the ServerGroup name
|
||||
// in pgAdmin.
|
||||
name: string
|
||||
|
||||
// PostgresClusterSelector selects clusters to dynamically add to
|
||||
// pgAdmin by matching labels. An empty selector like `{}` will
|
||||
// select ALL clusters in the namespace.
|
||||
postgresClusterSelector: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// Tolerations of the PGAdmin pod. More info:
|
||||
// https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
|
||||
tolerations?: [...{
|
||||
// Effect indicates the taint effect to match. Empty means match
|
||||
// all taint effects. When specified, allowed values are
|
||||
// NoSchedule, PreferNoSchedule and NoExecute.
|
||||
effect?: string
|
||||
|
||||
// Key is the taint key that the toleration applies to. Empty
|
||||
// means match all taint keys. If the key is empty, operator must
|
||||
// be Exists; this combination means to match all values and all
|
||||
// keys.
|
||||
key?: string
|
||||
|
||||
// Operator represents a key's relationship to the value. Valid
|
||||
// operators are Exists and Equal. Defaults to Equal. Exists is
|
||||
// equivalent to wildcard for value, so that a pod can tolerate
|
||||
// all taints of a particular category.
|
||||
operator?: string
|
||||
|
||||
// TolerationSeconds represents the period of time the toleration
|
||||
// (which must be of effect NoExecute, otherwise this field is
|
||||
// ignored) tolerates the taint. By default, it is not set, which
|
||||
// means tolerate the taint forever (do not evict). Zero and
|
||||
// negative values will be treated as 0 (evict immediately) by
|
||||
// the system.
|
||||
tolerationSeconds?: int
|
||||
|
||||
// Value is the taint value the toleration matches to. If the
|
||||
// operator is Exists, the value should be empty, otherwise just
|
||||
// a regular string.
|
||||
value?: string
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,632 @@
|
||||
// Code generated by timoni. DO NOT EDIT.
|
||||
|
||||
//timoni:generate timoni vendor crd -f /home/jeff/workspace/holos-run/holos-infra/deploy/clusters/core2/components/prod-pgo-crds/prod-pgo-crds.gen.yaml
|
||||
|
||||
package v1beta1
|
||||
|
||||
import "strings"
|
||||
|
||||
// PGUpgrade is the Schema for the pgupgrades API
|
||||
#PGUpgrade: {
|
||||
// APIVersion defines the versioned schema of this representation
|
||||
// of an object. Servers should convert recognized schemas to the
|
||||
// latest internal value, and may reject unrecognized values.
|
||||
// More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
apiVersion: "postgres-operator.crunchydata.com/v1beta1"
|
||||
|
||||
// Kind is a string value representing the REST resource this
|
||||
// object represents. Servers may infer this from the endpoint
|
||||
// the client submits requests to. Cannot be updated. In
|
||||
// CamelCase. More info:
|
||||
// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
kind: "PGUpgrade"
|
||||
metadata!: {
|
||||
name!: strings.MaxRunes(253) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
namespace!: strings.MaxRunes(63) & strings.MinRunes(1) & {
|
||||
string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// PGUpgradeSpec defines the desired state of PGUpgrade
|
||||
spec!: #PGUpgradeSpec
|
||||
}
|
||||
|
||||
// PGUpgradeSpec defines the desired state of PGUpgrade
|
||||
#PGUpgradeSpec: {
|
||||
// Scheduling constraints of the PGUpgrade pod. More info:
|
||||
// https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node
|
||||
affinity?: {
|
||||
// Describes node affinity scheduling rules for the pod.
|
||||
nodeAffinity?: {
|
||||
// The scheduler will prefer to schedule pods to nodes that
|
||||
// satisfy the affinity expressions specified by this field, but
|
||||
// it may choose a node that violates one or more of the
|
||||
// expressions. The node that is most preferred is the one with
|
||||
// the greatest sum of weights, i.e. for each node that meets all
|
||||
// of the scheduling requirements (resource request,
|
||||
// requiredDuringScheduling affinity expressions, etc.), compute
|
||||
// a sum by iterating through the elements of this field and
|
||||
// adding "weight" to the sum if the node matches the
|
||||
// corresponding matchExpressions; the node(s) with the highest
|
||||
// sum are the most preferred.
|
||||
preferredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// A node selector term, associated with the corresponding weight.
|
||||
preference: {
|
||||
// A list of node selector requirements by node's labels.
|
||||
matchExpressions?: [...{
|
||||
// The label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// Represents a key's relationship to a set of values. Valid
|
||||
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
operator: string
|
||||
|
||||
// An array of string values. If the operator is In or NotIn, the
|
||||
// values array must be non-empty. If the operator is Exists or
|
||||
// DoesNotExist, the values array must be empty. If the operator
|
||||
// is Gt or Lt, the values array must have a single element,
|
||||
// which will be interpreted as an integer. This array is
|
||||
// replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// A list of node selector requirements by node's fields.
|
||||
matchFields?: [...{
|
||||
// The label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// Represents a key's relationship to a set of values. Valid
|
||||
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
operator: string
|
||||
|
||||
// An array of string values. If the operator is In or NotIn, the
|
||||
// values array must be non-empty. If the operator is Exists or
|
||||
// DoesNotExist, the values array must be empty. If the operator
|
||||
// is Gt or Lt, the values array must have a single element,
|
||||
// which will be interpreted as an integer. This array is
|
||||
// replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
}
|
||||
|
||||
// Weight associated with matching the corresponding
|
||||
// nodeSelectorTerm, in the range 1-100.
|
||||
weight: int
|
||||
}]
|
||||
requiredDuringSchedulingIgnoredDuringExecution?: {
|
||||
// Required. A list of node selector terms. The terms are ORed.
|
||||
nodeSelectorTerms: [...{
|
||||
// A list of node selector requirements by node's labels.
|
||||
matchExpressions?: [...{
|
||||
// The label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// Represents a key's relationship to a set of values. Valid
|
||||
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
operator: string
|
||||
|
||||
// An array of string values. If the operator is In or NotIn, the
|
||||
// values array must be non-empty. If the operator is Exists or
|
||||
// DoesNotExist, the values array must be empty. If the operator
|
||||
// is Gt or Lt, the values array must have a single element,
|
||||
// which will be interpreted as an integer. This array is
|
||||
// replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// A list of node selector requirements by node's fields.
|
||||
matchFields?: [...{
|
||||
// The label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// Represents a key's relationship to a set of values. Valid
|
||||
// operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
operator: string
|
||||
|
||||
// An array of string values. If the operator is In or NotIn, the
|
||||
// values array must be non-empty. If the operator is Exists or
|
||||
// DoesNotExist, the values array must be empty. If the operator
|
||||
// is Gt or Lt, the values array must have a single element,
|
||||
// which will be interpreted as an integer. This array is
|
||||
// replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
// Describes pod affinity scheduling rules (e.g. co-locate this
|
||||
// pod in the same node, zone, etc. as some other pod(s)).
|
||||
podAffinity?: {
|
||||
// The scheduler will prefer to schedule pods to nodes that
|
||||
// satisfy the affinity expressions specified by this field, but
|
||||
// it may choose a node that violates one or more of the
|
||||
// expressions. The node that is most preferred is the one with
|
||||
// the greatest sum of weights, i.e. for each node that meets all
|
||||
// of the scheduling requirements (resource request,
|
||||
// requiredDuringScheduling affinity expressions, etc.), compute
|
||||
// a sum by iterating through the elements of this field and
|
||||
// adding "weight" to the sum if the node has pods which matches
|
||||
// the corresponding podAffinityTerm; the node(s) with the
|
||||
// highest sum are the most preferred.
|
||||
preferredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// Required. A pod affinity term, associated with the
|
||||
// corresponding weight.
|
||||
podAffinityTerm: {
|
||||
// A label query over a set of resources, in this case pods.
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A label query over the set of namespaces that the term applies
|
||||
// to. The term is applied to the union of the namespaces
|
||||
// selected by this field and the ones listed in the namespaces
|
||||
// field. null selector and null or empty namespaces list means
|
||||
// "this pod's namespace". An empty selector ({}) matches all
|
||||
// namespaces.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// namespaces specifies a static list of namespace names that the
|
||||
// term applies to. The term is applied to the union of the
|
||||
// namespaces listed in this field and the ones selected by
|
||||
// namespaceSelector. null or empty namespaces list and null
|
||||
// namespaceSelector means "this pod's namespace".
|
||||
namespaces?: [...string]
|
||||
|
||||
// This pod should be co-located (affinity) or not co-located
|
||||
// (anti-affinity) with the pods matching the labelSelector in
|
||||
// the specified namespaces, where co-located is defined as
|
||||
// running on a node whose value of the label with key
|
||||
// topologyKey matches that of any node on which any of the
|
||||
// selected pods is running. Empty topologyKey is not allowed.
|
||||
topologyKey: string
|
||||
}
|
||||
|
||||
// weight associated with matching the corresponding
|
||||
// podAffinityTerm, in the range 1-100.
|
||||
weight: int
|
||||
}]
|
||||
|
||||
// If the affinity requirements specified by this field are not
|
||||
// met at scheduling time, the pod will not be scheduled onto the
|
||||
// node. If the affinity requirements specified by this field
|
||||
// cease to be met at some point during pod execution (e.g. due
|
||||
// to a pod label update), the system may or may not try to
|
||||
// eventually evict the pod from its node. When there are
|
||||
// multiple elements, the lists of nodes corresponding to each
|
||||
// podAffinityTerm are intersected, i.e. all terms must be
|
||||
// satisfied.
|
||||
requiredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// A label query over a set of resources, in this case pods.
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A label query over the set of namespaces that the term applies
|
||||
// to. The term is applied to the union of the namespaces
|
||||
// selected by this field and the ones listed in the namespaces
|
||||
// field. null selector and null or empty namespaces list means
|
||||
// "this pod's namespace". An empty selector ({}) matches all
|
||||
// namespaces.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// namespaces specifies a static list of namespace names that the
|
||||
// term applies to. The term is applied to the union of the
|
||||
// namespaces listed in this field and the ones selected by
|
||||
// namespaceSelector. null or empty namespaces list and null
|
||||
// namespaceSelector means "this pod's namespace".
|
||||
namespaces?: [...string]
|
||||
|
||||
// This pod should be co-located (affinity) or not co-located
|
||||
// (anti-affinity) with the pods matching the labelSelector in
|
||||
// the specified namespaces, where co-located is defined as
|
||||
// running on a node whose value of the label with key
|
||||
// topologyKey matches that of any node on which any of the
|
||||
// selected pods is running. Empty topologyKey is not allowed.
|
||||
topologyKey: string
|
||||
}]
|
||||
}
|
||||
|
||||
// Describes pod anti-affinity scheduling rules (e.g. avoid
|
||||
// putting this pod in the same node, zone, etc. as some other
|
||||
// pod(s)).
|
||||
podAntiAffinity?: {
|
||||
// The scheduler will prefer to schedule pods to nodes that
|
||||
// satisfy the anti-affinity expressions specified by this field,
|
||||
// but it may choose a node that violates one or more of the
|
||||
// expressions. The node that is most preferred is the one with
|
||||
// the greatest sum of weights, i.e. for each node that meets all
|
||||
// of the scheduling requirements (resource request,
|
||||
// requiredDuringScheduling anti-affinity expressions, etc.),
|
||||
// compute a sum by iterating through the elements of this field
|
||||
// and adding "weight" to the sum if the node has pods which
|
||||
// matches the corresponding podAffinityTerm; the node(s) with
|
||||
// the highest sum are the most preferred.
|
||||
preferredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// Required. A pod affinity term, associated with the
|
||||
// corresponding weight.
|
||||
podAffinityTerm: {
|
||||
// A label query over a set of resources, in this case pods.
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A label query over the set of namespaces that the term applies
|
||||
// to. The term is applied to the union of the namespaces
|
||||
// selected by this field and the ones listed in the namespaces
|
||||
// field. null selector and null or empty namespaces list means
|
||||
// "this pod's namespace". An empty selector ({}) matches all
|
||||
// namespaces.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// namespaces specifies a static list of namespace names that the
|
||||
// term applies to. The term is applied to the union of the
|
||||
// namespaces listed in this field and the ones selected by
|
||||
// namespaceSelector. null or empty namespaces list and null
|
||||
// namespaceSelector means "this pod's namespace".
|
||||
namespaces?: [...string]
|
||||
|
||||
// This pod should be co-located (affinity) or not co-located
|
||||
// (anti-affinity) with the pods matching the labelSelector in
|
||||
// the specified namespaces, where co-located is defined as
|
||||
// running on a node whose value of the label with key
|
||||
// topologyKey matches that of any node on which any of the
|
||||
// selected pods is running. Empty topologyKey is not allowed.
|
||||
topologyKey: string
|
||||
}
|
||||
|
||||
// weight associated with matching the corresponding
|
||||
// podAffinityTerm, in the range 1-100.
|
||||
weight: int
|
||||
}]
|
||||
|
||||
// If the anti-affinity requirements specified by this field are
|
||||
// not met at scheduling time, the pod will not be scheduled onto
|
||||
// the node. If the anti-affinity requirements specified by this
|
||||
// field cease to be met at some point during pod execution (e.g.
|
||||
// due to a pod label update), the system may or may not try to
|
||||
// eventually evict the pod from its node. When there are
|
||||
// multiple elements, the lists of nodes corresponding to each
|
||||
// podAffinityTerm are intersected, i.e. all terms must be
|
||||
// satisfied.
|
||||
requiredDuringSchedulingIgnoredDuringExecution?: [...{
|
||||
// A label query over a set of resources, in this case pods.
|
||||
labelSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// A label query over the set of namespaces that the term applies
|
||||
// to. The term is applied to the union of the namespaces
|
||||
// selected by this field and the ones listed in the namespaces
|
||||
// field. null selector and null or empty namespaces list means
|
||||
// "this pod's namespace". An empty selector ({}) matches all
|
||||
// namespaces.
|
||||
namespaceSelector?: {
|
||||
// matchExpressions is a list of label selector requirements. The
|
||||
// requirements are ANDed.
|
||||
matchExpressions?: [...{
|
||||
// key is the label key that the selector applies to.
|
||||
key: string
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
operator: string
|
||||
|
||||
// values is an array of string values. If the operator is In or
|
||||
// NotIn, the values array must be non-empty. If the operator is
|
||||
// Exists or DoesNotExist, the values array must be empty. This
|
||||
// array is replaced during a strategic merge patch.
|
||||
values?: [...string]
|
||||
}]
|
||||
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value}
|
||||
// in the matchLabels map is equivalent to an element of
|
||||
// matchExpressions, whose key field is "key", the operator is
|
||||
// "In", and the values array contains only "value". The
|
||||
// requirements are ANDed.
|
||||
matchLabels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// namespaces specifies a static list of namespace names that the
|
||||
// term applies to. The term is applied to the union of the
|
||||
// namespaces listed in this field and the ones selected by
|
||||
// namespaceSelector. null or empty namespaces list and null
|
||||
// namespaceSelector means "this pod's namespace".
|
||||
namespaces?: [...string]
|
||||
|
||||
// This pod should be co-located (affinity) or not co-located
|
||||
// (anti-affinity) with the pods matching the labelSelector in
|
||||
// the specified namespaces, where co-located is defined as
|
||||
// running on a node whose value of the label with key
|
||||
// topologyKey matches that of any node on which any of the
|
||||
// selected pods is running. Empty topologyKey is not allowed.
|
||||
topologyKey: string
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
// The major version of PostgreSQL before the upgrade.
|
||||
fromPostgresVersion: uint & >=10 & <=16
|
||||
|
||||
// The image name to use for major PostgreSQL upgrades.
|
||||
image?: string
|
||||
|
||||
// ImagePullPolicy is used to determine when Kubernetes will
|
||||
// attempt to pull (download) container images. More info:
|
||||
// https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy
|
||||
imagePullPolicy?: "Always" | "Never" | "IfNotPresent"
|
||||
|
||||
// The image pull secrets used to pull from a private registry.
|
||||
// Changing this value causes all running PGUpgrade pods to
|
||||
// restart.
|
||||
// https://k8s.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
||||
imagePullSecrets?: [...{
|
||||
// Name of the referent. More info:
|
||||
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
name?: string
|
||||
}]
|
||||
|
||||
// Metadata contains metadata for custom resources
|
||||
metadata?: {
|
||||
annotations?: {
|
||||
[string]: string
|
||||
}
|
||||
labels?: {
|
||||
[string]: string
|
||||
}
|
||||
}
|
||||
|
||||
// The name of the cluster to be updated
|
||||
postgresClusterName: strings.MinRunes(1)
|
||||
|
||||
// Priority class name for the PGUpgrade pod. Changing this value
|
||||
// causes PGUpgrade pod to restart. More info:
|
||||
// https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/
|
||||
priorityClassName?: string
|
||||
|
||||
// Resource requirements for the PGUpgrade container.
|
||||
resources?: {
|
||||
// Limits describes the maximum amount of compute resources
|
||||
// allowed. More info:
|
||||
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
limits?: {
|
||||
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
|
||||
}
|
||||
|
||||
// Requests describes the minimum amount of compute resources
|
||||
// required. If Requests is omitted for a container, it defaults
|
||||
// to Limits if that is explicitly specified, otherwise to an
|
||||
// implementation-defined value. More info:
|
||||
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
requests?: {
|
||||
[string]: (int | string) & =~"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$"
|
||||
}
|
||||
}
|
||||
|
||||
// The image name to use for PostgreSQL containers after upgrade.
|
||||
// When omitted, the value comes from an operator environment
|
||||
// variable.
|
||||
toPostgresImage?: string
|
||||
|
||||
// The major version of PostgreSQL to be upgraded to.
|
||||
toPostgresVersion: uint & >=10 & <=16
|
||||
|
||||
// Tolerations of the PGUpgrade pod. More info:
|
||||
// https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration
|
||||
tolerations?: [...{
|
||||
// Effect indicates the taint effect to match. Empty means match
|
||||
// all taint effects. When specified, allowed values are
|
||||
// NoSchedule, PreferNoSchedule and NoExecute.
|
||||
effect?: string
|
||||
|
||||
// Key is the taint key that the toleration applies to. Empty
|
||||
// means match all taint keys. If the key is empty, operator must
|
||||
// be Exists; this combination means to match all values and all
|
||||
// keys.
|
||||
key?: string
|
||||
|
||||
// Operator represents a key's relationship to the value. Valid
|
||||
// operators are Exists and Equal. Defaults to Equal. Exists is
|
||||
// equivalent to wildcard for value, so that a pod can tolerate
|
||||
// all taints of a particular category.
|
||||
operator?: string
|
||||
|
||||
// TolerationSeconds represents the period of time the toleration
|
||||
// (which must be of effect NoExecute, otherwise this field is
|
||||
// ignored) tolerates the taint. By default, it is not set, which
|
||||
// means tolerate the taint forever (do not evict). Zero and
|
||||
// negative values will be treated as 0 (evict immediately) by
|
||||
// the system.
|
||||
tolerationSeconds?: int
|
||||
|
||||
// Value is the taint value the toleration matches to. If the
|
||||
// operator is Exists, the value should be empty, otherwise just
|
||||
// a regular string.
|
||||
value?: string
|
||||
}]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
package v1alpha1
|
||||
|
||||
// #BuildPlan is the API contract between CUE and the Holos cli.
|
||||
// Holos requires CUE to evaluate and provide a valid #BuildPlan.
|
||||
#BuildPlan: {
|
||||
kind: #BuildPlanKind
|
||||
apiVersion: #APIVersion
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,5 @@
|
||||
package v1alpha1
|
||||
|
||||
#HolosComponent: Skip: true | *false
|
||||
|
||||
#HelmChart: enableHooks: true | *false
|
||||
@@ -4,3 +4,8 @@ package v1
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
}
|
||||
|
||||
#StatefulSet: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "StatefulSet"
|
||||
}
|
||||
|
||||
39
docs/examples/helpers.cue
Normal file
39
docs/examples/helpers.cue
Normal file
@@ -0,0 +1,39 @@
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
|
||||
// #APIObjects is the output type for api objects produced by cue.
|
||||
#APIObjects: {
|
||||
// apiObjects holds each the api objects produced by cue.
|
||||
apiObjects: {
|
||||
[Kind=_]: {
|
||||
[string]: {
|
||||
kind: Kind
|
||||
...
|
||||
}
|
||||
}
|
||||
Namespace?: [Name=_]: #Namespace & {metadata: name: Name}
|
||||
ExternalSecret?: [Name=_]: #ExternalSecret & {_name: Name}
|
||||
VirtualService?: [Name=_]: #VirtualService & {metadata: name: Name}
|
||||
Issuer?: [Name=_]: #Issuer & {metadata: name: Name}
|
||||
Gateway?: [Name=_]: #Gateway & {metadata: name: Name}
|
||||
ConfigMap?: [Name=_]: #ConfigMap & {metadata: name: Name}
|
||||
|
||||
Deployment?: [_]: #Deployment
|
||||
StatefulSet?: [_]: #StatefulSet
|
||||
RequestAuthentication?: [_]: #RequestAuthentication
|
||||
AuthorizationPolicy?: [_]: #AuthorizationPolicy
|
||||
}
|
||||
|
||||
// apiObjectMap holds the marshalled representation of apiObjects
|
||||
apiObjectMap: {
|
||||
for kind, v in apiObjects {
|
||||
"\(kind)": {
|
||||
for name, obj in v {
|
||||
"\(name)": yaml.Marshal(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
...
|
||||
}
|
||||
}
|
||||
117
docs/examples/holos.cue
Normal file
117
docs/examples/holos.cue
Normal file
@@ -0,0 +1,117 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
h "github.com/holos-run/holos/api/v1alpha1"
|
||||
kc "sigs.k8s.io/kustomize/api/types"
|
||||
ksv1 "kustomize.toolkit.fluxcd.io/kustomization/v1"
|
||||
)
|
||||
|
||||
// The overall structure of the data is:
|
||||
// 1 CUE Instance => 1 BuildPlan => 0..N HolosComponents
|
||||
|
||||
// Holos requires CUE to evaluate and provide a valid BuildPlan.
|
||||
// Constrain each CUE instance to output a BuildPlan.
|
||||
{} & h.#BuildPlan
|
||||
|
||||
let DependsOn = {[Name=_]: name: string & Name}
|
||||
|
||||
// #HolosComponent defines struct fields common to all holos component types.
|
||||
#HolosComponent: {
|
||||
h.#HolosComponent
|
||||
_dependsOn: DependsOn
|
||||
let DEPENDS_ON = _dependsOn
|
||||
metadata: name: string
|
||||
#namelen: len(metadata.name) & >=1
|
||||
let Name = metadata.name
|
||||
|
||||
// TODO: ksContent needs to be component scoped, not instance scoped.
|
||||
ksContent: yaml.Marshal(#Kustomization & {
|
||||
_dependsOn: DEPENDS_ON
|
||||
metadata: name: Name
|
||||
})
|
||||
// Leave the HolosComponent open for components with additional fields like HelmChart.
|
||||
// Refer to https://cuelang.org/docs/tour/types/closed/
|
||||
...
|
||||
}
|
||||
|
||||
//#KustomizeFiles represents resources for holos to write into files for kustomize post-processing.
|
||||
#KustomizeFiles: {
|
||||
// Objects collects files for Holos to write for kustomize post-processing.
|
||||
Objects: "kustomization.yaml": #Kustomize
|
||||
// Files holds the marshaled output of Objects holos writes to the filesystem before calling the kustomize post-processor.
|
||||
Files: {
|
||||
for filename, obj in Objects {
|
||||
"\(filename)": yaml.Marshal(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Holos component types.
|
||||
#HelmChart: #HolosComponent & h.#HelmChart & {
|
||||
_values: {...}
|
||||
_kustomizeFiles: #KustomizeFiles
|
||||
|
||||
// Render the values to yaml for holos to provide to helm.
|
||||
valuesContent: yaml.Marshal(_values)
|
||||
// Kustomize post-processor
|
||||
// resources is the intermediate file name for api objects.
|
||||
resourcesFile: h.#ResourcesFile
|
||||
// kustomizeFiles represents the files in a kustomize directory tree.
|
||||
kustomizeFiles: _kustomizeFiles.Files
|
||||
|
||||
chart: h.#Chart & {
|
||||
name: string
|
||||
release: string | *name
|
||||
}
|
||||
}
|
||||
#KubernetesObjects: #HolosComponent & h.#KubernetesObjects
|
||||
#KustomizeBuild: #HolosComponent & h.#KustomizeBuild
|
||||
|
||||
// #ClusterName is the cluster name for cluster scoped resources.
|
||||
#ClusterName: #InputKeys.cluster
|
||||
|
||||
// Flux Kustomization CRDs
|
||||
#Kustomization: #NamespaceObject & ksv1.#Kustomization & {
|
||||
_dependsOn: DependsOn
|
||||
|
||||
metadata: {
|
||||
name: string
|
||||
namespace: string | *"flux-system"
|
||||
}
|
||||
spec: ksv1.#KustomizationSpec & {
|
||||
interval: string | *"30m0s"
|
||||
path: string | *"deploy/clusters/\(#InputKeys.cluster)/components/\(metadata.name)"
|
||||
prune: bool | *true
|
||||
retryInterval: string | *"2m0s"
|
||||
sourceRef: {
|
||||
kind: string | *"GitRepository"
|
||||
name: string | *"flux-system"
|
||||
}
|
||||
suspend?: bool
|
||||
targetNamespace?: string
|
||||
timeout: string | *"3m0s"
|
||||
// wait performs health checks for all reconciled resources. If set to true, .spec.healthChecks is ignored.
|
||||
// Setting this to true for all components generates considerable load on the api server from watches.
|
||||
// Operations are additionally more complicated when all resources are watched. Consider setting wait true for
|
||||
// relatively simple components, otherwise target specific resources with spec.healthChecks.
|
||||
wait: true | *false
|
||||
dependsOn: [for k, v in _dependsOn {v}, ...]
|
||||
}
|
||||
}
|
||||
|
||||
// #Kustomize represents the kustomize post processor.
|
||||
#Kustomize: kc.#Kustomization & {
|
||||
_patches: {[_]: kc.#Patch}
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
// resources are file names holos will use to store intermediate component output for kustomize to post-process (i.e. helm template | kubectl kustomize)
|
||||
// See the related resourcesFile field of the holos component.
|
||||
resources: [h.#ResourcesFile]
|
||||
if len(_patches) > 0 {
|
||||
patches: [for v in _patches {v}]
|
||||
}
|
||||
}
|
||||
|
||||
// So components don't need to import the package.
|
||||
#Patch: kc.#Patch
|
||||
26
docs/examples/managednamespaces.cue
Normal file
26
docs/examples/managednamespaces.cue
Normal file
@@ -0,0 +1,26 @@
|
||||
package holos
|
||||
|
||||
// NOTE: Beyond the base reference platform, services should typically be added to #OptionalServices instead of directly to a managed namespace.
|
||||
|
||||
// ManagedNamespace is a namespace to manage across all clusters in the holos platform.
|
||||
#ManagedNamespace: {
|
||||
namespace: {
|
||||
metadata: {
|
||||
name: string
|
||||
labels: [string]: string
|
||||
}
|
||||
}
|
||||
// clusterNames represents the set of clusters the namespace is managed on. Usually all clusters.
|
||||
clusterNames: [...string]
|
||||
for cluster in clusterNames {
|
||||
clusters: (cluster): name: cluster
|
||||
}
|
||||
}
|
||||
|
||||
// #ManagedNamepsaces is the union of all namespaces across all cluster types and optional services.
|
||||
// Holos adopts the namespace sameness position of SIG Multicluster, refer to https://github.com/kubernetes/community/blob/dd4c8b704ef1c9c3bfd928c6fa9234276d61ad18/sig-multicluster/namespace-sameness-position-statement.md
|
||||
#ManagedNamespaces: {
|
||||
[Name=_]: #ManagedNamespace & {
|
||||
namespace: metadata: name: Name
|
||||
}
|
||||
}
|
||||
54
docs/examples/meshconfig.cue
Normal file
54
docs/examples/meshconfig.cue
Normal file
@@ -0,0 +1,54 @@
|
||||
package holos
|
||||
|
||||
// #MeshConfig provides the istio meshconfig in the config key given projects.
|
||||
#MeshConfig: {
|
||||
projects: #Projects
|
||||
// clusterName is the value of the --cluster-name flag, the cluster currently being manged / rendered.
|
||||
clusterName: string | *#ClusterName
|
||||
|
||||
// for extAuthzHttp extension providers
|
||||
extensionProviderMap: [Name=_]: #ExtAuthzProxy & {name: Name}
|
||||
// for other extension providers like zipkin
|
||||
extensionProviderExtraMap: [Name=_]: {name: Name}
|
||||
|
||||
config: {
|
||||
accessLogEncoding: string | *"JSON"
|
||||
accessLogFile: string | *"/dev/stdout"
|
||||
defaultConfig: {
|
||||
discoveryAddress: string | *"istiod.istio-system.svc:15012"
|
||||
tracing: zipkin: address: string | *"zipkin.istio-system:9411"
|
||||
}
|
||||
defaultProviders: metrics: [...string] | *["prometheus"]
|
||||
enablePrometheusMerge: false | *true
|
||||
rootNamespace: string | *"istio-system"
|
||||
trustDomain: string | *"cluster.local"
|
||||
extensionProviders: [
|
||||
for x in extensionProviderMap {x},
|
||||
for y in extensionProviderExtraMap {y},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// #ExtAuthzProxy defines the provider configuration for an istio external authorization auth proxy.
|
||||
#ExtAuthzProxy: {
|
||||
name: string
|
||||
envoyExtAuthzHttp: {
|
||||
headersToDownstreamOnDeny: [
|
||||
"content-type",
|
||||
"set-cookie",
|
||||
]
|
||||
headersToUpstreamOnAllow: [
|
||||
"authorization",
|
||||
"path",
|
||||
"x-oidc-id-token",
|
||||
]
|
||||
includeAdditionalHeadersInCheck: "X-Auth-Request-Redirect": "%REQ(x-forwarded-proto)%://%REQ(:authority)%%REQ(:path)%%REQ(:query)%"
|
||||
includeRequestHeadersInCheck: [
|
||||
"authorization",
|
||||
"cookie",
|
||||
"x-forwarded-for",
|
||||
]
|
||||
port: 4180
|
||||
service: string
|
||||
}
|
||||
}
|
||||
48
docs/examples/optionalservices.cue
Normal file
48
docs/examples/optionalservices.cue
Normal file
@@ -0,0 +1,48 @@
|
||||
// Controls optional feature flags for services distributed across multiple holos components.
|
||||
// For example, enable issuing certificates in the provisioner cluster when an optional service is
|
||||
// enabled for a workload cluster. Another example is NATS, which isn't necessary on all clusters,
|
||||
// but is necessary on clusters with a project like holos which depends on NATS.
|
||||
|
||||
package holos
|
||||
|
||||
import "list"
|
||||
|
||||
#OptionalService: {
|
||||
name: string
|
||||
enabled: true | *false
|
||||
clusters: [Name=_]: #Platform.clusters[Name]
|
||||
clusterNames: [for c in clusters {c.name}]
|
||||
|
||||
managedNamespaces: [Name=_]: #ManagedNamespace & {
|
||||
namespace: metadata: name: Name
|
||||
clusterNames: ["provisioner", for c in clusters {c.name}]
|
||||
}
|
||||
// servers represents istio Gateway.spec.servers.hosts entries
|
||||
// Refer to istio/gateway/gateway.cue
|
||||
servers: [Name=_]: {
|
||||
hosts: [...string]
|
||||
port: name: Name
|
||||
port: number: 443
|
||||
port: protocol: "HTTPS"
|
||||
tls: credentialName: string
|
||||
tls: mode: "SIMPLE"
|
||||
}
|
||||
// public tls certs should align to hosts.
|
||||
certs: [Name=_]: #Certificate & {
|
||||
metadata: name: Name
|
||||
}
|
||||
}
|
||||
|
||||
#OptionalServices: {
|
||||
[Name=_]: #OptionalService & {
|
||||
name: Name
|
||||
}
|
||||
}
|
||||
|
||||
for svc in #OptionalServices {
|
||||
for nsName, ns in svc.managedNamespaces {
|
||||
if svc.enabled && list.Contains(ns.clusterNames, #ClusterName) {
|
||||
#ManagedNamespaces: "\(nsName)": ns
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package holos
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
let Broker = "broker"
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
_dependsOn: "prod-platform-issuer": _
|
||||
|
||||
metadata: name: "\(Namespace)-broker"
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let SelectorLabels = {
|
||||
"app.kubernetes.io/instance": Broker
|
||||
"app.kubernetes.io/name": Broker
|
||||
}
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
Certificate: "\(Broker)-tls": #Certificate & {
|
||||
metadata: {
|
||||
name: "\(Broker)-tls"
|
||||
namespace: Namespace
|
||||
labels: SelectorLabels
|
||||
}
|
||||
spec: {
|
||||
commonName: "\(Broker).\(Namespace).svc.cluster.local"
|
||||
dnsNames: [
|
||||
Broker,
|
||||
"\(Broker).\(Namespace).svc",
|
||||
"\(Broker).\(Namespace).svc.cluster.local",
|
||||
"provision-\(Broker)",
|
||||
"provision-\(Broker).\(Namespace).svc",
|
||||
"provision-\(Broker).\(Namespace).svc.cluster.local",
|
||||
"*.\(Broker)",
|
||||
"*.\(Broker).\(Namespace).svc",
|
||||
"*.\(Broker).\(Namespace).svc.cluster.local",
|
||||
]
|
||||
issuerRef: kind: "ClusterIssuer"
|
||||
issuerRef: name: "platform-issuer"
|
||||
secretName: metadata.name
|
||||
usages: ["signing", "key encipherment", "server auth", "client auth"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package holos
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
let Broker = "broker"
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
_dependsOn: "prod-secrets-stores": _
|
||||
|
||||
metadata: name: "\(Namespace)-broker"
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let SelectorLabels = {
|
||||
"app.kubernetes.io/instance": Broker
|
||||
"app.kubernetes.io/name": Broker
|
||||
}
|
||||
|
||||
let Metadata = {
|
||||
name: Broker
|
||||
namespace: Namespace
|
||||
labels: SelectorLabels
|
||||
}
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
ExternalSecret: "\(Broker)-tls": #ExternalSecret & {
|
||||
metadata: name: "\(Broker)-tls"
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
ExternalSecret: "choria-\(Broker)": #ExternalSecret & {
|
||||
metadata: name: "choria-\(Broker)"
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
StatefulSet: "\(Broker)": {
|
||||
metadata: Metadata
|
||||
spec: {
|
||||
selector: matchLabels: SelectorLabels
|
||||
serviceName: Broker
|
||||
template: metadata: labels: SelectorLabels
|
||||
template: spec: {
|
||||
containers: [
|
||||
{
|
||||
name: Broker
|
||||
command: ["choria", "broker", "run", "--config", "/etc/choria/broker.conf"]
|
||||
image: "registry.choria.io/choria/choria:0.28.0"
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
ports: [
|
||||
{
|
||||
containerPort: 4222
|
||||
name: "tcp-nats"
|
||||
protocol: "TCP"
|
||||
},
|
||||
{
|
||||
containerPort: 4333
|
||||
name: "https-wss"
|
||||
protocol: "TCP"
|
||||
},
|
||||
{
|
||||
containerPort: 5222
|
||||
name: "tcp-cluster"
|
||||
protocol: "TCP"
|
||||
},
|
||||
{
|
||||
containerPort: 8222
|
||||
name: "http-stats"
|
||||
protocol: "TCP"
|
||||
},
|
||||
]
|
||||
livenessProbe: httpGet: {
|
||||
path: "/healthz"
|
||||
port: "http-stats"
|
||||
}
|
||||
readinessProbe: livenessProbe
|
||||
resources: {}
|
||||
securityContext: {}
|
||||
volumeMounts: [
|
||||
{
|
||||
mountPath: "/etc/choria"
|
||||
name: Broker
|
||||
},
|
||||
{
|
||||
mountPath: "/etc/choria-tls"
|
||||
name: "\(Broker)-tls"
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
securityContext: {}
|
||||
serviceAccountName: Broker
|
||||
volumes: [
|
||||
{
|
||||
name: Broker
|
||||
secret: secretName: "choria-\(Broker)"
|
||||
},
|
||||
{
|
||||
name: "\(Broker)-tls"
|
||||
secret: secretName: "\(Broker)-tls"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
ServiceAccount: "\(Broker)": #ServiceAccount & {
|
||||
metadata: Metadata
|
||||
}
|
||||
Service: "\(Broker)": #Service & {
|
||||
metadata: Metadata
|
||||
spec: {
|
||||
type: "ClusterIP"
|
||||
clusterIP: "None"
|
||||
selector: SelectorLabels
|
||||
ports: [
|
||||
{
|
||||
name: "tcp-nats"
|
||||
appProtocol: "tcp"
|
||||
port: 4222
|
||||
protocol: "TCP"
|
||||
targetPort: "tcp-nats"
|
||||
},
|
||||
{
|
||||
name: "tcp-cluster"
|
||||
appProtocol: "tcp"
|
||||
port: 5222
|
||||
protocol: "TCP"
|
||||
targetPort: "tcp-cluster"
|
||||
},
|
||||
{
|
||||
name: "https-wss"
|
||||
appProtocol: "https"
|
||||
port: 443
|
||||
protocol: "TCP"
|
||||
targetPort: "https-wss"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
DestinationRule: "\(Broker)-wss": #DestinationRule & {
|
||||
metadata: Metadata
|
||||
spec: host: "\(Broker).\(Namespace).svc.cluster.local"
|
||||
spec: trafficPolicy: tls: {
|
||||
credentialName: "istio-ingress-mtls-cert"
|
||||
mode: "MUTUAL"
|
||||
}
|
||||
}
|
||||
VirtualService: "\(Broker)-wss": #VirtualService & {
|
||||
metadata: name: "\(Broker)-wss"
|
||||
metadata: namespace: Namespace
|
||||
spec: {
|
||||
gateways: ["istio-ingress/default"]
|
||||
hosts: ["jeff.provision.dev.\(#ClusterName).holos.run"]
|
||||
http: [
|
||||
{
|
||||
route: [
|
||||
{
|
||||
destination: {
|
||||
host: "\(Broker).\(Namespace).svc.cluster.local"
|
||||
port: "number": 443
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
# build output from https://github.com/holos-run/holos-infra/blob/main/experiments/components/holos-saas/broker/build
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: broker
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: broker
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: broker-0.1.0
|
||||
name: broker
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: broker
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: broker
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: broker-0.1.0
|
||||
name: broker
|
||||
spec:
|
||||
clusterIP: None
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: tcp-nats
|
||||
port: 4222
|
||||
protocol: TCP
|
||||
targetPort: tcp-nats
|
||||
- appProtocol: tcp
|
||||
name: tcp-cluster
|
||||
port: 5222
|
||||
protocol: TCP
|
||||
targetPort: tcp-cluster
|
||||
- appProtocol: https
|
||||
name: https-wss
|
||||
port: 443
|
||||
protocol: TCP
|
||||
targetPort: https-wss
|
||||
selector:
|
||||
app.kubernetes.io/instance: broker
|
||||
app.kubernetes.io/name: broker
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: broker
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: broker
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: broker-0.1.0
|
||||
name: broker-lb
|
||||
spec:
|
||||
externalTrafficPolicy: Local
|
||||
loadBalancerIP: 1.2.3.4
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: tcp-nats
|
||||
port: 4222
|
||||
protocol: TCP
|
||||
targetPort: tcp-nats
|
||||
- appProtocol: https
|
||||
name: https-wss
|
||||
port: 443
|
||||
protocol: TCP
|
||||
targetPort: https-wss
|
||||
selector:
|
||||
app.kubernetes.io/instance: broker
|
||||
app.kubernetes.io/name: broker
|
||||
type: LoadBalancer
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: broker
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: broker
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: broker-0.1.0
|
||||
name: broker
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: broker
|
||||
app.kubernetes.io/name: broker
|
||||
serviceName: broker
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: broker
|
||||
app.kubernetes.io/name: broker
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- choria
|
||||
- broker
|
||||
- run
|
||||
- --config
|
||||
- /etc/choria/broker.conf
|
||||
image: registry.choria.io/choria/choria:latest
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http-stats
|
||||
name: broker
|
||||
ports:
|
||||
- containerPort: 4222
|
||||
name: tcp-nats
|
||||
protocol: TCP
|
||||
- containerPort: 4333
|
||||
name: https-wss
|
||||
protocol: TCP
|
||||
- containerPort: 5222
|
||||
name: tcp-cluster
|
||||
protocol: TCP
|
||||
- containerPort: 8222
|
||||
name: http-stats
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http-stats
|
||||
resources: {}
|
||||
securityContext: {}
|
||||
volumeMounts:
|
||||
- mountPath: /etc/choria
|
||||
name: broker
|
||||
- mountPath: /etc/choria-tls
|
||||
name: broker-tls
|
||||
securityContext: {}
|
||||
serviceAccountName: broker
|
||||
volumes:
|
||||
- name: broker
|
||||
secret:
|
||||
secretName: broker
|
||||
- name: broker-tls
|
||||
secret:
|
||||
secretName: broker-tls
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: broker-tls
|
||||
namespace: holos-dev
|
||||
spec:
|
||||
commonName: broker.holos-dev.svc.cluster.local
|
||||
dnsNames:
|
||||
- broker
|
||||
- broker.holos-dev.svc
|
||||
- broker.holos-dev.svc.cluster.local
|
||||
- provision-broker
|
||||
- provision-broker.holos-dev.svc
|
||||
- provision-broker.holos-dev.svc.cluster.local
|
||||
- '*.broker'
|
||||
- '*.broker.holos-dev.svc'
|
||||
- '*.broker.holos-dev.svc.cluster.local'
|
||||
issuerRef:
|
||||
kind: ClusterIssuer
|
||||
name: cluster-issuer
|
||||
secretName: broker-tls
|
||||
usages:
|
||||
- signing
|
||||
- key encipherment
|
||||
- server auth
|
||||
- client auth
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: broker
|
||||
spec:
|
||||
dataFrom:
|
||||
- extract:
|
||||
key: kv//kube-namespace/holos-dev/broker
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
kind: SecretStore
|
||||
name: core-vault
|
||||
target:
|
||||
creationPolicy: Owner
|
||||
name: broker
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: broker-wss
|
||||
namespace: holos-dev
|
||||
spec:
|
||||
host: broker.holos-dev.svc.cluster.local
|
||||
trafficPolicy:
|
||||
tls:
|
||||
credentialName: istio-ingress-mtls-cert
|
||||
mode: MUTUAL
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: broker-wss
|
||||
namespace: holos-dev
|
||||
spec:
|
||||
gateways:
|
||||
- istio-ingress/wildcard-pub-gw
|
||||
hosts:
|
||||
- provision.pub.k2.holos.run
|
||||
http:
|
||||
- route:
|
||||
- destination:
|
||||
host: broker.holos-dev.svc.cluster.local
|
||||
port:
|
||||
number: 443
|
||||
tls:
|
||||
mode: SIMPLE
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# Machine Room Provisioner
|
||||
|
||||
This sub-tree contains Holos Components to manage a [Choria Provisioner][1]
|
||||
system for the use case of provisioning `holos controller` instances. These
|
||||
instances are implementations of Machine Room which are in turn implementations
|
||||
of Choria Server, hence why we use Choria Provisioner.
|
||||
|
||||
[1]: https://choria-io.github.io/provisioner/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
# curl -LO https://github.com/nats-io/nack/releases/latest/download/crds.yml
|
||||
resources:
|
||||
- crds.yml
|
||||
@@ -0,0 +1,8 @@
|
||||
package holos
|
||||
|
||||
// NATS NetStream Controller (NACK)
|
||||
spec: components: KustomizeBuildList: [
|
||||
#KustomizeBuild & {
|
||||
metadata: name: "prod-nack-crds"
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,62 @@
|
||||
package holos
|
||||
|
||||
// for Project in _Projects {
|
||||
// spec: components: resources: (#ProjectTemplate & {project: Project}).workload.resources
|
||||
// }
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
|
||||
#Kustomization: spec: targetNamespace: Namespace
|
||||
|
||||
spec: components: HelmChartList: [
|
||||
#HelmChart & {
|
||||
metadata: name: "jeff-holos-nats"
|
||||
namespace: Namespace
|
||||
_dependsOn: "prod-secrets-stores": _
|
||||
chart: {
|
||||
name: "nats"
|
||||
version: "1.1.10"
|
||||
repository: NatsRepository
|
||||
}
|
||||
_values: #NatsValues & {
|
||||
config: {
|
||||
// https://github.com/nats-io/k8s/tree/main/helm/charts/nats#operator-mode-with-nats-resolver
|
||||
resolver: enabled: true
|
||||
resolver: merge: {
|
||||
type: "full"
|
||||
interval: "2m"
|
||||
timeout: "1.9s"
|
||||
}
|
||||
merge: {
|
||||
operator: "eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJUSElBTDM2NUtOS0lVVVJDMzNLNFJGQkJVRlFBSTRLS0NQTDJGVDZYVjdNQVhWU1dFNElRIiwiaWF0IjoxNzEzMjIxMzE1LCJpc3MiOiJPREtQM0RZTzc3T1NBRU5IU0FFR0s3WUNFTFBYT1FFWUI3RVFSTVBLWlBNQUxINE5BRUVLSjZDRyIsIm5hbWUiOiJIb2xvcyIsInN1YiI6Ik9ES1AzRFlPNzdPU0FFTkhTQUVHSzdZQ0VMUFhPUUVZQjdFUVJNUEtaUE1BTEg0TkFFRUtKNkNHIiwibmF0cyI6eyJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.dQURTb-zIQMc-OYd9328oY887AEnvog6gOXY1-VCsDG3L89nq5x_ks4ME7dJ4Pn-Pvm2eyBi1Jx6ubgkthHgCQ"
|
||||
system_account: "ADIQCYK4K3OKTPODGCLI4PDQ6XBO52MISBPTAIDESEJMLZCMNULDKCCY"
|
||||
resolver_preload: {
|
||||
// NOTEL: Make sure you do not include the trailing , in the SYS_ACCOUNT_JWT
|
||||
"ADIQCYK4K3OKTPODGCLI4PDQ6XBO52MISBPTAIDESEJMLZCMNULDKCCY": "eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiI2SEVMNlhKSUdWUElMNFBURVI1MkUzTkFITjZLWkVUUUdFTlFVS0JWRzNUWlNLRzVLT09RIiwiaWF0IjoxNzEzMjIxMzE1LCJpc3MiOiJPREtQM0RZTzc3T1NBRU5IU0FFR0s3WUNFTFBYT1FFWUI3RVFSTVBLWlBNQUxINE5BRUVLSjZDRyIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBRElRQ1lLNEszT0tUUE9ER0NMSTRQRFE2WEJPNTJNSVNCUFRBSURFU0VKTUxaQ01OVUxES0NDWSIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJhdXRob3JpemF0aW9uIjp7fSwidHlwZSI6ImFjY291bnQiLCJ2ZXJzaW9uIjoyfX0.TiGIk8XON394D9SBEowGHY_nTeOyHiM-ihyw6HZs8AngOnYPFXH9OVjsaAf8Poa2k_V84VtH7yVNgNdjBgduDA"
|
||||
}
|
||||
}
|
||||
cluster: enabled: true
|
||||
jetstream: enabled: true
|
||||
websocket: enabled: true
|
||||
monitor: enabled: true
|
||||
}
|
||||
promExporter: enabled: true
|
||||
promExporter: podMonitor: enabled: true
|
||||
}
|
||||
},
|
||||
#HelmChart & {
|
||||
metadata: name: "jeff-holos-nack"
|
||||
namespace: Namespace
|
||||
_dependsOn: "jeff-holos-nats": _
|
||||
chart: {
|
||||
name: "nack"
|
||||
version: "0.25.2"
|
||||
repository: NatsRepository
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
let NatsRepository = {
|
||||
name: "nats"
|
||||
url: "https://nats-io.github.io/k8s/helm/charts/"
|
||||
}
|
||||
@@ -0,0 +1,722 @@
|
||||
package holos
|
||||
|
||||
#NatsValues: {
|
||||
//###############################################################################
|
||||
// Global options
|
||||
//###############################################################################
|
||||
global: {
|
||||
image: {
|
||||
// global image pull policy to use for all container images in the chart
|
||||
// can be overridden by individual image pullPolicy
|
||||
pullPolicy: null
|
||||
// global list of secret names to use as image pull secrets for all pod specs in the chart
|
||||
// secrets must exist in the same namespace
|
||||
// https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
||||
pullSecretNames: []
|
||||
// global registry to use for all container images in the chart
|
||||
// can be overridden by individual image registry
|
||||
registry: null
|
||||
}
|
||||
|
||||
// global labels will be applied to all resources deployed by the chart
|
||||
labels: {}
|
||||
}
|
||||
|
||||
//###############################################################################
|
||||
// Common options
|
||||
//###############################################################################
|
||||
// override name of the chart
|
||||
nameOverride: null
|
||||
// override full name of the chart+release
|
||||
fullnameOverride: null
|
||||
// override the namespace that resources are installed into
|
||||
namespaceOverride: null
|
||||
|
||||
// reference a common CA Certificate or Bundle in all nats config `tls` blocks and nats-box contexts
|
||||
// note: `tls.verify` still must be set in the appropriate nats config `tls` blocks to require mTLS
|
||||
tlsCA: {
|
||||
enabled: false
|
||||
// set configMapName in order to mount an existing configMap to dir
|
||||
configMapName: null
|
||||
// set secretName in order to mount an existing secretName to dir
|
||||
secretName: null
|
||||
// directory to mount the configMap or secret to
|
||||
dir: "/etc/nats-ca-cert"
|
||||
// key in the configMap or secret that contains the CA Certificate or Bundle
|
||||
key: "ca.crt"
|
||||
}
|
||||
|
||||
//###############################################################################
|
||||
// NATS Stateful Set and associated resources
|
||||
//###############################################################################
|
||||
//###########################################################
|
||||
// NATS config
|
||||
//###########################################################
|
||||
config: {
|
||||
cluster: {
|
||||
enabled: true | *false
|
||||
port: 6222
|
||||
// must be 2 or higher when jetstream is enabled
|
||||
replicas: 3
|
||||
|
||||
// apply to generated route URLs that connect to other pods in the StatefulSet
|
||||
routeURLs: {
|
||||
// if both user and password are set, they will be added to route URLs
|
||||
// and the cluster authorization block
|
||||
user: null
|
||||
password: null
|
||||
// set to true to use FQDN in route URLs
|
||||
useFQDN: false
|
||||
k8sClusterDomain: "cluster.local"
|
||||
}
|
||||
|
||||
tls: {
|
||||
enabled: true | *false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/cluster"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// merge or patch the cluster config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/clustering/cluster_config
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
jetstream: {
|
||||
enabled: true | *false
|
||||
|
||||
fileStore: {
|
||||
enabled: true
|
||||
dir: "/data"
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> volume claim templates -> jetstream pvc
|
||||
//###########################################################
|
||||
pvc: {
|
||||
enabled: true
|
||||
size: "10Gi"
|
||||
storageClassName: null
|
||||
|
||||
// merge or patch the jetstream pvc
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#persistentvolumeclaim-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-js"
|
||||
name: null
|
||||
}
|
||||
|
||||
// defaults to the PVC size
|
||||
maxSize: null
|
||||
}
|
||||
|
||||
memoryStore: {
|
||||
enabled: false
|
||||
// ensure that container has a sufficient memory limit greater than maxSize
|
||||
maxSize: "1Gi"
|
||||
}
|
||||
|
||||
// merge or patch the jetstream config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration#jetstream
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
nats: {
|
||||
port: 4222
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/nats"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
}
|
||||
|
||||
leafnodes: {
|
||||
enabled: false
|
||||
port: 7422
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/leafnodes"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// merge or patch the leafnodes config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/leafnodes/leafnode_conf
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
websocket: {
|
||||
enabled: true | *false
|
||||
port: 8080
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/websocket"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// ingress
|
||||
//###########################################################
|
||||
// service must be enabled also
|
||||
ingress: {
|
||||
enabled: false
|
||||
// must contain at least 1 host otherwise ingress will not be created
|
||||
hosts: []
|
||||
path: "/"
|
||||
pathType: "Exact"
|
||||
// sets to the ingress class name
|
||||
className: null
|
||||
// set to an existing secret name to enable TLS on the ingress; applies to all hosts
|
||||
tlsSecretName: null
|
||||
|
||||
// merge or patch the ingress
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#ingress-v1-networking-k8s-io
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-ws"
|
||||
name: null
|
||||
}
|
||||
|
||||
// merge or patch the websocket config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/websocket/websocket_conf
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
mqtt: {
|
||||
enabled: false
|
||||
port: 1883
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/mqtt"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// merge or patch the mqtt config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/mqtt/mqtt_config
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
gateway: {
|
||||
enabled: false
|
||||
port: 7222
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/gateway"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// merge or patch the gateway config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/gateways/gateway#gateway-configuration-block
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
monitor: {
|
||||
enabled: true
|
||||
port: 8222
|
||||
tls: {
|
||||
// config.nats.tls must be enabled also
|
||||
// when enabled, monitoring port will use HTTPS with the options from config.nats.tls
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
profiling: {
|
||||
enabled: false
|
||||
port: 65432
|
||||
}
|
||||
|
||||
resolver: {
|
||||
enabled: true | *false
|
||||
dir: "/data/resolver"
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> volume claim templates -> resolver pvc
|
||||
//###########################################################
|
||||
pvc: {
|
||||
enabled: true
|
||||
size: "1Gi"
|
||||
storageClassName: null
|
||||
|
||||
// merge or patch the pvc
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#persistentvolumeclaim-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-resolver"
|
||||
name: null
|
||||
}
|
||||
|
||||
// merge or patch the resolver
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/jwt/resolver
|
||||
merge: {
|
||||
type?: string
|
||||
interval?: string
|
||||
timeout?: string
|
||||
}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// adds a prefix to the server name, which defaults to the pod name
|
||||
// helpful for ensuring server name is unique in a super cluster
|
||||
serverNamePrefix: ""
|
||||
|
||||
// merge or patch the nats config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration
|
||||
// following special rules apply
|
||||
// 1. strings that start with << and end with >> will be unquoted
|
||||
// use this for variables and numbers with units
|
||||
// 2. keys ending in $include will be switched to include directives
|
||||
// keys are sorted alphabetically, use prefix before $includes to control includes ordering
|
||||
// paths should be relative to /etc/nats-config/nats.conf
|
||||
// example:
|
||||
//
|
||||
// merge:
|
||||
// $include: ./my-config.conf
|
||||
// zzz$include: ./my-config-last.conf
|
||||
// server_name: nats
|
||||
// authorization:
|
||||
// token: << $TOKEN >>
|
||||
// jetstream:
|
||||
// max_memory_store: << 1GB >>
|
||||
//
|
||||
// will yield the config:
|
||||
// {
|
||||
// include ./my-config.conf;
|
||||
// "authorization": {
|
||||
// "token": $TOKEN
|
||||
// },
|
||||
// "jetstream": {
|
||||
// "max_memory_store": 1GB
|
||||
// },
|
||||
// "server_name": "nats",
|
||||
// include ./my-config-last.conf;
|
||||
// }
|
||||
merge: {
|
||||
operator?: string
|
||||
system_account?: string
|
||||
resolver_preload?: [string]: string
|
||||
}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> pod template -> nats container
|
||||
//###########################################################
|
||||
container: {
|
||||
image: {
|
||||
repository: "nats"
|
||||
tag: "2.10.12-alpine"
|
||||
pullPolicy: null
|
||||
registry: null
|
||||
}
|
||||
|
||||
// container port options
|
||||
// must be enabled in the config section also
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#containerport-v1-core
|
||||
ports: {
|
||||
nats: {}
|
||||
leafnodes: {}
|
||||
websocket: {}
|
||||
mqtt: {}
|
||||
cluster: {}
|
||||
gateway: {}
|
||||
monitor: {}
|
||||
profiling: {}
|
||||
}
|
||||
|
||||
// map with key as env var name, value can be string or map
|
||||
// example:
|
||||
//
|
||||
// env:
|
||||
// GOMEMLIMIT: 7GiB
|
||||
// TOKEN:
|
||||
// valueFrom:
|
||||
// secretKeyRef:
|
||||
// name: nats-auth
|
||||
// key: token
|
||||
env: {}
|
||||
|
||||
// merge or patch the container
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#container-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> pod template -> reloader container
|
||||
//###########################################################
|
||||
reloader: {
|
||||
enabled: true
|
||||
image: {
|
||||
repository: "natsio/nats-server-config-reloader"
|
||||
tag: "0.14.1"
|
||||
pullPolicy: null
|
||||
registry: null
|
||||
}
|
||||
|
||||
// env var map, see nats.env for an example
|
||||
env: {}
|
||||
|
||||
// all nats container volume mounts with the following prefixes
|
||||
// will be mounted into the reloader container
|
||||
natsVolumeMountPrefixes: ["/etc/"]
|
||||
|
||||
// merge or patch the container
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#container-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> pod template -> prom-exporter container
|
||||
//###########################################################
|
||||
// config.monitor must be enabled
|
||||
promExporter: {
|
||||
enabled: true | *false
|
||||
image: {
|
||||
repository: "natsio/prometheus-nats-exporter"
|
||||
tag: "0.14.0"
|
||||
pullPolicy: null
|
||||
registry: null
|
||||
}
|
||||
|
||||
port: 7777
|
||||
// env var map, see nats.env for an example
|
||||
env: {}
|
||||
|
||||
// merge or patch the container
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#container-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
|
||||
//###########################################################
|
||||
// prometheus pod monitor
|
||||
//###########################################################
|
||||
podMonitor: {
|
||||
enabled: true | *false
|
||||
|
||||
// merge or patch the pod monitor
|
||||
// https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.PodMonitor
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// service
|
||||
//###########################################################
|
||||
service: {
|
||||
enabled: true
|
||||
|
||||
// service port options
|
||||
// additional boolean field enable to control whether port is exposed in the service
|
||||
// must be enabled in the config section also
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#serviceport-v1-core
|
||||
ports: {
|
||||
nats: enabled: true
|
||||
leafnodes: enabled: true
|
||||
websocket: enabled: true
|
||||
mqtt: enabled: true
|
||||
cluster: enabled: false
|
||||
gateway: enabled: false
|
||||
monitor: enabled: false
|
||||
profiling: enabled: false
|
||||
}
|
||||
|
||||
// merge or patch the service
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#service-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// other nats extension points
|
||||
//###########################################################
|
||||
// stateful set
|
||||
statefulSet: {
|
||||
// merge or patch the stateful set
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#statefulset-v1-apps
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
|
||||
// stateful set -> pod template
|
||||
podTemplate: {
|
||||
// adds a hash of the ConfigMap as a pod annotation
|
||||
// this will cause the StatefulSet to roll when the ConfigMap is updated
|
||||
configChecksumAnnotation: true
|
||||
|
||||
// map of topologyKey: topologySpreadConstraint
|
||||
// labelSelector will be added to match StatefulSet pods
|
||||
//
|
||||
// topologySpreadConstraints:
|
||||
// kubernetes.io/hostname:
|
||||
// maxSkew: 1
|
||||
//
|
||||
topologySpreadConstraints: {}
|
||||
|
||||
// merge or patch the pod template
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#pod-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// headless service
|
||||
headlessService: {
|
||||
// merge or patch the headless service
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#service-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-headless"
|
||||
name: null
|
||||
}
|
||||
|
||||
// config map
|
||||
configMap: {
|
||||
// merge or patch the config map
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#configmap-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-config"
|
||||
name: null
|
||||
}
|
||||
|
||||
// pod disruption budget
|
||||
podDisruptionBudget: {
|
||||
enabled: true
|
||||
// merge or patch the pod disruption budget
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#poddisruptionbudget-v1-policy
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
|
||||
// service account
|
||||
serviceAccount: {
|
||||
enabled: false
|
||||
// merge or patch the service account
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#serviceaccount-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// natsBox
|
||||
//
|
||||
// NATS Box Deployment and associated resources
|
||||
//###########################################################
|
||||
natsBox: {
|
||||
enabled: true
|
||||
|
||||
//###########################################################
|
||||
// NATS contexts
|
||||
//###########################################################
|
||||
contexts: {
|
||||
default: {
|
||||
creds: {
|
||||
// set contents in order to create a secret with the creds file contents
|
||||
contents: null
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
// defaults to /etc/nats-creds/<context-name>
|
||||
dir: null
|
||||
key: "nats.creds"
|
||||
}
|
||||
nkey: {
|
||||
// set contents in order to create a secret with the nkey file contents
|
||||
contents: null
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
// defaults to /etc/nats-nkeys/<context-name>
|
||||
dir: null
|
||||
key: "nats.nk"
|
||||
}
|
||||
// used to connect with client certificates
|
||||
tls: {
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
// defaults to /etc/nats-certs/<context-name>
|
||||
dir: null
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
}
|
||||
|
||||
// merge or patch the context
|
||||
// https://docs.nats.io/using-nats/nats-tools/nats_cli#nats-contexts
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
}
|
||||
|
||||
// name of context to select by default
|
||||
defaultContextName: "default"
|
||||
|
||||
//###########################################################
|
||||
// deployment -> pod template -> nats-box container
|
||||
//###########################################################
|
||||
container: {
|
||||
image: {
|
||||
repository: "natsio/nats-box"
|
||||
tag: "0.14.2"
|
||||
pullPolicy: null
|
||||
registry: null
|
||||
}
|
||||
|
||||
// env var map, see nats.env for an example
|
||||
env: {}
|
||||
|
||||
// merge or patch the container
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#container-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// other nats-box extension points
|
||||
//###########################################################
|
||||
// deployment
|
||||
deployment: {
|
||||
// merge or patch the deployment
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#deployment-v1-apps
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-box"
|
||||
name: null
|
||||
}
|
||||
|
||||
// deployment -> pod template
|
||||
podTemplate: {
|
||||
// merge or patch the pod template
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#pod-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// contexts secret
|
||||
contextsSecret: {
|
||||
// merge or patch the context secret
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secret-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-box-contexts"
|
||||
name: null
|
||||
}
|
||||
|
||||
// contents secret
|
||||
contentsSecret: {
|
||||
// merge or patch the contents secret
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secret-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-box-contents"
|
||||
name: null
|
||||
}
|
||||
|
||||
// service account
|
||||
serviceAccount: {
|
||||
enabled: false
|
||||
// merge or patch the service account
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#serviceaccount-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-box"
|
||||
name: null
|
||||
}
|
||||
}
|
||||
|
||||
//###############################################################################
|
||||
// Extra user-defined resources
|
||||
//###############################################################################
|
||||
//
|
||||
// add arbitrary user-generated resources
|
||||
// example:
|
||||
//
|
||||
// config:
|
||||
// websocket:
|
||||
// enabled: true
|
||||
// extraResources:
|
||||
// - apiVersion: networking.istio.io/v1beta1
|
||||
// kind: VirtualService
|
||||
// metadata:
|
||||
// name:
|
||||
// $tplYaml: >
|
||||
// {{ include "nats.fullname" $ | quote }}
|
||||
// labels:
|
||||
// $tplYaml: |
|
||||
// {{ include "nats.labels" $ }}
|
||||
// spec:
|
||||
// hosts:
|
||||
// - demo.nats.io
|
||||
// gateways:
|
||||
// - my-gateway
|
||||
// http:
|
||||
// - name: default
|
||||
// match:
|
||||
// - name: root
|
||||
// uri:
|
||||
// exact: /
|
||||
// route:
|
||||
// - destination:
|
||||
// host:
|
||||
// $tplYaml: >
|
||||
// {{ .Values.service.name | quote }}
|
||||
// port:
|
||||
// number:
|
||||
// $tplYaml: >
|
||||
// {{ .Values.config.websocket.port }}
|
||||
//
|
||||
extraResources: []
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# This script initializes authorization for a nats cluster. The process is:
|
||||
#
|
||||
# Locally:
|
||||
# 1. Generate the nats operator jwt.
|
||||
# 2. Generate a SYS account jwt issued by the operator.
|
||||
# 3. Store both into vault
|
||||
#
|
||||
# When nats is deployed an ExternalSecret populates auth.conf which is included
|
||||
# into nats.conf. This approach allows helm values to be used for most things
|
||||
# except for secrets.
|
||||
#
|
||||
# Clean up by removing the nsc directory.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
PARENT="$(cd "$(dirname $0)" && pwd)"
|
||||
: "${OPERATOR_NAME:="Holos"}"
|
||||
|
||||
: "${OIX_NAMESPACE:=$(kubectl config view --minify --flatten -ojsonpath='{.contexts[0].context.namespace}')}"
|
||||
nsc="${HOME}/.bin/nsc"
|
||||
|
||||
ROOT="${PARENT}/${OIX_NAMESPACE}/nsc"
|
||||
export NKEYS_PATH="${ROOT}/nkeys"
|
||||
export NSC_HOME="${ROOT}/accounts"
|
||||
|
||||
mkdir -p "$NKEYS_PATH"
|
||||
mkdir -p "$NSC_HOME"
|
||||
|
||||
# Install nsc if not already installed
|
||||
if ! [[ -x $nsc ]]; then
|
||||
platform="$(kubectl version --output=json | jq .clientVersion.platform -r)"
|
||||
platform="${platform//\//-}"
|
||||
curl -fSLo "${tmpdir}/nsc.zip" "https://github.com/nats-io/nsc/releases/download/v2.8.6/nsc-${platform}.zip"
|
||||
(cd "${tmpdir}" && unzip nsc.zip)
|
||||
sudo install -o 0 -g 0 -m 0755 "${tmpdir}/nsc" $nsc
|
||||
fi
|
||||
|
||||
echo "export NKEYS_PATH='${NKEYS_PATH}'" > "${ROOT}/nsc.env"
|
||||
echo "export NSC_HOME='${NSC_HOME}'" >> "${ROOT}/nsc.env"
|
||||
# use kubectl port-forward nats-headless 4222
|
||||
echo "export NATS_URL='nats://localhost:4222'" >> "${ROOT}/nsc.env"
|
||||
echo "export NATS_CREDS='${ROOT}/nkeys/creds/${OPERATOR_NAME}/SYS/sys.creds'" >> "${ROOT}/nsc.env"
|
||||
|
||||
echo "export NATS_CA='${ROOT}/ca.crt'" >> "${ROOT}/nsc.env"
|
||||
echo "export NATS_CERT='${ROOT}/tls.crt'" >> "${ROOT}/nsc.env"
|
||||
echo "export NATS_KEY='${ROOT}/tls.key'" >> "${ROOT}/nsc.env"
|
||||
|
||||
$nsc --data-dir="${ROOT}/stores" list operators
|
||||
|
||||
# Create operator
|
||||
$nsc add operator --name "${OPERATOR_NAME}"
|
||||
# Create system account
|
||||
$nsc add account --name SYS
|
||||
$nsc add user --name sys
|
||||
# Create account for STAN purposes.
|
||||
$nsc add account --name STAN
|
||||
$nsc add user --name stan
|
||||
|
||||
# Generate an auth config compatible with the StatefulSet mounting the
|
||||
# nats-jwt-pvc PersistentVolumeClaim at path /data/accounts
|
||||
$nsc generate config --sys-account SYS --nats-resolver \
|
||||
| sed "s,dir.*jwt',dir: '/data/accounts'" \
|
||||
> "${ROOT}/auth.conf"
|
||||
|
||||
# Store the auth config in vault.
|
||||
# vault kv put kv/${OIX_CLUSTER_NAME}/kube-namespace/holos-dev/nats-auth-config "auth.conf=@${tmpdir}/auth.conf"
|
||||
# Store the SYS creds in vault for use by the nack controller.
|
||||
# vault kv put kv/${OIX_CLUSTER_NAME}/kube-namespace/holos-dev/nats-sys-creds "sys.creds=@${OIX_CLUSTER_NAME}/nsc/nkeys/creds/${OPERATOR_NAME}/SYS/sys.creds"
|
||||
|
||||
echo "After deploying the nats component, use the get-cert command to fetch the client cert."
|
||||
|
||||
echo "Use kubectl port-forward svc/nats-headless 4222" >&2
|
||||
echo "source ${ROOT}/nsc.env to make it all work." >&2
|
||||
5
docs/examples/platforms/holos-saas/readme.md
Normal file
5
docs/examples/platforms/holos-saas/readme.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Holos
|
||||
|
||||
This subtree contains holos components for holos itself. We strive for minimal dependencies, so this is likely going to contain NATS and/or Postgres resources.
|
||||
|
||||
Components depend on the holos project and may iterate over the defined environments in the project stages.
|
||||
56
docs/examples/platforms/optional.site.cue
Normal file
56
docs/examples/platforms/optional.site.cue
Normal file
@@ -0,0 +1,56 @@
|
||||
package holos
|
||||
|
||||
let CoreDomain = "core.\(#Platform.org.domain)"
|
||||
let TargetNamespace = "prod-core-vault"
|
||||
|
||||
#OptionalServices: {
|
||||
vault: {
|
||||
enabled: true
|
||||
clusters: core1: _
|
||||
clusters: core2: _
|
||||
managedNamespaces: "prod-core-vault": {
|
||||
namespace: metadata: labels: "istio-injection": "enabled"
|
||||
}
|
||||
certs: "vault-core": #Certificate & {
|
||||
metadata: name: "vault-core"
|
||||
metadata: namespace: "istio-ingress"
|
||||
spec: {
|
||||
commonName: "vault.\(CoreDomain)"
|
||||
dnsNames: [commonName]
|
||||
secretName: metadata.name
|
||||
issuerRef: kind: "ClusterIssuer"
|
||||
issuerRef: name: string | *"letsencrypt"
|
||||
}
|
||||
}
|
||||
servers: "https-vault-core": {
|
||||
hosts: ["\(TargetNamespace)/vault.\(CoreDomain)"]
|
||||
tls: credentialName: certs."vault-core".spec.secretName
|
||||
}
|
||||
for k, v in clusters {
|
||||
let obj = (Cert & {Name: "vault-core", Cluster: v.name}).APIObject
|
||||
certs: "\(obj.metadata.name)": obj
|
||||
servers: "https-\(obj.metadata.name)": {
|
||||
hosts: [for host in obj.spec.dnsNames {"\(TargetNamespace)/\(host)"}]
|
||||
tls: credentialName: obj.spec.secretName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cert provisions a cluster specific certificate.
|
||||
let Cert = {
|
||||
Name: string
|
||||
Cluster: string
|
||||
|
||||
APIObject: #Certificate & {
|
||||
metadata: name: "\(Cluster)-\(Name)"
|
||||
metadata: namespace: string | *"istio-ingress"
|
||||
spec: {
|
||||
commonName: string | *"vault.\(Cluster).\(CoreDomain)"
|
||||
dnsNames: [commonName]
|
||||
secretName: metadata.name
|
||||
issuerRef: kind: "ClusterIssuer"
|
||||
issuerRef: name: string | *"letsencrypt"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,21 @@
|
||||
package holos
|
||||
|
||||
#PlatformServers: {
|
||||
for cluster in #Platform.clusters {
|
||||
(cluster.name): {
|
||||
"https-istio-ingress-httpbin": {
|
||||
let cert = #PlatformCerts[cluster.name+"-httpbin"]
|
||||
hosts: [for host in cert.spec.dnsNames {"istio-ingress/\(host)"}]
|
||||
port: name: "https-istio-ingress-httpbin"
|
||||
port: number: 443
|
||||
port: protocol: "HTTPS"
|
||||
tls: credentialName: cert.spec.secretName
|
||||
tls: mode: "SIMPLE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#PlatformCerts: {
|
||||
// Globally scoped platform services are defined here.
|
||||
login: #PlatformCert & {
|
||||
@@ -44,7 +60,8 @@ package holos
|
||||
_name: string
|
||||
_cluster: string
|
||||
_wildcard: true | *false
|
||||
metadata: name: string | *"\(_cluster)-\(_name)"
|
||||
// Enforce this value
|
||||
metadata: name: "\(_cluster)-\(_name)"
|
||||
metadata: namespace: string | *"istio-ingress"
|
||||
spec: {
|
||||
commonName: string | *"\(_name).\(_cluster).\(#Platform.org.domain)"
|
||||
|
||||
@@ -4,7 +4,4 @@ package holos
|
||||
#InputKeys: project: "iam"
|
||||
|
||||
// Shared dependencies for all components in this collection.
|
||||
#DependsOn: _Namespaces
|
||||
|
||||
// Common Dependencies
|
||||
_Namespaces: Namespaces: name: "\(#StageName)-secrets-namespaces"
|
||||
#DependsOn: namespaces: name: "\(#StageName)-secrets-stores"
|
||||
@@ -0,0 +1,10 @@
|
||||
To deploy monitoring:
|
||||
|
||||
> **_NOTE:_** For more detailed instructions on deploying, see the [documentation on installing Monitoring](https://access.crunchydata.com/documentation/postgres-operator/latest/installation/monitoring/kustomize).
|
||||
|
||||
1. verify the namespace is correct in kustomization.yaml
|
||||
2. If you are deploying in openshift, comment out the fsGroup line under securityContext in the following files:
|
||||
- `alertmanager/deployment.yaml`
|
||||
- `grafana/deployment.yaml`
|
||||
- `prometheus/deployment.yaml`
|
||||
3. kubectl apply -k .
|
||||
@@ -0,0 +1,78 @@
|
||||
###
|
||||
#
|
||||
# Copyright © 2017-2024 Crunchy Data Solutions, Inc. All Rights Reserved.
|
||||
#
|
||||
###
|
||||
|
||||
# Based on upstream example file found here: https://github.com/prometheus/alertmanager/blob/master/doc/examples/simple.yml
|
||||
global:
|
||||
smtp_smarthost: 'localhost: 25'
|
||||
smtp_require_tls: false
|
||||
smtp_from: 'Alertmanager <abc@yahoo.com>'
|
||||
# smtp_smarthost: 'smtp.example.com:587'
|
||||
# smtp_from: 'Alertmanager <abc@yahoo.com>'
|
||||
# smtp_auth_username: '<username>'
|
||||
# smtp_auth_password: '<password>'
|
||||
|
||||
# templates:
|
||||
# - '/etc/alertmanager/template/*.tmpl'
|
||||
|
||||
inhibit_rules:
|
||||
# Apply inhibition of warning if the alertname for the same system and service is already critical
|
||||
- source_match:
|
||||
severity: 'critical'
|
||||
target_match:
|
||||
severity: 'warning'
|
||||
equal: ['alertname', 'job', 'service']
|
||||
|
||||
receivers:
|
||||
- name: 'default-receiver'
|
||||
email_configs:
|
||||
- to: 'example@crunchydata.com'
|
||||
send_resolved: true
|
||||
|
||||
## Examples of alternative alert receivers. See documentation for more info on how to configure these fully
|
||||
#- name: 'pagerduty-dba'
|
||||
# pagerduty_configs:
|
||||
# - service_key: <RANDOMKEYSTUFF>
|
||||
|
||||
#- name: 'pagerduty-sre'
|
||||
# pagerduty_configs:
|
||||
# - service_key: <RANDOMKEYSTUFF>
|
||||
|
||||
#- name: 'dba-team'
|
||||
# email_configs:
|
||||
# - to: 'example-dba-team@crunchydata.com'
|
||||
# send_resolved: true
|
||||
|
||||
#- name: 'sre-team'
|
||||
# email_configs:
|
||||
# - to: 'example-sre-team@crunchydata.com'
|
||||
# send_resolved: true
|
||||
|
||||
route:
|
||||
receiver: default-receiver
|
||||
group_by: [severity, service, job, alertname]
|
||||
group_wait: 30s
|
||||
group_interval: 5m
|
||||
repeat_interval: 24h
|
||||
|
||||
## Example routes to show how to route outgoing alerts based on the content of that alert
|
||||
# routes:
|
||||
# - match_re:
|
||||
# service: ^(postgresql|mysql|oracle)$
|
||||
# receiver: dba-team
|
||||
# # sub route to send critical dba alerts to pagerduty
|
||||
# routes:
|
||||
# - match:
|
||||
# severity: critical
|
||||
# receiver: pagerduty-dba
|
||||
#
|
||||
# - match:
|
||||
# service: system
|
||||
# receiver: sre-team
|
||||
# # sub route to send critical sre alerts to pagerduty
|
||||
# routes:
|
||||
# - match:
|
||||
# severity: critical
|
||||
# receiver: pagerduty-sre
|
||||
@@ -0,0 +1,46 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: crunchy-alertmanager
|
||||
spec:
|
||||
selector: {}
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: alertmanager
|
||||
image: prom/alertmanager:v0.24.0
|
||||
args:
|
||||
- --config.file=/etc/alertmanager/alertmanager.yml
|
||||
- --storage.path=/alertmanager
|
||||
- --log.level=info
|
||||
- --cluster.advertise-address=0.0.0.0:9093
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /-/healthy
|
||||
port: 9093
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 20
|
||||
ports:
|
||||
- containerPort: 9093
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /-/ready
|
||||
port: 9093
|
||||
volumeMounts:
|
||||
- mountPath: /etc/alertmanager
|
||||
name: alertmanagerconf
|
||||
- mountPath: /alertmanager
|
||||
name: alertmanagerdata
|
||||
securityContext:
|
||||
fsGroup: 26
|
||||
# supplementalGroups:
|
||||
# - 65534
|
||||
serviceAccountName: alertmanager
|
||||
volumes:
|
||||
- name: alertmanagerdata
|
||||
persistentVolumeClaim:
|
||||
claimName: alertmanagerdata
|
||||
- name: alertmanagerconf
|
||||
configMap:
|
||||
defaultMode: 420
|
||||
name: alertmanager-config
|
||||
@@ -0,0 +1,21 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
labels:
|
||||
- includeSelectors: true
|
||||
pairs:
|
||||
app.kubernetes.io/component: crunchy-alertmanager
|
||||
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- pvc.yaml
|
||||
- service.yaml
|
||||
- serviceaccount.yaml
|
||||
|
||||
configMapGenerator:
|
||||
- name: alertmanager-config
|
||||
files:
|
||||
- config/alertmanager.yml
|
||||
|
||||
generatorOptions:
|
||||
disableNameSuffixHash: true
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: alertmanagerdata
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: crunchy-alertmanager
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: alertmanager
|
||||
port: 9093
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: alertmanager
|
||||
@@ -0,0 +1,16 @@
|
||||
###
|
||||
#
|
||||
# Copyright © 2017-2024 Crunchy Data Solutions, Inc. All Rights Reserved.
|
||||
#
|
||||
###
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: 'crunchy_dashboards'
|
||||
orgId: 1
|
||||
folder: ''
|
||||
type: file
|
||||
disableDeletion: false
|
||||
updateIntervalSeconds: 3 #how often Grafana will scan for changed dashboards
|
||||
options:
|
||||
path: /etc/grafana/provisioning/dashboards
|
||||
@@ -0,0 +1,18 @@
|
||||
###
|
||||
#
|
||||
# Copyright © 2017-2024 Crunchy Data Solutions, Inc. All Rights Reserved.
|
||||
#
|
||||
###
|
||||
|
||||
# config file version
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: PROMETHEUS
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://$PROM_HOST:$PROM_PORT
|
||||
isDefault: True
|
||||
editable: False
|
||||
orgId: 1
|
||||
version: 1
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
configMapGenerator:
|
||||
- name: grafana-dashboards
|
||||
files:
|
||||
- pgbackrest.json
|
||||
- pod_details.json
|
||||
- postgresql_overview.json
|
||||
- postgresql_details.json
|
||||
- postgresql_service_health.json
|
||||
- prometheus_alerts.json
|
||||
- query_statistics.json
|
||||
|
||||
generatorOptions:
|
||||
disableNameSuffixHash: true
|
||||
@@ -0,0 +1,687 @@
|
||||
{
|
||||
"__inputs": [
|
||||
{
|
||||
"name": "DS_PROMETHEUS",
|
||||
"label": "PROMETHEUS",
|
||||
"description": "",
|
||||
"type": "datasource",
|
||||
"pluginId": "prometheus",
|
||||
"pluginName": "Prometheus"
|
||||
}
|
||||
],
|
||||
"__requires": [
|
||||
{
|
||||
"type": "grafana",
|
||||
"id": "grafana",
|
||||
"name": "Grafana",
|
||||
"version": "7.4.5"
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "graph",
|
||||
"name": "Graph",
|
||||
"version": ""
|
||||
},
|
||||
{
|
||||
"type": "datasource",
|
||||
"id": "prometheus",
|
||||
"name": "Prometheus",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "stat",
|
||||
"name": "Stat",
|
||||
"version": ""
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": false,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"iteration": 1625069660860,
|
||||
"links": [
|
||||
{
|
||||
"asDropdown": false,
|
||||
"icon": "external link",
|
||||
"includeVars": true,
|
||||
"keepTime": true,
|
||||
"tags": [
|
||||
"vendor=crunchydata"
|
||||
],
|
||||
"title": "",
|
||||
"type": "dashboards"
|
||||
}
|
||||
],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": "PROMETHEUS",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"custom": {},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "semi-dark-blue",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "dtdhms"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 3,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 8,
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"last"
|
||||
],
|
||||
"fields": "/^Value$/",
|
||||
"values": false
|
||||
},
|
||||
"text": {
|
||||
"valueSize": 45
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "7.4.5",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "time()-ccp_backrest_oldest_full_backup_time_seconds{pg_cluster=\"[[cluster]]\", role=\"master\"}",
|
||||
"format": "table",
|
||||
"instant": true,
|
||||
"interval": "",
|
||||
"legendFormat": "Recovery window",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Recovery Window",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"aliasColors": {
|
||||
"Differential": "dark-blue",
|
||||
"Differential Backup": "dark-blue",
|
||||
"Full": "dark-green",
|
||||
"Full Backup": "dark-green",
|
||||
"Incremental": "light-blue",
|
||||
"Incremental Backup": "light-blue"
|
||||
},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "PROMETHEUS",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {},
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 3
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 2,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"sideWidth": 150,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": false
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.4.5",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_incr_backup_time_since_completion_seconds{pg_cluster=\"[[cluster]]\", role=\"master\"}) without(deployment,instance,ip,pod)",
|
||||
"format": "time_series",
|
||||
"instant": false,
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Incremental Backup",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_diff_backup_time_since_completion_seconds{pg_cluster=\"[[cluster]]\", role=\"master\"}) without(deployment, instance,ip,pod)",
|
||||
"hide": false,
|
||||
"interval": "",
|
||||
"legendFormat": "Differential Backup",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_full_backup_time_since_completion_seconds{pg_cluster=\"[[cluster]]\", role=\"master\"}) without(deployment, instance,ip,pod)",
|
||||
"hide": false,
|
||||
"interval": "",
|
||||
"legendFormat": "Full Backup",
|
||||
"refId": "C"
|
||||
},
|
||||
{
|
||||
"expr": "min(ccp_archive_command_status_seconds_since_last_archive{pg_cluster=\"[[cluster]]\", role=\"master\"}) without(deployment, instance,ip,pod)",
|
||||
"hide": false,
|
||||
"interval": "",
|
||||
"legendFormat": "WAL Archive",
|
||||
"refId": "D"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Time Since",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "s",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": false
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {
|
||||
"Differential": "dark-blue",
|
||||
"Full": "dark-green",
|
||||
"Incremental": "light-blue"
|
||||
},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "PROMETHEUS",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {},
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 3
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 4,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"hideEmpty": false,
|
||||
"hideZero": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"sideWidth": 150,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.4.5",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_info_backup_runtime_seconds{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"incr\"}) without (deployment,instance,pod,ip)",
|
||||
"format": "time_series",
|
||||
"instant": false,
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Incremental",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_info_backup_runtime_seconds{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"diff\"}) without (deployment,instance,pod,ip)",
|
||||
"hide": false,
|
||||
"interval": "",
|
||||
"legendFormat": "Differential",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_info_backup_runtime_seconds{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"full\"}) without (deployment,instance,pod,ip)",
|
||||
"hide": false,
|
||||
"interval": "",
|
||||
"legendFormat": "Full",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Backup Runtimes",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "s",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 2,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": false
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {
|
||||
"Differential": "dark-blue",
|
||||
"Full": "dark-green",
|
||||
"Incremental": "light-blue"
|
||||
},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "PROMETHEUS",
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {},
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 10
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 5,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"hideEmpty": false,
|
||||
"hideZero": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"sideWidth": 150,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.4.5",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_info_repo_backup_size_bytes{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"incr\"}) without (deployment, instance,pod,ip)",
|
||||
"format": "time_series",
|
||||
"instant": false,
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Incremental",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_info_repo_backup_size_bytes{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"diff\"}) without (deployment,instance,pod,ip)",
|
||||
"hide": false,
|
||||
"interval": "",
|
||||
"legendFormat": "Differential",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "min(ccp_backrest_last_info_repo_backup_size_bytes{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"full\"}) without (deployment,instance,pod,ip)",
|
||||
"hide": false,
|
||||
"interval": "",
|
||||
"legendFormat": "Full",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Backup Size",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 2,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": false
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {
|
||||
"Archive age": "blue",
|
||||
"Archive count": "green",
|
||||
"Differential": "dark-blue",
|
||||
"Failed count": "red",
|
||||
"Full": "dark-green",
|
||||
"Incremental": "light-blue"
|
||||
},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "PROMETHEUS",
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {},
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 3,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 10
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 6,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"hideEmpty": false,
|
||||
"hideZero": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"sideWidth": 150,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.4.5",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "avg(idelta(ccp_archive_command_status_failed_count{pg_cluster=\"[[cluster]]\", role=\"master\"}[1m])) without (instance,ip)",
|
||||
"format": "time_series",
|
||||
"instant": false,
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Failed count",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "avg(idelta(ccp_archive_command_status_archived_count{pg_cluster=\"[[cluster]]\", role=\"master\"}[1m])) without (instance,pod, ip)",
|
||||
"hide": false,
|
||||
"interval": "",
|
||||
"legendFormat": "Archive count",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "WAL Stats",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": "",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": "0",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": "0",
|
||||
"show": false
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"refresh": "5m",
|
||||
"schemaVersion": 27,
|
||||
"style": "dark",
|
||||
"tags": [
|
||||
"vendor=crunchydata"
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {},
|
||||
"datasource": "PROMETHEUS",
|
||||
"definition": "label_values(pg_cluster)",
|
||||
"description": null,
|
||||
"error": null,
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "cluster",
|
||||
"multi": false,
|
||||
"name": "cluster",
|
||||
"options": [],
|
||||
"query": {
|
||||
"query": "label_values(pg_cluster)",
|
||||
"refId": "PROMETHEUS-cluster-Variable-Query"
|
||||
},
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 1,
|
||||
"tagValuesQuery": "",
|
||||
"tags": [],
|
||||
"tagsQuery": "",
|
||||
"type": "query",
|
||||
"useTags": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-2w",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "browser",
|
||||
"title": "pgBackRest",
|
||||
"uid": "2fcFZ6PGk",
|
||||
"version": 1
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user