mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 16:54:58 +00:00
Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f0de7555c | ||
|
|
650636f944 | ||
|
|
b28c110694 | ||
|
|
5bb3e90b38 | ||
|
|
6a60b613ff | ||
|
|
5862725bab | ||
|
|
8660826b05 | ||
|
|
449df91e33 | ||
|
|
ac59173b30 | ||
|
|
fb75e560fc | ||
|
|
69a064e3ea | ||
|
|
71b72807bb | ||
|
|
0e4ecf9d13 | ||
|
|
ec2fdadd44 | ||
|
|
38b082095f | ||
|
|
f9346ea7c0 | ||
|
|
0f7010288a | ||
|
|
386fb89cc6 | ||
|
|
c5401d6b02 | ||
|
|
f215405643 | ||
|
|
2c79982bd3 | ||
|
|
e5e4de3073 | ||
|
|
ec462f5f0b | ||
|
|
0e95a2812e | ||
|
|
54efe3e24a | ||
|
|
f693f049f4 | ||
|
|
85238710ac | ||
|
|
3ec62d272e | ||
|
|
49afb44fd4 | ||
|
|
a023f135ab | ||
|
|
c6a3a5d689 | ||
|
|
3f1eed3f06 | ||
|
|
7fb7df1441 | ||
|
|
a798111d4d | ||
|
|
3ddb823341 | ||
|
|
70d48592c4 | ||
|
|
006f08df93 | ||
|
|
39e2db5d37 | ||
|
|
ceb293fd8a | ||
|
|
188ff95015 | ||
|
|
5f658e0ba0 | ||
|
|
18b2850d3c | ||
|
|
366a7fe93d | ||
|
|
f71d6d5bd9 | ||
|
|
4529673e93 | ||
|
|
16a6447926 | ||
|
|
111a5944ff | ||
|
|
ff1446dc93 | ||
|
|
67ef990c37 | ||
|
|
6bd54ab856 | ||
|
|
89a23a10fd | ||
|
|
5a939bb6fe | ||
|
|
ee16f14e03 | ||
|
|
7530345620 | ||
|
|
47d60ef86d | ||
|
|
9e9f6efd04 | ||
|
|
fb4a043823 | ||
|
|
d718ab1910 | ||
|
|
c649db18a9 | ||
|
|
b3bddf3ee3 | ||
|
|
77836be250 | ||
|
|
4db670b854 | ||
|
|
d87c919519 | ||
|
|
2184bda2a1 | ||
|
|
a8ab4dabaa | ||
|
|
7175950ce0 | ||
|
|
e186c1be37 | ||
|
|
a998513e34 | ||
|
|
2f821ec33c | ||
|
|
4d54190f2e | ||
|
|
b466ec3457 | ||
|
|
45120797b9 | ||
|
|
e6d25bf5eb | ||
|
|
3ad6e69336 | ||
|
|
9b10e23e43 | ||
|
|
b19022d3ff | ||
|
|
3fd06f594b | ||
|
|
a75338f21c |
12
.cspell.json
12
.cspell.json
@@ -29,6 +29,7 @@
|
||||
"authpolicy",
|
||||
"authproxy",
|
||||
"authroutes",
|
||||
"autoload",
|
||||
"automount",
|
||||
"automounting",
|
||||
"autoscaler",
|
||||
@@ -36,6 +37,7 @@
|
||||
"blackbox",
|
||||
"buildplan",
|
||||
"buildplans",
|
||||
"Buildx",
|
||||
"builtinpluginloadingoptions",
|
||||
"cachedir",
|
||||
"cadvisor",
|
||||
@@ -44,6 +46,7 @@
|
||||
"certificaterequest",
|
||||
"certificaterequests",
|
||||
"certificatesigningrequests",
|
||||
"chartmuseum",
|
||||
"clientset",
|
||||
"clsx",
|
||||
"clusterexternalsecret",
|
||||
@@ -58,6 +61,7 @@
|
||||
"Cmds",
|
||||
"CNCF",
|
||||
"CODEOWNERS",
|
||||
"compinit",
|
||||
"componentconfig",
|
||||
"configdir",
|
||||
"configmap",
|
||||
@@ -71,6 +75,7 @@
|
||||
"creds",
|
||||
"crossplane",
|
||||
"crunchydata",
|
||||
"ctxt",
|
||||
"cuecontext",
|
||||
"cuelang",
|
||||
"customresourcedefinition",
|
||||
@@ -80,6 +85,7 @@
|
||||
"destinationrules",
|
||||
"devel",
|
||||
"devicecode",
|
||||
"distroless",
|
||||
"dnsmasq",
|
||||
"dscacheutil",
|
||||
"ecrauthorizationtoken",
|
||||
@@ -98,6 +104,7 @@
|
||||
"fieldmaskpb",
|
||||
"fieldspec",
|
||||
"flushcache",
|
||||
"fluxcd",
|
||||
"fullname",
|
||||
"gatewayclass",
|
||||
"gatewayclasses",
|
||||
@@ -151,6 +158,7 @@
|
||||
"jetstack",
|
||||
"jiralert",
|
||||
"Jsonnet",
|
||||
"Kargo",
|
||||
"kfbh",
|
||||
"killall",
|
||||
"kubeadm",
|
||||
@@ -188,6 +196,7 @@
|
||||
"mutatingwebhookconfigurations",
|
||||
"mvdan",
|
||||
"mxcl",
|
||||
"mychart",
|
||||
"myhostname",
|
||||
"myRegistrKeySecretName",
|
||||
"mysecret",
|
||||
@@ -274,6 +283,7 @@
|
||||
"serviceentries",
|
||||
"serviceentry",
|
||||
"servicemonitor",
|
||||
"sigstore",
|
||||
"somevalue",
|
||||
"SOMEVAR",
|
||||
"sortoptions",
|
||||
@@ -309,10 +319,12 @@
|
||||
"traefik",
|
||||
"transactionhistory",
|
||||
"tsdb",
|
||||
"txtar",
|
||||
"typemeta",
|
||||
"udev",
|
||||
"uibutton",
|
||||
"Unmarshal",
|
||||
"unshallow",
|
||||
"unstage",
|
||||
"untar",
|
||||
"upbound",
|
||||
|
||||
131
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
131
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: NeedsInvestigation, Triage
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!--
|
||||
Please answer these questions before submitting your issue. Thanks!
|
||||
To ask questions, see https://github.com/holos-run/holos/discussions
|
||||
-->
|
||||
|
||||
### What version of holos are you using (`holos --version`)?
|
||||
|
||||
```
|
||||
0.0.0
|
||||
```
|
||||
|
||||
### Does this issue reproduce with the latest release?
|
||||
|
||||
<!--
|
||||
Get the latest release with:
|
||||
|
||||
brew install holos-run/tap/holos
|
||||
|
||||
Or see https://holos.run/docs/v1alpha5/tutorial/setup/
|
||||
-->
|
||||
|
||||
### What did you do?
|
||||
|
||||
<!--
|
||||
Please provide a testscript that should pass, but does not because of the bug.
|
||||
See the below example.
|
||||
|
||||
You can create a txtar from a directory with:
|
||||
|
||||
holos txtar ./path/to/dir
|
||||
|
||||
Refer to: https://github.com/rogpeppe/go-internal/tree/master/cmd/testscript
|
||||
-->
|
||||
|
||||
Steps to reproduce:
|
||||
|
||||
```shell
|
||||
testscript -v -continue <<EOF
|
||||
```
|
||||
|
||||
```txtar
|
||||
# Have: an error related to the imported Kustomize schemas.
|
||||
# Want: holos show buildplans to work.
|
||||
exec holos --version
|
||||
exec holos init platform v1alpha5 --force
|
||||
# remove the fix to trigger the bug
|
||||
rm cue.mod/pkg/sigs.k8s.io/kustomize/api/types/var.cue
|
||||
# want a BuildPlan shown
|
||||
exec holos show buildplans
|
||||
cmp stdout buildplan.yaml
|
||||
# want this error to go away
|
||||
! stderr 'cannot convert non-concrete value string'
|
||||
-- buildplan.yaml --
|
||||
kind: BuildPlan
|
||||
-- platform/example.cue --
|
||||
package holos
|
||||
|
||||
Platform: Components: example: {
|
||||
name: "example"
|
||||
path: "components/example"
|
||||
}
|
||||
-- components/example/example.cue --
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
Component: #Kustomize & {
|
||||
KustomizeConfig: Kustomization: patches: [
|
||||
{
|
||||
target: kind: "CustomResourceDefinition"
|
||||
patch: yaml.Marshal([{
|
||||
op: "add"
|
||||
path: "/metadata/annotations/example"
|
||||
value: "example-value"
|
||||
}])
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
```shell
|
||||
EOF
|
||||
```
|
||||
|
||||
### What did you expect to see?
|
||||
|
||||
The testscript should pass.
|
||||
|
||||
### What did you see instead?
|
||||
|
||||
The testscript fails because of the bug.
|
||||
|
||||
```txt
|
||||
# Have: an error related to the imported Kustomize schemas.
|
||||
# Want: holos show buildplans to work. (0.168s)
|
||||
> exec holos --version
|
||||
[stdout]
|
||||
0.100.1-2-g9b10e23-dirty
|
||||
> exec holos init platform v1alpha5 --force
|
||||
# remove the fix to trigger the bug (0.000s)
|
||||
> rm cue.mod/pkg/sigs.k8s.io/kustomize/api/types/var.cue
|
||||
# want a BuildPlan shown (0.091s)
|
||||
> exec holos show buildplans
|
||||
[stderr]
|
||||
could not run: holos.spec.artifacts.0.transformers.0.kustomize.kustomization.patches.0.target.name: cannot convert non-concrete value string at builder/v1alpha5/builder.go:218
|
||||
holos.spec.artifacts.0.transformers.0.kustomize.kustomization.patches.0.target.name: cannot convert non-concrete value string:
|
||||
$WORK/cue.mod/gen/sigs.k8s.io/kustomize/api/types/var_go_gen.cue:33:2
|
||||
[exit status 1]
|
||||
FAIL: <stdin>:8: unexpected command failure
|
||||
> cmp stdout buildplan.yaml
|
||||
diff stdout buildplan.yaml
|
||||
--- stdout
|
||||
+++ buildplan.yaml
|
||||
@@ -0,0 +1,1 @@
|
||||
+kind: BuildPlan
|
||||
|
||||
FAIL: <stdin>:9: stdout and buildplan.yaml differ
|
||||
# want this error to go away (0.000s)
|
||||
> ! stderr 'cannot convert non-concrete value string'
|
||||
FAIL: <stdin>:11: unexpected match for `cannot convert non-concrete value string` found in stderr: cannot convert non-concrete value string
|
||||
failed run
|
||||
```
|
||||
143
.github/workflows/container.yaml
vendored
Normal file
143
.github/workflows/container.yaml
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
name: Container
|
||||
|
||||
# Only allow actors with write permission to the repository to trigger this
|
||||
# workflow.
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
git_ref:
|
||||
description: 'Git ref to build (e.g., refs/tags/v1.2.3, refs/heads/main)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
buildx:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Set tag from trigger event
|
||||
id: opts
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
echo "ref=${{ inputs.git_ref }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "ref=${GITHUB_REF}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ steps.opts.outputs.ref }}
|
||||
- name: SHA
|
||||
id: sha
|
||||
run: echo "sha=$(/usr/bin/git log -1 --format='%H')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Fetch tags
|
||||
run: git fetch --prune --unshallow --tags
|
||||
- name: Set Tags
|
||||
id: tags
|
||||
run: |
|
||||
echo "detail=$(/usr/bin/git describe --tags HEAD)" >> $GITHUB_OUTPUT
|
||||
echo "suffix=$(test -n "$(git status --porcelain)" && echo '-dirty' || echo '')" >> $GITHUB_OUTPUT
|
||||
echo "tag=$(/usr/bin/git describe --tags HEAD)$(test -n "$(git status --porcelain)" && echo '-dirty' || echo '')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push container images
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/holos-run/holos:${{ steps.tags.outputs.tag }}
|
||||
ghcr.io/holos-run/holos:${{ steps.sha.outputs.sha }}${{ steps.tags.outputs.suffix }}
|
||||
- name: Setup Cosign to sign container images
|
||||
uses: sigstore/cosign-installer@v3.7.0
|
||||
- name: Sign with GitHub OIDC Token
|
||||
env:
|
||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||
run: |
|
||||
cosign sign --yes ghcr.io/holos-run/holos:${{ steps.tags.outputs.tag }}@${DIGEST}
|
||||
cosign sign --yes ghcr.io/holos-run/holos:${{ steps.sha.outputs.sha }}${{ steps.tags.outputs.suffix }}@${DIGEST}
|
||||
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
owner: ${{ github.repository_owner }}
|
||||
app-id: ${{ vars.GORELEASER_APP_ID }}
|
||||
private-key: ${{ secrets.GORELEASER_APP_PRIVATE_KEY }}
|
||||
- name: Get GitHub App User ID
|
||||
id: get-user-id
|
||||
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
- run: |
|
||||
git config --global user.name '${{ steps.app-token.outputs.app-slug }}[bot]'
|
||||
git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com'
|
||||
- name: Update holos-run/holos-action
|
||||
env:
|
||||
IMAGE: ghcr.io/holos-run/holos:v0.102.1
|
||||
VERSION: ${{ steps.tags.outputs.tag }}
|
||||
USER_ID: ${{ steps.get-user-id.outputs.user-id }}
|
||||
TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git clone "https://github.com/holos-run/holos-action"
|
||||
cd holos-action
|
||||
git remote set-url origin https://${USER_ID}:${TOKEN}@github.com/holos-run/holos-action
|
||||
docker pull --quiet "${IMAGE}"
|
||||
docker run -v $(pwd):/app --workdir /app --rm "${IMAGE}" \
|
||||
holos cue export --out yaml action.cue -t "version=${VERSION}" > action.yml
|
||||
git add action.yml
|
||||
git commit -m "ci: update holos to ${VERSION} - https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" || (echo "No changes to commit"; exit 0)
|
||||
git push origin HEAD:main HEAD:v0 HEAD:v1
|
||||
|
||||
- name: Login to quay.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_USER }}
|
||||
password: ${{ secrets.QUAY_TOKEN }}
|
||||
- name: Push to quay.io
|
||||
env:
|
||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||
run: |
|
||||
# docker push quay.io/holos-run/holos:${{ steps.tags.outputs.tag }}
|
||||
docker pull --quiet ghcr.io/holos-run/holos:${{ steps.tags.outputs.tag }}@${DIGEST}
|
||||
docker tag ghcr.io/holos-run/holos:${{ steps.tags.outputs.tag }}@${DIGEST} \
|
||||
quay.io/holos-run/holos:${{ steps.tags.outputs.tag }}
|
||||
docker push quay.io/holos-run/holos:${{ steps.tags.outputs.tag }}
|
||||
|
||||
docker pull --quiet ghcr.io/holos-run/holos:${{ steps.sha.outputs.sha }}${{ steps.tags.outputs.suffix }}@${DIGEST}
|
||||
docker tag ghcr.io/holos-run/holos:${{ steps.sha.outputs.sha }}${{ steps.tags.outputs.suffix }}@${DIGEST} \
|
||||
quay.io/holos-run/holos:${{ steps.sha.outputs.sha }}${{ steps.tags.outputs.suffix }}
|
||||
docker push quay.io/holos-run/holos:${{ steps.sha.outputs.sha }}${{ steps.tags.outputs.suffix }}
|
||||
- name: Sign quay.io image
|
||||
env:
|
||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||
run: |
|
||||
cosign sign --yes quay.io/holos-run/holos:${{ steps.tags.outputs.tag }}@${DIGEST}
|
||||
cosign sign --yes quay.io/holos-run/holos:${{ steps.sha.outputs.sha }}${{ steps.tags.outputs.suffix }}@${DIGEST}
|
||||
|
||||
outputs:
|
||||
tag: ${{ steps.tags.outputs.tag }}
|
||||
detail: ${{ steps.tags.outputs.detail }}
|
||||
2
.github/workflows/dev-deploy.yaml
vendored
2
.github/workflows/dev-deploy.yaml
vendored
@@ -2,7 +2,7 @@ name: Dev Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['main', 'dev-deploy']
|
||||
branches: ['dev-deploy']
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
||||
33
.github/workflows/lint.yaml
vendored
33
.github/workflows/lint.yaml
vendored
@@ -1,6 +1,5 @@
|
||||
---
|
||||
# https://github.com/golangci/golangci-lint-action?tab=readme-ov-file#how-to-use
|
||||
name: Lint
|
||||
name: Spelling
|
||||
"on":
|
||||
push:
|
||||
branches:
|
||||
@@ -8,35 +7,11 @@ name: Lint
|
||||
- test
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: lint
|
||||
cspell:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: stable
|
||||
|
||||
## Not needed on ubuntu-latest
|
||||
# - name: Install Packages
|
||||
# run: sudo apt update && sudo apt -qq -y install git curl zip unzip tar bzip2 make
|
||||
|
||||
- name: Install Tools
|
||||
run: make tools
|
||||
|
||||
- name: Lint
|
||||
# golangci-lint runs in a separate workflow.
|
||||
run: make lint -o golangci-lint
|
||||
- uses: actions/checkout@v4
|
||||
- run: ./hack/cspell
|
||||
|
||||
8
.github/workflows/test.yaml
vendored
8
.github/workflows/test.yaml
vendored
@@ -28,19 +28,11 @@ jobs:
|
||||
with:
|
||||
go-version: stable
|
||||
|
||||
- name: Install Packages
|
||||
run: sudo apt update && sudo apt -qq -y install git curl zip unzip tar bzip2 make
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v4
|
||||
|
||||
- name: Set up Kubectl
|
||||
uses: azure/setup-kubectl@v4
|
||||
|
||||
- name: Install Tools
|
||||
run: |
|
||||
set -x
|
||||
make tools
|
||||
|
||||
- name: Test
|
||||
run: ./scripts/test
|
||||
|
||||
39
Dockerfile
39
Dockerfile
@@ -1,8 +1,31 @@
|
||||
FROM quay.io/holos-run/debian:bullseye AS final
|
||||
USER root
|
||||
WORKDIR /app
|
||||
ADD bin bin
|
||||
RUN chown -R app: /app
|
||||
# Kubernetes requires the user to be numeric
|
||||
USER 8192
|
||||
ENTRYPOINT bin/holos server
|
||||
FROM registry.k8s.io/kubectl:v1.31.0 AS kubectl
|
||||
# https://github.com/GoogleContainerTools/distroless
|
||||
FROM golang:1.23 AS build
|
||||
|
||||
WORKDIR /go/src/app
|
||||
COPY . .
|
||||
|
||||
RUN CGO_ENABLED=0 make install
|
||||
RUN CGO_ENABLED=0 go install sigs.k8s.io/kustomize/kustomize/v5
|
||||
|
||||
# Install helm to /usr/local/bin/helm
|
||||
# https://helm.sh/docs/intro/install/#from-script
|
||||
# https://holos.run/docs/v1alpha5/tutorial/setup/#dependencies
|
||||
RUN curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 \
|
||||
&& chmod 700 get_helm.sh \
|
||||
&& DESIRED_VERSION=v3.16.2 ./get_helm.sh \
|
||||
&& rm -f get_helm.sh
|
||||
|
||||
COPY --from=kubectl /bin/kubectl /usr/local/bin/
|
||||
|
||||
# distroless
|
||||
FROM gcr.io/distroless/static-debian12 AS final
|
||||
COPY --from=build \
|
||||
/go/bin/holos \
|
||||
/go/bin/kustomize \
|
||||
/usr/local/bin/kubectl \
|
||||
/usr/local/bin/helm \
|
||||
/bin/
|
||||
|
||||
# Usage: docker run -v $(pwd):/app --workdir /app --rm -it quay.io/holos-run/holos holos render platform
|
||||
CMD ["/bin/holos"]
|
||||
|
||||
129
README.md
129
README.md
@@ -1,35 +1,130 @@
|
||||
## Holos - A Holistic Development Platform
|
||||
# Holos
|
||||
|
||||
<img width="50%"
|
||||
align="right"
|
||||
style="display: block; margin: 40px auto;"
|
||||
src="https://openinfrastructure.co/blog/2016/02/27/logo/logorectangle.png">
|
||||
|
||||
Building and maintaining a software development platform is a complex and time
|
||||
consuming endeavour. Organizations often dedicate a team of 3-4 who need 6-12
|
||||
months to build the platform.
|
||||
[Holos] is a configuration management tool for Kubernetes implementing the
|
||||
[rendered manifests pattern]. It handles configurations ranging from single
|
||||
resources to multi-cluster platforms across regions.
|
||||
|
||||
Holos is a tool and a reference platform to reduce the complexity and speed up
|
||||
the process of building a modern, cloud native software development platform.
|
||||
Key components:
|
||||
- Platform schemas defining component integration
|
||||
- Building blocks unifying Helm, Kustomize and Kubernetes configs with CUE
|
||||
- BuildPlan pipeline for generating, transforming and validating manifests
|
||||
|
||||
- **Accelerate new projects** - Reduce time to market and operational complexity by starting your new project on top of the Holos reference platform.
|
||||
- **Modernize existing projects** - Incrementally incorporate your existing platform services into Holos for simpler integration.
|
||||
- **Unified configuration model** - Increase safety and reduce the risk of config changes with CUE.
|
||||
- **First class Helm and Kustomize support** - Leverage and reuse your existing investment in existing configuration tools such as Helm and Kustomize.
|
||||
- **Modern Authentication and Authorization** - Holos seamlessly integrates platform identity and access management with zero-trust beyond corp style authorization policy.
|
||||
```mermaid
|
||||
---
|
||||
title: Rendering Overview
|
||||
---
|
||||
graph LR
|
||||
Platform[<a href="https://holos.run/docs/v1alpha5/api/author/#Platform">Platform</a>]
|
||||
Component[<a href="https://holos.run/docs/v1alpha5/api/author/#ComponentConfig">Components</a>]
|
||||
|
||||
## Quick Installation
|
||||
Helm[<a href="https://holos.run/docs/v1alpha5/api/author/#Helm">Helm</a>]
|
||||
Kustomize[<a href="https://holos.run/docs/v1alpha5/api/author/#Kustomize">Kustomize</a>]
|
||||
Kubernetes[<a href="https://holos.run/docs/v1alpha5/api/author/#Kubernetes">Kubernetes</a>]
|
||||
|
||||
```console
|
||||
go install github.com/holos-run/holos/cmd/holos@latest
|
||||
BuildPlan[<a href="https://holos.run/docs/v1alpha5/api/core/#BuildPlan">BuildPlan</a>]
|
||||
|
||||
ResourcesArtifact[<a href="https://holos.run/docs/v1alpha5/api/core/#Artifact">Resources<br/>Artifact</a>]
|
||||
GitOpsArtifact[<a href="https://holos.run/docs/v1alpha5/api/core/#Artifact">GitOps<br/>Artifact</a>]
|
||||
|
||||
Generators[<a href="https://holos.run/docs/v1alpha5/api/core/#Generator">Generators</a>]
|
||||
Transformers[<a href="https://holos.run/docs/v1alpha5/api/core/#Transformer">Transformers</a>]
|
||||
Validators[<a href="https://holos.run/docs/v1alpha5/api/core/#Validator">Validators</a>]
|
||||
Files[Manifest<br/>Files]
|
||||
|
||||
Platform --> Component
|
||||
Component --> Helm --> BuildPlan
|
||||
Component --> Kubernetes --> BuildPlan
|
||||
Component --> Kustomize --> BuildPlan
|
||||
|
||||
BuildPlan --> ResourcesArtifact --> Generators
|
||||
BuildPlan --> GitOpsArtifact --> Generators
|
||||
|
||||
Generators --> Transformers --> Validators --> Files
|
||||
```
|
||||
|
||||
## Docs and Support
|
||||
## Setup
|
||||
|
||||
The documentation for developing and using Holos is available at: https://holos.run
|
||||
```shell
|
||||
brew install holos-run/tap/holos
|
||||
```
|
||||
|
||||
For discussion and support, [open a discussion](https://github.com/orgs/holos-run/discussions/new/choose).
|
||||
Refer to [setup] for other installation methods and dependencies.
|
||||
|
||||
## Example
|
||||
|
||||
See our [tutorial] for a complete hello world example.
|
||||
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
Component: #Helm & {
|
||||
Name: "podinfo"
|
||||
Chart: {
|
||||
version: "6.6.2"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
Values: ui: {
|
||||
message: string | *"Hello World" @tag(message, type=string)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Organizational Role
|
||||
|
||||
Platform engineers use Holos to generate Kubernetes manifests, both locally and
|
||||
in CI pipelines. The manifests are committed to version control and deployed via
|
||||
GitOps tools like ArgoCD or Flux.
|
||||
|
||||
Holos integrates seamlessly with existing Helm charts, Kustomize bases, and
|
||||
other version-controlled configurations.
|
||||
|
||||
## Advantages of Holos
|
||||
|
||||
### Safe
|
||||
|
||||
Holos leverages [CUE] for strong typing and validation of configuration data,
|
||||
ensuring consistent output from Helm and other tools.
|
||||
|
||||
### Consistent
|
||||
|
||||
A unified pipeline processes all configurations - whether from CUE, Helm, or
|
||||
Kustomize - through the same well-defined stages.
|
||||
|
||||
### Flexible
|
||||
|
||||
Composable building blocks for generation, transformation, validation and
|
||||
integration let teams assemble workflows that match their needs.
|
||||
|
||||
The core is intentionally unopinionated about platform configuration patterns.
|
||||
Common needs like environments and clusters are provided as customizable
|
||||
[topics] recipes rather than enforced structures.
|
||||
|
||||
## Getting Help
|
||||
|
||||
Get support through our [Discord] channel or [GitHub discussions]. Configuration
|
||||
challenges arise at all experience levels - we welcome your questions and are
|
||||
here to help.
|
||||
|
||||
## License
|
||||
|
||||
Holos is licensed under Apache 2.0 as found in the [LICENSE file](LICENSE).
|
||||
|
||||
[Holos]: https://holos.run/docs/overview/
|
||||
[rendered manifests pattern]: https://akuity.io/blog/the-rendered-manifests-pattern
|
||||
[CUE]: https://cuelang.org/
|
||||
[Discord]: https://discord.gg/JgDVbNpye7
|
||||
[GitHub discussions]: https://github.com/holos-run/holos/discussions
|
||||
[Why CUE for Configuration]: https://holos.run/blog/why-cue-for-configuration/
|
||||
[tutorial]: https://holos.run/docs/overview/
|
||||
[setup]: https://holos.run/docs/setup/
|
||||
[topics]: https://holos.run/docs/topics/
|
||||
|
||||
@@ -65,8 +65,10 @@ type ComponentConfig struct {
|
||||
|
||||
// Resources represents kubernetes resources mixed into the rendered manifest.
|
||||
Resources core.Resources
|
||||
// KustomizeConfig represents the configuration kustomize.
|
||||
// KustomizeConfig represents the kustomize configuration.
|
||||
KustomizeConfig KustomizeConfig
|
||||
// Validators represent checks that must pass for output to be written.
|
||||
Validators map[NameLabel]core.Validator
|
||||
// Artifacts represents additional artifacts to mix in. Useful for adding
|
||||
// GitOps resources. Each Artifact is unified without modification into the
|
||||
// BuildPlan.
|
||||
|
||||
@@ -40,14 +40,6 @@ type BuildPlanSpec struct {
|
||||
Disabled bool `json:"disabled,omitempty" yaml:"disabled,omitempty"`
|
||||
}
|
||||
|
||||
// BuildPlanSource reflects the origin of a [BuildPlan]. Useful to save a build
|
||||
// plan to a file, then re-generate it without needing to process a [Platform]
|
||||
// component collection.
|
||||
type BuildPlanSource struct {
|
||||
// Component reflects the component that produced the build plan.
|
||||
Component Component `json:"component,omitempty" yaml:"component,omitempty"`
|
||||
}
|
||||
|
||||
// Artifact represents one fully rendered manifest produced by a [Transformer]
|
||||
// sequence, which transforms a [Generator] collection. A [BuildPlan] produces
|
||||
// an [Artifact] collection.
|
||||
@@ -72,6 +64,7 @@ type Artifact struct {
|
||||
Artifact FilePath `json:"artifact,omitempty" yaml:"artifact,omitempty"`
|
||||
Generators []Generator `json:"generators,omitempty" yaml:"generators,omitempty"`
|
||||
Transformers []Transformer `json:"transformers,omitempty" yaml:"transformers,omitempty"`
|
||||
Validators []Validator `json:"validators,omitempty" yaml:"validators,omitempty"`
|
||||
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
|
||||
}
|
||||
|
||||
@@ -153,9 +146,26 @@ type Chart struct {
|
||||
}
|
||||
|
||||
// Repository represents a [Helm] [Chart] repository.
|
||||
//
|
||||
// The Auth field is useful to configure http basic authentication to the Helm
|
||||
// repository. Holos gets the username and password from the environment
|
||||
// variables represented by the Auth field.
|
||||
type Repository struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
URL string `json:"url" yaml:"url"`
|
||||
Auth Auth `json:"auth,omitempty" yaml:"auth,omitempty"`
|
||||
}
|
||||
|
||||
// Auth represents environment variable names containing auth credentials.
|
||||
type Auth struct {
|
||||
Username AuthSource `json:"username" yaml:"username"`
|
||||
Password AuthSource `json:"password" yaml:"password"`
|
||||
}
|
||||
|
||||
// AuthSource represents a source for the value of an [Auth] field.
|
||||
type AuthSource struct {
|
||||
Value string `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
FromEnv string `json:"fromEnv,omitempty" yaml:"fromEnv,omitempty"`
|
||||
}
|
||||
|
||||
// Transformer combines multiple inputs from prior [Generator] or [Transformer]
|
||||
@@ -206,15 +216,37 @@ type Kustomize struct {
|
||||
// is expected to happen in CUE against the kubectl version the user prefers.
|
||||
type Kustomization map[string]any
|
||||
|
||||
// FileContent represents file contents.
|
||||
type FileContent string
|
||||
|
||||
// FileContentMap represents a mapping of file paths to file contents.
|
||||
type FileContentMap map[FilePath]FileContent
|
||||
|
||||
// FilePath represents a file path.
|
||||
type FilePath string
|
||||
|
||||
// FileContent represents file contents.
|
||||
type FileContent string
|
||||
|
||||
// Validator validates files. Useful to validate an [Artifact] prior to writing
|
||||
// it out to the final destination. Holos may execute validators concurrently.
|
||||
// See the [validators] tutorial for an end to end example.
|
||||
//
|
||||
// [validators]: https://holos.run/docs/v1alpha5/tutorial/validators/
|
||||
type Validator struct {
|
||||
// Kind represents the kind of transformer. Must be Kustomize, or Join.
|
||||
Kind string `json:"kind" yaml:"kind" cue:"\"Command\""`
|
||||
// Inputs represents the files to validate. Usually the final Artifact.
|
||||
Inputs []FilePath `json:"inputs" yaml:"inputs"`
|
||||
// Command represents a validation command. Ignored unless kind is Command.
|
||||
Command Command `json:"command,omitempty" yaml:"command,omitempty"`
|
||||
}
|
||||
|
||||
// Command represents a command vetting one or more artifacts. Holos appends
|
||||
// fully qualified input file paths to the end of the args list, then executes
|
||||
// the command. Inputs are written into a temporary directory prior to
|
||||
// executing the command and removed afterwards.
|
||||
type Command struct {
|
||||
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
|
||||
}
|
||||
|
||||
// InternalLabel is an arbitrary unique identifier internal to holos itself.
|
||||
// The holos cli is expected to never write a InternalLabel value to rendered
|
||||
// output files, therefore use a InternalLabel when the identifier must be
|
||||
@@ -231,7 +263,7 @@ type Metadata struct {
|
||||
// Labels represents a resource selector.
|
||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
// Annotations represents arbitrary non-identifying metadata. For example
|
||||
// holos uses the `cli.holos.run/description` annotation to log resources in a
|
||||
// holos uses the `app.holos.run/description` annotation to log resources in a
|
||||
// user customized way.
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
}
|
||||
@@ -271,6 +303,10 @@ type Component struct {
|
||||
// Path represents the path of the component relative to the platform root.
|
||||
// Injected as the tag variable "holos_component_path".
|
||||
Path string `json:"path" yaml:"path"`
|
||||
// Instances represents additional cue instance paths to unify with Path.
|
||||
// Useful to unify data files into a component BuildPlan. Added in holos
|
||||
// 0.101.7.
|
||||
Instances []Instance `json:"instances,omitempty" yaml:"instances,omitempty"`
|
||||
// WriteTo represents the holos render component --write-to flag. If empty,
|
||||
// the default value for the --write-to flag is used.
|
||||
WriteTo string `json:"writeTo,omitempty" yaml:"writeTo,omitempty"`
|
||||
@@ -284,6 +320,30 @@ type Component struct {
|
||||
// resulting BuildPlan.
|
||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
// Annotations represents arbitrary non-identifying metadata. Use the
|
||||
// `cli.holos.run/description` to customize the log message of each BuildPlan.
|
||||
// `app.holos.run/description` to customize the log message of each BuildPlan.
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// Instance represents a data instance to unify with the configuration.
|
||||
//
|
||||
// Useful to unify json and yaml files with cue configuration files for
|
||||
// integration with other tools. For example, executing holos render platform
|
||||
// from a pull request workflow after [Kargo] executes the [yaml update] and
|
||||
// [git wait for pr] promotion steps.
|
||||
//
|
||||
// [Kargo]: https://docs.kargo.io/
|
||||
// [yaml update]: https://docs.kargo.io/references/promotion-steps#yaml-update
|
||||
// [git wait for pr]: https://docs.kargo.io/references/promotion-steps#git-wait-for-pr
|
||||
type Instance struct {
|
||||
// Kind is a discriminator.
|
||||
Kind string `json:"kind" yaml:"kind" cue:"\"ExtractYAML\""`
|
||||
// Ignored unless kind is ExtractYAML.
|
||||
ExtractYAML ExtractYAML `json:"extractYAML,omitempty" yaml:"extractYAML,omitempty"`
|
||||
}
|
||||
|
||||
// ExtractYAML represents a cue data instance encoded as yaml or json. If Path
|
||||
// refers to a directory all files in the directory are extracted
|
||||
// non-recursively. Otherwise, path must refer to a file.
|
||||
type ExtractYAML struct {
|
||||
Path string `json:"path" yaml:"path"`
|
||||
}
|
||||
|
||||
63
cmd/cmd.go
Normal file
63
cmd/cmd.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"runtime/trace"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
)
|
||||
|
||||
// MakeMain makes a main function for the cli or tests.
|
||||
func MakeMain(options ...holos.Option) func() int {
|
||||
return func() (exitCode int) {
|
||||
cfg := holos.New(options...)
|
||||
slog.SetDefault(cfg.Logger())
|
||||
ctx := context.Background()
|
||||
|
||||
if format := os.Getenv("HOLOS_CPU_PROFILE"); format != "" {
|
||||
f, _ := os.Create(fmt.Sprintf(format, os.Getppid(), os.Getpid()))
|
||||
err := pprof.StartCPUProfile(f)
|
||||
defer func() {
|
||||
pprof.StopCPUProfile()
|
||||
f.Close()
|
||||
}()
|
||||
if err != nil {
|
||||
return cli.HandleError(ctx, err, cfg)
|
||||
}
|
||||
}
|
||||
defer memProfile(ctx, cfg)
|
||||
|
||||
if format := os.Getenv("HOLOS_TRACE"); format != "" {
|
||||
f, _ := os.Create(fmt.Sprintf(format, os.Getppid(), os.Getpid()))
|
||||
err := trace.Start(f)
|
||||
defer func() {
|
||||
trace.Stop()
|
||||
f.Close()
|
||||
}()
|
||||
if err != nil {
|
||||
return cli.HandleError(ctx, err, cfg)
|
||||
}
|
||||
}
|
||||
|
||||
feature := &holos.EnvFlagger{}
|
||||
if err := cli.New(cfg, feature).ExecuteContext(ctx); err != nil {
|
||||
return cli.HandleError(ctx, err, cfg)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func memProfile(ctx context.Context, cfg *holos.Config) {
|
||||
if format := os.Getenv("HOLOS_MEM_PROFILE"); format != "" {
|
||||
f, _ := os.Create(fmt.Sprintf(format, os.Getppid(), os.Getpid()))
|
||||
defer f.Close()
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
_ = cli.HandleError(ctx, err, cfg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,9 @@ package main
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli"
|
||||
"github.com/holos-run/holos/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
os.Exit(cli.MakeMain()())
|
||||
os.Exit(cmd.MakeMain()())
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ import (
|
||||
"testing"
|
||||
|
||||
cue "cuelang.org/go/cmd/cue/cmd"
|
||||
"github.com/holos-run/holos/internal/cli"
|
||||
"github.com/holos-run/holos/cmd"
|
||||
"github.com/rogpeppe/go-internal/testscript"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(testscript.RunMain(m, map[string]func() int{
|
||||
"holos": cli.MakeMain(),
|
||||
"holos": cmd.MakeMain(),
|
||||
"cue": cue.Main,
|
||||
}))
|
||||
}
|
||||
|
||||
12
cmd/holos/tests/cli/cue-vet.txt
Normal file
12
cmd/holos/tests/cli/cue-vet.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
# https://github.com/holos-run/holos/issues/358
|
||||
# holos cue vet should fail verifications with exit code 1
|
||||
! exec holos cue vet ./policy --path strings.ToLower(kind) ./data/secret.yaml
|
||||
# holos cue vet should report validation errors to stderr
|
||||
stderr 'Forbidden. Use an ExternalSecret instead.'
|
||||
|
||||
-- data/secret.yaml --
|
||||
kind: Secret
|
||||
-- policy/validators.cue --
|
||||
package policy
|
||||
|
||||
secret: kind: "Forbidden. Use an ExternalSecret instead."
|
||||
@@ -7,11 +7,11 @@ cd $WORK
|
||||
exec holos generate platform v1alpha5 --force
|
||||
|
||||
# Platforms are empty by default.
|
||||
exec holos render platform ./platform
|
||||
exec holos render platform
|
||||
stderr -count=1 '^rendered platform'
|
||||
|
||||
# Holos uses CUE to build a platform specification.
|
||||
exec cue export --expression holos --out=yaml ./platform
|
||||
exec holos show platform
|
||||
cmp stdout want/1.platform_spec.yaml
|
||||
|
||||
# Define the host and port in projects/blackbox.schema.cue
|
||||
@@ -22,7 +22,7 @@ mv projects/platform/components/prometheus/prometheus.cue.disabled projects/plat
|
||||
mv platform/prometheus.cue.disabled platform/prometheus.cue
|
||||
|
||||
# Render the platform to render the prometheus chart.
|
||||
exec holos render platform ./platform
|
||||
exec holos render platform
|
||||
stderr -count=1 '^rendered prometheus'
|
||||
stderr -count=1 '^rendered platform'
|
||||
cmp deploy/components/prometheus/prometheus.gen.yaml want/1.prometheus.gen.yaml
|
||||
@@ -73,8 +73,8 @@ core.#BuildPlan & {
|
||||
metadata: name: _Tags.component.name
|
||||
}
|
||||
-- want/1.platform_spec.yaml --
|
||||
kind: Platform
|
||||
apiVersion: v1alpha5
|
||||
kind: Platform
|
||||
metadata:
|
||||
name: default
|
||||
spec:
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
# https://github.com/holos-run/holos/issues/332
|
||||
env HOME=$WORK
|
||||
# Mock with a stub helm command
|
||||
env PATH=$WORK/bin:$PATH
|
||||
chmod 755 bin/helm
|
||||
# Initialize the platform
|
||||
exec holos init platform v1alpha5 --force
|
||||
# when helm update returns an error
|
||||
! exec holos render platform
|
||||
# holos should log the helm error to stderr
|
||||
stderr 'Error: chart "podinfo" matching 0.0.0 not found in podinfo index'
|
||||
-- bin/helm --
|
||||
#! /bin/bash
|
||||
echo 'Error: chart "podinfo" matching 0.0.0 not found in podinfo index' >&2
|
||||
exit 2
|
||||
-- platform/podinfo.cue --
|
||||
package holos
|
||||
|
||||
Platform: Components: podinfo: {
|
||||
name: "podinfo"
|
||||
path: "components/podinfo"
|
||||
}
|
||||
-- components/podinfo/podinfo.cue --
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: HelmChart.BuildPlan
|
||||
|
||||
HelmChart: #Helm & {
|
||||
Name: "podinfo"
|
||||
Chart: {
|
||||
version: "0.0.0"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,9 +106,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
---
|
||||
@@ -135,9 +132,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
---
|
||||
@@ -164,9 +158,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
---
|
||||
@@ -193,9 +184,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
-- want/buildplans.1.yaml --
|
||||
@@ -222,9 +210,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
-- want/buildplans.2.yaml --
|
||||
@@ -251,9 +236,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
-- want/buildplans.3.yaml --
|
||||
@@ -280,9 +262,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
---
|
||||
@@ -309,9 +288,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
---
|
||||
@@ -338,9 +314,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
-- want/buildplans.4.yaml --
|
||||
@@ -367,9 +340,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
---
|
||||
@@ -396,9 +366,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
---
|
||||
@@ -425,9 +392,6 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
---
|
||||
@@ -454,8 +418,5 @@ spec:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# https://github.com/holos-run/holos/issues/348
|
||||
# when the optional kustomize patch name field is omitted
|
||||
exec holos init platform v1alpha5 --force
|
||||
# want a buildplan shown
|
||||
exec holos show buildplans
|
||||
cmp stdout buildplan.yaml
|
||||
# want this error to go away
|
||||
! stderr 'cannot convert non-concrete value string'
|
||||
-- platform/example.cue --
|
||||
package holos
|
||||
|
||||
Platform: Components: example: {
|
||||
name: "example"
|
||||
path: "components/example"
|
||||
}
|
||||
-- components/example/example.cue --
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
Component: #Kustomize & {
|
||||
KustomizeConfig: Kustomization: patches: [
|
||||
{
|
||||
target: kind: "CustomResourceDefinition"
|
||||
patch: yaml.Marshal([{
|
||||
op: "add"
|
||||
path: "/metadata/annotations/example"
|
||||
value: "example-value"
|
||||
}])
|
||||
},
|
||||
]
|
||||
}
|
||||
-- buildplan.yaml --
|
||||
kind: BuildPlan
|
||||
apiVersion: v1alpha5
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
artifacts:
|
||||
- artifact: components/example/example.gen.yaml
|
||||
generators:
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
transformers:
|
||||
- kind: Kustomize
|
||||
inputs:
|
||||
- resources.gen.yaml
|
||||
output: components/example/example.gen.yaml
|
||||
kustomize:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
patches:
|
||||
- patch: |
|
||||
- op: add
|
||||
path: /metadata/annotations/example
|
||||
value: example-value
|
||||
target:
|
||||
kind: CustomResourceDefinition
|
||||
name: ""
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
50
cmd/holos/tests/v1alpha5/issues/issue366-cue-build-tags.txt
Normal file
50
cmd/holos/tests/v1alpha5/issues/issue366-cue-build-tags.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
# https://github.com/holos-run/holos/issues/366
|
||||
# Build tags conditionally include CUE files.
|
||||
env HOME=$WORK
|
||||
|
||||
exec holos init platform v1alpha5 --force
|
||||
exec holos show platform
|
||||
cmp stdout want/empty.yaml
|
||||
|
||||
exec holos show platform -t foo
|
||||
cmp stdout want/foo.yaml
|
||||
|
||||
-- platform/empty.cue --
|
||||
@if(foo)
|
||||
package holos
|
||||
|
||||
Platform: Components: foo: _
|
||||
-- platform/metadata.cue --
|
||||
package holos
|
||||
|
||||
Platform: Components: [NAME=string]: {
|
||||
name: NAME
|
||||
path: "components/empty"
|
||||
labels: "app.holos.run/name": NAME
|
||||
annotations: "app.holos.run/description": "\(NAME) empty test case"
|
||||
}
|
||||
-- components/empty/empty.cue --
|
||||
package holos
|
||||
|
||||
Component: #Kubernetes & {}
|
||||
holos: Component.BuildPlan
|
||||
-- want/empty.yaml --
|
||||
apiVersion: v1alpha5
|
||||
kind: Platform
|
||||
metadata:
|
||||
name: default
|
||||
spec:
|
||||
components: []
|
||||
-- want/foo.yaml --
|
||||
apiVersion: v1alpha5
|
||||
kind: Platform
|
||||
metadata:
|
||||
name: default
|
||||
spec:
|
||||
components:
|
||||
- annotations:
|
||||
app.holos.run/description: foo empty test case
|
||||
labels:
|
||||
app.holos.run/name: foo
|
||||
name: foo
|
||||
path: components/empty
|
||||
@@ -31,6 +31,7 @@ spec:
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
resources: {}
|
||||
validators: []
|
||||
transformers:
|
||||
- kind: Kustomize
|
||||
inputs:
|
||||
@@ -38,9 +39,6 @@ spec:
|
||||
output: components/no-name/no-name.gen.yaml
|
||||
kustomize:
|
||||
kustomization:
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- resources.gen.yaml
|
||||
kind: Kustomization
|
||||
|
||||
37
cmd/holos/tests/v1alpha5/schemas/validators.txt
Normal file
37
cmd/holos/tests/v1alpha5/schemas/validators.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
# https://github.com/holos-run/holos/issues/357
|
||||
exec holos init platform v1alpha5 --force
|
||||
! exec holos render platform
|
||||
stderr 'secret.kind: conflicting values "Forbidden. Use an ExternalSecret instead." and "Secret"'
|
||||
|
||||
-- validators.cue --
|
||||
package holos
|
||||
|
||||
import "github.com/holos-run/holos/api/author/v1alpha5:author"
|
||||
|
||||
#ComponentConfig: author.#ComponentConfig & {
|
||||
Validators: cue: {
|
||||
kind: "Command"
|
||||
command: args: ["holos", "cue", "vet", "./policy", "--path", "strings.ToLower(kind)"]
|
||||
}
|
||||
}
|
||||
-- policy/validations.cue --
|
||||
package validations
|
||||
|
||||
secret: kind: "Forbidden. Use an ExternalSecret instead."
|
||||
-- platform/example.cue --
|
||||
package holos
|
||||
|
||||
Platform: Components: example: {
|
||||
name: "example"
|
||||
path: "components/example"
|
||||
}
|
||||
-- components/example/secret.cue --
|
||||
package holos
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
Component: #Kubernetes & {
|
||||
Resources: Secret: test: {
|
||||
metadata: name: "test"
|
||||
}
|
||||
}
|
||||
7
doc/md/_markdown-tests/examples/01-holos-version.txt
Normal file
7
doc/md/_markdown-tests/examples/01-holos-version.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
exec bash -c 'bash -euo pipefail $WORK/command.sh 2>&1'
|
||||
cmp stdout $WORK/output.txt
|
||||
|
||||
-- command.sh --
|
||||
holos --version
|
||||
-- output.txt --
|
||||
0.102.5
|
||||
357
doc/md/_markdown-tests/examples/02-helm-values.txt
Normal file
357
doc/md/_markdown-tests/examples/02-helm-values.txt
Normal file
@@ -0,0 +1,357 @@
|
||||
# Set $HOME because:
|
||||
# - Helm uses it for temporary files
|
||||
# - Git requires it for setting author name/email globally
|
||||
env HOME=$WORK/.tmp
|
||||
chmod 0755 $WORK/update.sh
|
||||
|
||||
# Configure git author for testscript execution
|
||||
exec git config --global user.name 'Holos Docs'
|
||||
exec git config --global user.email 'hello@holos.run'
|
||||
exec git config --global init.defaultBranch main
|
||||
|
||||
# Remove the tutorial directory if it already exists
|
||||
exec rm -rf holos-helm-values-tutorial
|
||||
|
||||
# Create and change to the tutorial directory, and then initialize the Holos platform
|
||||
exec bash -c 'bash -euo pipefail mkdir.and.init.sh'
|
||||
cd holos-helm-values-tutorial
|
||||
|
||||
# Git init and create the component directories
|
||||
exec bash -c 'bash -euo pipefail $WORK/git.init.sh'
|
||||
exec bash -c 'bash -euo pipefail $WORK/mkdir.components.sh'
|
||||
|
||||
# Combine and execute the multiline prometheus/blackbox component header/body/trailer files
|
||||
exec cat $WORK/prometheus.component.header.sh ../prometheus.component.body.cue ../eof.trailer.sh
|
||||
stdin stdout
|
||||
exec bash -xeuo pipefail
|
||||
exec cat $WORK/blackbox.component.header.sh ../blackbox.component.body.cue ../eof.trailer.sh
|
||||
stdin stdout
|
||||
exec bash -xeuo pipefail
|
||||
|
||||
# Combine and execute the multiline platform registration header/body/trailer files.
|
||||
exec cat $WORK/register.components.header.sh ../register.components.body.cue ../eof.trailer.sh
|
||||
stdin stdout
|
||||
exec bash -xeuo pipefail
|
||||
|
||||
# Render the platform, capture stdout, and use update.sh to gate whether the
|
||||
# output file should be updated.
|
||||
#
|
||||
# NOTE: The [net] condition will test whether external network access is available
|
||||
[net] exec bash -c 'bash -euo pipefail $WORK/render.sh 2>&1'
|
||||
[net] stdin stdout
|
||||
exec $WORK/update.sh $WORK/register.components.output.txt
|
||||
|
||||
# Commit and conditionally update the output file
|
||||
exec bash -c 'bash -euo pipefail $WORK/register.components.git.commit.sh'
|
||||
stdin stdout
|
||||
exec $WORK/update.sh $WORK/register.components.git.commit.output.txt
|
||||
|
||||
# Import values
|
||||
exec bash -c 'bash -euo pipefail $WORK/import.prometheus.values.sh'
|
||||
exec bash -c 'bash -euo pipefail $WORK/import.blackbox.values.sh'
|
||||
|
||||
# Render, update the output file, commit, and update the commit output file.
|
||||
[net] exec bash -c 'bash -euo pipefail $WORK/render.sh 2>&1'
|
||||
[net] stdin stdout
|
||||
exec $WORK/update.sh $WORK/import.values.render.output.txt
|
||||
exec bash -c 'bash -euo pipefail $WORK/import.values.git.commit.sh'
|
||||
stdin stdout
|
||||
exec $WORK/update.sh $WORK/import.values.git.output.txt
|
||||
|
||||
# Combine and execute the common configuration header/body/trailer to write the cue file.
|
||||
exec cat $WORK/blackbox.common.config.header.sh ../blackbox.common.config.body.cue ../eof.trailer.sh
|
||||
stdin stdout
|
||||
exec bash -xeuo pipefail
|
||||
|
||||
# Git commit blackbox common config
|
||||
exec bash -c 'bash -euo pipefail $WORK/blackbox.common.config.git.commit.sh'
|
||||
stdin stdout
|
||||
exec $WORK/update.sh $WORK/blackbox.common.config.git.output.txt
|
||||
|
||||
# Patch the common config values file and write to output file.
|
||||
#
|
||||
# NOTE: Using a symlink here because the patch script references values.patch
|
||||
# within the same directory, but it actually lives one directory up in the
|
||||
# testscript $WORK dir.
|
||||
exec ln -s $WORK/values.patch values.patch
|
||||
exec bash -c 'bash -euo pipefail $WORK/common.config.patch.sh'
|
||||
stdin stdout
|
||||
exec $WORK/update.sh $WORK/common.config.patch.txt
|
||||
|
||||
# Remove patch and commit changes
|
||||
exec bash -c 'bash -euo pipefail $WORK/common.config.rm.sh'
|
||||
exec bash -c 'bash -euo pipefail $WORK/common.config.git.sh'
|
||||
stdin stdout
|
||||
exec $WORK/update.sh $WORK/common.config.git.output.txt
|
||||
|
||||
# Final render and update of output file.
|
||||
[net] exec bash -c 'bash -euo pipefail $WORK/render.sh 2>&1'
|
||||
[net] stdin stdout
|
||||
exec $WORK/update.sh $WORK/reviewing.changes.git.output.txt
|
||||
|
||||
# Git diff and write to output file.
|
||||
exec bash -c 'bash -euo pipefail $WORK/git.diff.sh'
|
||||
stdin stdout
|
||||
exec $WORK/update.sh $WORK/git.diff
|
||||
|
||||
# Final commit and write to output file
|
||||
exec bash -c 'bash -euo pipefail $WORK/reviewing.changes.git.commit.sh'
|
||||
stdin stdout
|
||||
exec $WORK/update.sh $WORK/reviewing.changes.git.output.txt
|
||||
|
||||
# Clean up the tutorial directory and tmp $HOME directory
|
||||
cd $WORK
|
||||
exec rm -rf holos-helm-values-tutorial
|
||||
exec rm -rf $HOME
|
||||
|
||||
-- update.sh --
|
||||
#! /bin/bash
|
||||
set -euo pipefail
|
||||
[[ -s "$1" ]] && [[ -z "${HOLOS_UPDATE_SCRIPTS:-}" ]] && exit 0
|
||||
cat > "$1"
|
||||
-- mkdir.and.init.sh --
|
||||
mkdir holos-helm-values-tutorial
|
||||
cd holos-helm-values-tutorial
|
||||
holos init platform v1alpha5
|
||||
-- git.init.sh --
|
||||
git init . && git add . && git commit -m "initial commit"
|
||||
-- mkdir.components.sh --
|
||||
mkdir -p components/prometheus components/blackbox
|
||||
-- prometheus.component.header.sh --
|
||||
cat <<EOF > components/prometheus/prometheus.cue
|
||||
-- prometheus.component.body.cue --
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: Helm.BuildPlan
|
||||
|
||||
Helm: #Helm & {
|
||||
Chart: {
|
||||
name: "prometheus"
|
||||
version: "25.27.0"
|
||||
repository: {
|
||||
name: "prometheus-community"
|
||||
url: "https://prometheus-community.github.io/helm-charts"
|
||||
}
|
||||
}
|
||||
}
|
||||
-- eof.trailer.sh --
|
||||
EOF
|
||||
-- blackbox.component.header.sh --
|
||||
cat <<EOF > components/blackbox/blackbox.cue
|
||||
-- blackbox.component.body.cue --
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: Helm.BuildPlan
|
||||
|
||||
Helm: #Helm & {
|
||||
Chart: {
|
||||
name: "prometheus-blackbox-exporter"
|
||||
version: "9.0.1"
|
||||
repository: {
|
||||
name: "prometheus-community"
|
||||
url: "https://prometheus-community.github.io/helm-charts"
|
||||
}
|
||||
}
|
||||
}
|
||||
-- register.components.header.sh --
|
||||
cat <<EOF > platform/prometheus.cue
|
||||
-- register.components.body.cue --
|
||||
package holos
|
||||
|
||||
Platform: Components: {
|
||||
prometheus: {
|
||||
name: "prometheus"
|
||||
path: "components/prometheus"
|
||||
}
|
||||
blackbox: {
|
||||
name: "blackbox"
|
||||
path: "components/blackbox"
|
||||
}
|
||||
}
|
||||
-- render.sh --
|
||||
holos render platform
|
||||
-- register.components.output.txt --
|
||||
cached prometheus-blackbox-exporter 9.0.1
|
||||
rendered blackbox in 3.825430417s
|
||||
cached prometheus 25.27.0
|
||||
rendered prometheus in 4.840089667s
|
||||
rendered platform in 4.840137792s
|
||||
-- register.components.git.commit.sh --
|
||||
git add . && git commit -m 'add blackbox and prometheus'
|
||||
-- register.components.git.commit.output.txt --
|
||||
[main b5df111] add blackbox and prometheus
|
||||
5 files changed, 1550 insertions(+)
|
||||
create mode 100644 components/blackbox/blackbox.cue
|
||||
create mode 100644 components/prometheus/prometheus.cue
|
||||
create mode 100644 deploy/components/blackbox/blackbox.gen.yaml
|
||||
create mode 100644 deploy/components/prometheus/prometheus.gen.yaml
|
||||
create mode 100644 platform/prometheus.cue
|
||||
-- import.prometheus.values.sh --
|
||||
holos cue import \
|
||||
--package holos \
|
||||
--path 'Helm: Values:' \
|
||||
--outfile components/prometheus/values.cue \
|
||||
components/prometheus/vendor/25.27.0/prometheus/values.yaml
|
||||
-- import.blackbox.values.sh --
|
||||
holos cue import \
|
||||
--package holos \
|
||||
--path 'Helm: Values:' \
|
||||
--outfile components/blackbox/values.cue \
|
||||
components/blackbox/vendor/9.0.1/prometheus-blackbox-exporter/values.yaml
|
||||
-- import.values.render.output.txt --
|
||||
rendered blackbox in 365.936792ms
|
||||
rendered prometheus in 371.855875ms
|
||||
rendered platform in 372.109916ms
|
||||
-- import.values.git.commit.sh --
|
||||
git add . && git commit -m 'import values'
|
||||
-- import.values.git.output.txt --
|
||||
[main 52e90ea] import values
|
||||
2 files changed, 1815 insertions(+)
|
||||
create mode 100644 components/blackbox/values.cue
|
||||
create mode 100644 components/prometheus/values.cue
|
||||
-- blackbox.common.config.header.sh --
|
||||
cat <<EOF > components/blackbox.cue
|
||||
-- blackbox.common.config.body.cue --
|
||||
package holos
|
||||
|
||||
// Schema Definition
|
||||
#Blackbox: {
|
||||
// host constrained to a lower case dns label
|
||||
host: string & =~"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"
|
||||
// port constrained to a valid range
|
||||
port: int & >0 & <=65535
|
||||
}
|
||||
|
||||
// Concrete values must validate against the schema.
|
||||
Blackbox: #Blackbox & {
|
||||
host: "blackbox"
|
||||
port: 9115
|
||||
}
|
||||
-- blackbox.common.config.git.commit.sh --
|
||||
git add . && git commit -m 'add blackbox configuration'
|
||||
-- blackbox.common.config.git.output.txt --
|
||||
[main 1adcd08] add blackbox configuration
|
||||
1 file changed, 15 insertions(+)
|
||||
create mode 100644 components/blackbox.cue
|
||||
-- common.config.patch.sh --
|
||||
patch -p1 < values.patch
|
||||
-- values.patch --
|
||||
--- a/components/blackbox/values.cue
|
||||
+++ b/components/blackbox/values.cue
|
||||
@@ -1,6 +1,8 @@
|
||||
package holos
|
||||
|
||||
Helm: Values: {
|
||||
+ fullnameOverride: Blackbox.host
|
||||
+
|
||||
global: {
|
||||
//# Global image registry to use if it needs to be overriden for some specific use cases (e.g local registries, custom images, ...)
|
||||
//#
|
||||
@@ -192,7 +194,7 @@ Helm: Values: {
|
||||
annotations: {}
|
||||
labels: {}
|
||||
type: "ClusterIP"
|
||||
- port: 9115
|
||||
+ port: Blackbox.port
|
||||
ipDualStack: {
|
||||
enabled: false
|
||||
ipFamilies: ["IPv6", "IPv4"]
|
||||
--- a/components/prometheus/values.cue
|
||||
+++ b/components/prometheus/values.cue
|
||||
@@ -1083,7 +1083,7 @@ Helm: Values: {
|
||||
target_label: "__param_target"
|
||||
}, {
|
||||
target_label: "__address__"
|
||||
- replacement: "blackbox"
|
||||
+ replacement: "\(Blackbox.host):\(Blackbox.port)"
|
||||
}, {
|
||||
source_labels: ["__param_target"]
|
||||
target_label: "instance"
|
||||
-- common.config.patch.txt --
|
||||
patching file 'components/blackbox/values.cue'
|
||||
patching file 'components/prometheus/values.cue'
|
||||
-- common.config.rm.sh --
|
||||
rm values.patch
|
||||
-- common.config.git.sh --
|
||||
git add . && git commit -m 'integrate blackbox and prometheus together'
|
||||
-- common.config.git.output.txt --
|
||||
[main 4221803] integrate blackbox and prometheus together
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
-- reviewing.changes.render.output.txt --
|
||||
rendered blackbox in 374.810666ms
|
||||
rendered prometheus in 382.899334ms
|
||||
rendered platform in 383.270625ms
|
||||
-- git.diff.sh --
|
||||
git diff
|
||||
-- git.diff --
|
||||
diff --git a/deploy/components/blackbox/blackbox.gen.yaml b/deploy/components/blackbox/blackbox.gen.yaml
|
||||
index 3db20cd..5336f44 100644
|
||||
--- a/deploy/components/blackbox/blackbox.gen.yaml
|
||||
+++ b/deploy/components/blackbox/blackbox.gen.yaml
|
||||
@@ -7,7 +7,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -31,7 +31,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -43,7 +43,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
spec:
|
||||
ports:
|
||||
@@ -65,7 +65,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
@@ -119,8 +119,8 @@ spec:
|
||||
name: config
|
||||
hostNetwork: false
|
||||
restartPolicy: Always
|
||||
- serviceAccountName: prometheus-blackbox-exporter
|
||||
+ serviceAccountName: blackbox
|
||||
volumes:
|
||||
- configMap:
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
name: config
|
||||
diff --git a/deploy/components/prometheus/prometheus.gen.yaml b/deploy/components/prometheus/prometheus.gen.yaml
|
||||
index 9e02bce..ab638f0 100644
|
||||
--- a/deploy/components/prometheus/prometheus.gen.yaml
|
||||
+++ b/deploy/components/prometheus/prometheus.gen.yaml
|
||||
@@ -589,7 +589,7 @@ data:
|
||||
- source_labels:
|
||||
- __address__
|
||||
target_label: __param_target
|
||||
- - replacement: blackbox
|
||||
+ - replacement: blackbox:9115
|
||||
target_label: __address__
|
||||
- source_labels:
|
||||
- __param_target
|
||||
-- reviewing.changes.git.commit.sh --
|
||||
git add . && git commit -m 'render integrated blackbox and prometheus manifests'
|
||||
-- reviewing.changes.git.output.txt --
|
||||
[main 67efe0d] render integrated blackbox and prometheus manifests
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
@@ -0,0 +1 @@
|
||||
holos --version
|
||||
@@ -0,0 +1 @@
|
||||
0.102.4
|
||||
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
// Schema Definition
|
||||
#Blackbox: {
|
||||
// host constrained to a lower case dns label
|
||||
host: string & =~"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"
|
||||
// port constrained to a valid range
|
||||
port: int & >0 & <=65535
|
||||
}
|
||||
|
||||
// Concrete values must validate against the schema.
|
||||
Blackbox: #Blackbox & {
|
||||
host: "blackbox"
|
||||
port: 9115
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
git add . && git commit -m 'add blackbox configuration'
|
||||
@@ -0,0 +1,3 @@
|
||||
[main ffea4dd] add blackbox configuration
|
||||
1 file changed, 15 insertions(+)
|
||||
create mode 100644 components/blackbox.cue
|
||||
@@ -0,0 +1 @@
|
||||
cat <<EOF > components/blackbox.cue
|
||||
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: Helm.BuildPlan
|
||||
|
||||
Helm: #Helm & {
|
||||
Chart: {
|
||||
name: "prometheus-blackbox-exporter"
|
||||
version: "9.0.1"
|
||||
repository: {
|
||||
name: "prometheus-community"
|
||||
url: "https://prometheus-community.github.io/helm-charts"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
cat <<EOF > components/blackbox/blackbox.cue
|
||||
@@ -0,0 +1,2 @@
|
||||
[main a4bc817] integrate blackbox and prometheus together
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
@@ -0,0 +1 @@
|
||||
git add . && git commit -m 'integrate blackbox and prometheus together'
|
||||
@@ -0,0 +1 @@
|
||||
patch -p1 < values.patch
|
||||
@@ -0,0 +1,2 @@
|
||||
patching file 'components/blackbox/values.cue'
|
||||
patching file 'components/prometheus/values.cue'
|
||||
@@ -0,0 +1 @@
|
||||
rm values.patch
|
||||
@@ -0,0 +1 @@
|
||||
EOF
|
||||
64
doc/md/_markdown-tests/script-02-helm-values/git.diff
Normal file
64
doc/md/_markdown-tests/script-02-helm-values/git.diff
Normal file
@@ -0,0 +1,64 @@
|
||||
diff --git a/deploy/components/blackbox/blackbox.gen.yaml b/deploy/components/blackbox/blackbox.gen.yaml
|
||||
index 3db20cd..5336f44 100644
|
||||
--- a/deploy/components/blackbox/blackbox.gen.yaml
|
||||
+++ b/deploy/components/blackbox/blackbox.gen.yaml
|
||||
@@ -7,7 +7,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -31,7 +31,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -43,7 +43,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
spec:
|
||||
ports:
|
||||
@@ -65,7 +65,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
@@ -119,8 +119,8 @@ spec:
|
||||
name: config
|
||||
hostNetwork: false
|
||||
restartPolicy: Always
|
||||
- serviceAccountName: prometheus-blackbox-exporter
|
||||
+ serviceAccountName: blackbox
|
||||
volumes:
|
||||
- configMap:
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
name: config
|
||||
diff --git a/deploy/components/prometheus/prometheus.gen.yaml b/deploy/components/prometheus/prometheus.gen.yaml
|
||||
index 9e02bce..ab638f0 100644
|
||||
--- a/deploy/components/prometheus/prometheus.gen.yaml
|
||||
+++ b/deploy/components/prometheus/prometheus.gen.yaml
|
||||
@@ -589,7 +589,7 @@ data:
|
||||
- source_labels:
|
||||
- __address__
|
||||
target_label: __param_target
|
||||
- - replacement: blackbox
|
||||
+ - replacement: blackbox:9115
|
||||
target_label: __address__
|
||||
- source_labels:
|
||||
- __param_target
|
||||
1
doc/md/_markdown-tests/script-02-helm-values/git.diff.sh
Normal file
1
doc/md/_markdown-tests/script-02-helm-values/git.diff.sh
Normal file
@@ -0,0 +1 @@
|
||||
git diff
|
||||
1
doc/md/_markdown-tests/script-02-helm-values/git.init.sh
Normal file
1
doc/md/_markdown-tests/script-02-helm-values/git.init.sh
Normal file
@@ -0,0 +1 @@
|
||||
git init . && git add . && git commit -m "initial commit"
|
||||
@@ -0,0 +1,5 @@
|
||||
holos cue import \
|
||||
--package holos \
|
||||
--path 'Helm: Values:' \
|
||||
--outfile components/blackbox/values.cue \
|
||||
components/blackbox/vendor/9.0.1/prometheus-blackbox-exporter/values.yaml
|
||||
@@ -0,0 +1,5 @@
|
||||
holos cue import \
|
||||
--package holos \
|
||||
--path 'Helm: Values:' \
|
||||
--outfile components/prometheus/values.cue \
|
||||
components/prometheus/vendor/25.27.0/prometheus/values.yaml
|
||||
@@ -0,0 +1 @@
|
||||
git add . && git commit -m 'import values'
|
||||
@@ -0,0 +1,4 @@
|
||||
[main d8046af] import values
|
||||
2 files changed, 1815 insertions(+)
|
||||
create mode 100644 components/blackbox/values.cue
|
||||
create mode 100644 components/prometheus/values.cue
|
||||
@@ -0,0 +1,3 @@
|
||||
rendered blackbox in 161.782375ms
|
||||
rendered prometheus in 203.388ms
|
||||
rendered platform in 203.481459ms
|
||||
@@ -0,0 +1,3 @@
|
||||
mkdir holos-helm-values-tutorial
|
||||
cd holos-helm-values-tutorial
|
||||
holos init platform v1alpha5
|
||||
@@ -0,0 +1 @@
|
||||
mkdir -p components/prometheus components/blackbox
|
||||
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: Helm.BuildPlan
|
||||
|
||||
Helm: #Helm & {
|
||||
Chart: {
|
||||
name: "prometheus"
|
||||
version: "25.27.0"
|
||||
repository: {
|
||||
name: "prometheus-community"
|
||||
url: "https://prometheus-community.github.io/helm-charts"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
cat <<EOF > components/prometheus/prometheus.cue
|
||||
@@ -0,0 +1,12 @@
|
||||
package holos
|
||||
|
||||
Platform: Components: {
|
||||
prometheus: {
|
||||
name: "prometheus"
|
||||
path: "components/prometheus"
|
||||
}
|
||||
blackbox: {
|
||||
name: "blackbox"
|
||||
path: "components/blackbox"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
[main 8971a74] add blackbox and prometheus
|
||||
5 files changed, 1550 insertions(+)
|
||||
create mode 100644 components/blackbox/blackbox.cue
|
||||
create mode 100644 components/prometheus/prometheus.cue
|
||||
create mode 100644 deploy/components/blackbox/blackbox.gen.yaml
|
||||
create mode 100644 deploy/components/prometheus/prometheus.gen.yaml
|
||||
create mode 100644 platform/prometheus.cue
|
||||
@@ -0,0 +1 @@
|
||||
git add . && git commit -m 'add blackbox and prometheus'
|
||||
@@ -0,0 +1 @@
|
||||
cat <<EOF > platform/prometheus.cue
|
||||
@@ -0,0 +1,3 @@
|
||||
rendered blackbox in 1.324044833s
|
||||
rendered prometheus in 1.336657625s
|
||||
rendered platform in 1.33672525s
|
||||
1
doc/md/_markdown-tests/script-02-helm-values/render.sh
Normal file
1
doc/md/_markdown-tests/script-02-helm-values/render.sh
Normal file
@@ -0,0 +1 @@
|
||||
holos render platform
|
||||
@@ -0,0 +1 @@
|
||||
git add . && git commit -m 'render integrated blackbox and prometheus manifests'
|
||||
@@ -0,0 +1,2 @@
|
||||
[main 1200227] render integrated blackbox and prometheus manifests
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
@@ -0,0 +1,3 @@
|
||||
rendered blackbox in 374.810666ms
|
||||
rendered prometheus in 382.899334ms
|
||||
rendered platform in 383.270625ms
|
||||
4
doc/md/_markdown-tests/script-02-helm-values/update.sh
Executable file
4
doc/md/_markdown-tests/script-02-helm-values/update.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#! /bin/bash
|
||||
set -euo pipefail
|
||||
[[ -s "$1" ]] && [[ -z "${HOLOS_UPDATE_SCRIPTS:-}" ]] && exit 0
|
||||
cat > "$1"
|
||||
31
doc/md/_markdown-tests/script-02-helm-values/values.patch
Normal file
31
doc/md/_markdown-tests/script-02-helm-values/values.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
--- a/components/blackbox/values.cue
|
||||
+++ b/components/blackbox/values.cue
|
||||
@@ -1,6 +1,8 @@
|
||||
package holos
|
||||
|
||||
Helm: Values: {
|
||||
+ fullnameOverride: Blackbox.host
|
||||
+
|
||||
global: {
|
||||
//# Global image registry to use if it needs to be overriden for some specific use cases (e.g local registries, custom images, ...)
|
||||
//#
|
||||
@@ -192,7 +194,7 @@ Helm: Values: {
|
||||
annotations: {}
|
||||
labels: {}
|
||||
type: "ClusterIP"
|
||||
- port: 9115
|
||||
+ port: Blackbox.port
|
||||
ipDualStack: {
|
||||
enabled: false
|
||||
ipFamilies: ["IPv6", "IPv4"]
|
||||
--- a/components/prometheus/values.cue
|
||||
+++ b/components/prometheus/values.cue
|
||||
@@ -1083,7 +1083,7 @@ Helm: Values: {
|
||||
target_label: "__param_target"
|
||||
}, {
|
||||
target_label: "__address__"
|
||||
- replacement: "blackbox"
|
||||
+ replacement: "\(Blackbox.host):\(Blackbox.port)"
|
||||
}, {
|
||||
source_labels: ["__param_target"]
|
||||
target_label: "instance"
|
||||
@@ -62,8 +62,10 @@ type ComponentConfig struct {
|
||||
|
||||
// Resources represents kubernetes resources mixed into the rendered manifest.
|
||||
Resources core.Resources
|
||||
// KustomizeConfig represents the configuration kustomize.
|
||||
// KustomizeConfig represents the kustomize configuration.
|
||||
KustomizeConfig KustomizeConfig
|
||||
// Validators represent checks that must pass for output to be written.
|
||||
Validators map[NameLabel]core.Validator
|
||||
// Artifacts represents additional artifacts to mix in. Useful for adding
|
||||
// GitOps resources. Each Artifact is unified without modification into the
|
||||
// BuildPlan.
|
||||
|
||||
@@ -15,17 +15,21 @@ Package core contains schemas for a [Platform](<#Platform>) and [BuildPlan](<#Bu
|
||||
## Index
|
||||
|
||||
- [type Artifact](<#Artifact>)
|
||||
- [type Auth](<#Auth>)
|
||||
- [type AuthSource](<#AuthSource>)
|
||||
- [type BuildPlan](<#BuildPlan>)
|
||||
- [type BuildPlanSource](<#BuildPlanSource>)
|
||||
- [type BuildPlanSpec](<#BuildPlanSpec>)
|
||||
- [type Chart](<#Chart>)
|
||||
- [type Command](<#Command>)
|
||||
- [type Component](<#Component>)
|
||||
- [type ExtractYAML](<#ExtractYAML>)
|
||||
- [type File](<#File>)
|
||||
- [type FileContent](<#FileContent>)
|
||||
- [type FileContentMap](<#FileContentMap>)
|
||||
- [type FilePath](<#FilePath>)
|
||||
- [type Generator](<#Generator>)
|
||||
- [type Helm](<#Helm>)
|
||||
- [type Instance](<#Instance>)
|
||||
- [type InternalLabel](<#InternalLabel>)
|
||||
- [type Join](<#Join>)
|
||||
- [type Kind](<#Kind>)
|
||||
@@ -38,6 +42,7 @@ Package core contains schemas for a [Platform](<#Platform>) and [BuildPlan](<#Bu
|
||||
- [type Resource](<#Resource>)
|
||||
- [type Resources](<#Resources>)
|
||||
- [type Transformer](<#Transformer>)
|
||||
- [type Validator](<#Validator>)
|
||||
- [type Values](<#Values>)
|
||||
|
||||
|
||||
@@ -59,10 +64,35 @@ type Artifact struct {
|
||||
Artifact FilePath `json:"artifact,omitempty" yaml:"artifact,omitempty"`
|
||||
Generators []Generator `json:"generators,omitempty" yaml:"generators,omitempty"`
|
||||
Transformers []Transformer `json:"transformers,omitempty" yaml:"transformers,omitempty"`
|
||||
Validators []Validator `json:"validators,omitempty" yaml:"validators,omitempty"`
|
||||
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Auth"></a>
|
||||
## type Auth {#Auth}
|
||||
|
||||
Auth represents environment variable names containing auth credentials.
|
||||
|
||||
```go
|
||||
type Auth struct {
|
||||
Username AuthSource `json:"username" yaml:"username"`
|
||||
Password AuthSource `json:"password" yaml:"password"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="AuthSource"></a>
|
||||
## type AuthSource {#AuthSource}
|
||||
|
||||
AuthSource represents a source for the value of an [Auth](<#Auth>) field.
|
||||
|
||||
```go
|
||||
type AuthSource struct {
|
||||
Value string `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
FromEnv string `json:"fromEnv,omitempty" yaml:"fromEnv,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="BuildPlan"></a>
|
||||
## type BuildPlan {#BuildPlan}
|
||||
|
||||
@@ -85,18 +115,6 @@ type BuildPlan struct {
|
||||
}
|
||||
```
|
||||
|
||||
<a name="BuildPlanSource"></a>
|
||||
## type BuildPlanSource {#BuildPlanSource}
|
||||
|
||||
BuildPlanSource reflects the origin of a [BuildPlan](<#BuildPlan>). Useful to save a build plan to a file, then re\-generate it without needing to process a [Platform](<#Platform>) component collection.
|
||||
|
||||
```go
|
||||
type BuildPlanSource struct {
|
||||
// Component reflects the component that produced the build plan.
|
||||
Component Component `json:"component,omitempty" yaml:"component,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="BuildPlanSpec"></a>
|
||||
## type BuildPlanSpec {#BuildPlanSpec}
|
||||
|
||||
@@ -129,6 +147,17 @@ type Chart struct {
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Command"></a>
|
||||
## type Command {#Command}
|
||||
|
||||
Command represents a command vetting one or more artifacts. Holos appends fully qualified input file paths to the end of the args list, then executes the command. Inputs are written into a temporary directory prior to executing the command and removed afterwards.
|
||||
|
||||
```go
|
||||
type Command struct {
|
||||
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Component"></a>
|
||||
## type Component {#Component}
|
||||
|
||||
@@ -142,6 +171,10 @@ type Component struct {
|
||||
// Path represents the path of the component relative to the platform root.
|
||||
// Injected as the tag variable "holos_component_path".
|
||||
Path string `json:"path" yaml:"path"`
|
||||
// Instances represents additional cue instance paths to unify with Path.
|
||||
// Useful to unify data files into a component BuildPlan. Added in holos
|
||||
// 0.101.7.
|
||||
Instances []Instance `json:"instances,omitempty" yaml:"instances,omitempty"`
|
||||
// WriteTo represents the holos render component --write-to flag. If empty,
|
||||
// the default value for the --write-to flag is used.
|
||||
WriteTo string `json:"writeTo,omitempty" yaml:"writeTo,omitempty"`
|
||||
@@ -155,11 +188,22 @@ type Component struct {
|
||||
// resulting BuildPlan.
|
||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
// Annotations represents arbitrary non-identifying metadata. Use the
|
||||
// `cli.holos.run/description` to customize the log message of each BuildPlan.
|
||||
// `app.holos.run/description` to customize the log message of each BuildPlan.
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="ExtractYAML"></a>
|
||||
## type ExtractYAML {#ExtractYAML}
|
||||
|
||||
ExtractYAML represents a cue data instance encoded as yaml or json. If Path refers to a directory all files in the directory are extracted non\-recursively. Otherwise, path must refer to a file.
|
||||
|
||||
```go
|
||||
type ExtractYAML struct {
|
||||
Path string `json:"path" yaml:"path"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="File"></a>
|
||||
## type File {#File}
|
||||
|
||||
@@ -252,6 +296,22 @@ type Helm struct {
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Instance"></a>
|
||||
## type Instance {#Instance}
|
||||
|
||||
Instance represents a data instance to unify with the configuration.
|
||||
|
||||
Useful to unify json and yaml files with cue configuration files for integration with other tools. For example, executing holos render platform from a pull request workflow after [Kargo](<https://docs.kargo.io/>) executes the [yaml update](<https://docs.kargo.io/references/promotion-steps#yaml-update>) and [git wait for pr](<https://docs.kargo.io/references/promotion-steps#git-wait-for-pr>) promotion steps.
|
||||
|
||||
```go
|
||||
type Instance struct {
|
||||
// Kind is a discriminator.
|
||||
Kind string `json:"kind" yaml:"kind" cue:"\"ExtractYAML\""`
|
||||
// Ignored unless kind is ExtractYAML.
|
||||
ExtractYAML ExtractYAML `json:"extractYAML,omitempty" yaml:"extractYAML,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="InternalLabel"></a>
|
||||
## type InternalLabel {#InternalLabel}
|
||||
|
||||
@@ -316,7 +376,7 @@ type Metadata struct {
|
||||
// Labels represents a resource selector.
|
||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
// Annotations represents arbitrary non-identifying metadata. For example
|
||||
// holos uses the `cli.holos.run/description` annotation to log resources in a
|
||||
// holos uses the `app.holos.run/description` annotation to log resources in a
|
||||
// user customized way.
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
}
|
||||
@@ -364,10 +424,13 @@ type PlatformSpec struct {
|
||||
|
||||
Repository represents a [Helm](<#Helm>) [Chart](<#Chart>) repository.
|
||||
|
||||
The Auth field is useful to configure http basic authentication to the Helm repository. Holos gets the username and password from the environment variables represented by the Auth field.
|
||||
|
||||
```go
|
||||
type Repository struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
URL string `json:"url" yaml:"url"`
|
||||
Auth Auth `json:"auth,omitempty" yaml:"auth,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
@@ -414,6 +477,22 @@ type Transformer struct {
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Validator"></a>
|
||||
## type Validator {#Validator}
|
||||
|
||||
Validator validates files. Useful to validate an [Artifact](<#Artifact>) prior to writing it out to the final destination. Holos may execute validators concurrently. See the [validators](<https://holos.run/docs/v1alpha5/tutorial/validators/>) tutorial for an end to end example.
|
||||
|
||||
```go
|
||||
type Validator struct {
|
||||
// Kind represents the kind of transformer. Must be Kustomize, or Join.
|
||||
Kind string `json:"kind" yaml:"kind" cue:"\"Command\""`
|
||||
// Inputs represents the files to validate. Usually the final Artifact.
|
||||
Inputs []FilePath `json:"inputs" yaml:"inputs"`
|
||||
// Command represents a validation command. Ignored unless kind is Command.
|
||||
Command Command `json:"command,omitempty" yaml:"command,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Values"></a>
|
||||
## type Values {#Values}
|
||||
|
||||
|
||||
87
doc/md/markdown_test.go
Normal file
87
doc/md/markdown_test.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/holos-run/holos/cmd"
|
||||
"github.com/rogpeppe/go-internal/testscript"
|
||||
|
||||
cue "cuelang.org/go/cmd/cue/cmd"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(testscript.RunMain(m, map[string]func() int{
|
||||
"holos": cmd.MakeMain(),
|
||||
"cue": cue.Main,
|
||||
}))
|
||||
}
|
||||
|
||||
// Run these with go test -v to see the verbose names
|
||||
func TestMarkdown(t *testing.T) {
|
||||
t.Run("AddOnPromoter", func(t *testing.T) {
|
||||
// Get an ordered list of test script files.
|
||||
dir := "_markdown-tests"
|
||||
for _, file := range sortedTestScripts(t, filepath.Join(dir, "examples")) {
|
||||
t.Run("examples", func(t *testing.T) {
|
||||
runOneScript(t, dir, file)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func runOneScript(t *testing.T, dir string, file string) {
|
||||
params := testscript.Params{
|
||||
Dir: "",
|
||||
Files: []string{file},
|
||||
RequireExplicitExec: true,
|
||||
RequireUniqueNames: false,
|
||||
WorkdirRoot: filepath.Join(testDir(t), dir),
|
||||
UpdateScripts: os.Getenv("HOLOS_UPDATE_SCRIPTS") != "",
|
||||
Setup: func(env *testscript.Env) error {
|
||||
// Needed for update.sh to determine if we need to update output files.
|
||||
env.Setenv("HOLOS_UPDATE_SCRIPTS", os.Getenv("HOLOS_UPDATE_SCRIPTS"))
|
||||
// Just like cmd/cue/cmd.TestScript, set up separate cache and config dirs per test.
|
||||
env.Setenv("CUE_CACHE_DIR", filepath.Join(env.WorkDir, "tmp/cachedir"))
|
||||
configDir := filepath.Join(env.WorkDir, "tmp/configdir")
|
||||
env.Setenv("CUE_CONFIG_DIR", configDir)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
testscript.Run(t, params)
|
||||
}
|
||||
|
||||
// testDir returns the path of the directory containing the go source file of
|
||||
// the caller.
|
||||
func testDir(t *testing.T) string {
|
||||
_, file, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
t.Fatal("could not get runtime caller")
|
||||
}
|
||||
return filepath.Dir(file)
|
||||
}
|
||||
|
||||
func sortedTestScripts(t *testing.T, dir string) (files []string) {
|
||||
entries, err := os.ReadDir(dir)
|
||||
if os.IsNotExist(err) {
|
||||
// Continue to helpful error on len(files) == 0 below.
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, entry := range entries {
|
||||
name := entry.Name()
|
||||
if strings.HasSuffix(name, ".txtar") || strings.HasSuffix(name, ".txt") {
|
||||
files = append(files, filepath.Join(dir, name))
|
||||
}
|
||||
}
|
||||
if len(files) == 0 {
|
||||
t.Fatalf("no txtar nor txt scripts found in dir %s", dir)
|
||||
}
|
||||
slices.Sort(files)
|
||||
return files
|
||||
}
|
||||
57
doc/md/topics/comparison.mdx
Normal file
57
doc/md/topics/comparison.mdx
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
description: Holos compared to other tools
|
||||
sidebar_label: Comparison
|
||||
slug: comparison
|
||||
sidebar_position: 40
|
||||
---
|
||||
|
||||
{/* cspell:ignore Prodan, rollouts */}
|
||||
|
||||
# Holos compared to other tools
|
||||
|
||||
## Timoni
|
||||
|
||||
Holos and Timoni both aim to solve similar problems but approach them at
|
||||
different levels of the stack.
|
||||
|
||||
Timoni focuses on managing applications by evaluating [CUE] stored in OCI
|
||||
containers. Its creator, Stephan Prodan, envisions a controller that applies the
|
||||
resulting manifests. In this process, Timoni defers to [Flux] for managing Helm
|
||||
charts within the cluster.
|
||||
|
||||
In contrast, Holos implements the [Rendered Manifests Pattern] and takes a
|
||||
different approach, particularly in how it handles [Helm] charts. Like
|
||||
[ArgoCD], Holos renders Helm charts into manifests using the `helm template`
|
||||
command in its rendering pipeline. Holos differs from Timoni in several important
|
||||
ways:
|
||||
|
||||
1. **Separation of Responsibilities:** Holos stops short of applying
|
||||
rendered manifests to a cluster, leaving that task to existing tools like
|
||||
[ArgoCD], [Flux], or even basic `kubectl apply` commands.
|
||||
|
||||
2. **Ecosystem Integration:** By focusing solely on rendering Kubernetes
|
||||
manifests, Holos creates space for other tools to handle deployment and
|
||||
management. For instance, Holos integrates seamlessly with [Kargo] for
|
||||
progressive rollouts, as [Kargo] operates between Holos and the Kubernetes API.
|
||||
This approach ensures that you're not locked into any specific tool and can
|
||||
choose the best solution for each task.
|
||||
|
||||
3. **Platform Integration:** Holos focuses on integrating multiple Components
|
||||
into a larger Platform. In Holos terminology, a Component refers to a wrapper
|
||||
for [Helm] charts, [Kustomize] bases, or raw YAML files, integrated into the
|
||||
rendering pipeline through [CUE]. A Platform represents the full combination of
|
||||
these components.
|
||||
|
||||
4. **Explicit Rendering Pipeline:** Holos emphasizes flexibility in its
|
||||
rendering pipeline. The system allows any tool that generates Kubernetes
|
||||
manifests to be wrapped in a Generator, which can then feed into existing
|
||||
transformers like [Kustomize]. This explicit separation makes Holos highly
|
||||
adaptable for different workflows.
|
||||
|
||||
[Kargo]: https://kargo.io/
|
||||
[Flux]: https://fluxcd.io
|
||||
[Helm]: https://helm.sh
|
||||
[ArgoCD]: https://argoproj.github.io/cd/
|
||||
[Kustomize]: https://kustomize.io/
|
||||
[CUE]: https://cuelang.org/
|
||||
[Rendered Manifests Pattern]: https://akuity.io/blog/the-rendered-manifests-pattern
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
description: Re-use components by passing in parameters.
|
||||
slug: component-parameters
|
||||
sidebar_position: 400
|
||||
---
|
||||
|
||||
# Component Parameters
|
||||
|
||||
Key points:
|
||||
|
||||
1. Components can be reused.
|
||||
2. The Platform spec can pass user defined parameters to a component.
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
description: Organize clusters into fleets.
|
||||
slug: fleets
|
||||
sidebar_position: 300
|
||||
---
|
||||
|
||||
# Fleets
|
||||
|
||||
Key points:
|
||||
|
||||
1. Workload fleet.
|
||||
2. Management fleet.
|
||||
@@ -177,7 +177,7 @@ source:
|
||||
<Tabs groupId="E150C802-7162-4FBF-82A7-77D9ADAEE847">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
@@ -218,7 +218,6 @@ spec:
|
||||
[CUE Module]: https://cuelang.org/docs/reference/modules/
|
||||
[CUE Tags]: https://cuelang.org/docs/howto/inject-value-into-evaluation-using-tag-attribute/
|
||||
[Application]: https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/
|
||||
[Component Parameters]: ../component-parameters.mdx
|
||||
[Platform]: ../../api/author.md#Platform
|
||||
[ComponentConfig]: ../../api/author.md#ComponentConfig
|
||||
[Artifact]: ../../api/core.md#Artifact
|
||||
|
||||
218
doc/md/topics/gitops/flux-kustomization.mdx
Normal file
218
doc/md/topics/gitops/flux-kustomization.mdx
Normal file
@@ -0,0 +1,218 @@
|
||||
---
|
||||
slug: flux-kustomization
|
||||
title: Flux Kustomization
|
||||
description: Configuring a Kustomization for each Component.
|
||||
sidebar_position: 120
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CommonComponent from '../../common/example-component.mdx';
|
||||
import CommonComponentIntegrate from '../../common/example-component-integrate.mdx';
|
||||
|
||||
# Flux Kustomization
|
||||
|
||||
## Overview
|
||||
|
||||
This topic covers how to mix in a Flux Kustomization to all components. We'll
|
||||
use the `Artifacts` field of [ComponentConfig] defined by the author schema.
|
||||
|
||||
## The Code
|
||||
|
||||
### Generating the structure
|
||||
|
||||
Use `holos` to generate a minimal platform directory structure. Start by
|
||||
creating a blank directory to hold the platform configuration.
|
||||
|
||||
```shell
|
||||
mkdir holos-flux-kustomization && cd holos-flux-kustomization
|
||||
```
|
||||
|
||||
```shell
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
|
||||
### Creating an example Component
|
||||
|
||||
<CommonComponent />
|
||||
<CommonComponentIntegrate />
|
||||
|
||||
## Adding Flux Kustomizations
|
||||
|
||||
Configure Holos to render a [Kustomization] by defining an [Artifact] for it in
|
||||
every BuildPlan holos produces. We're unifying our custom configuration with
|
||||
the existing `#ComponentConfig` defined in `schema.cue`.
|
||||
|
||||
```bash
|
||||
cat <<EOF >flux-kustomization.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
import (
|
||||
"path"
|
||||
flux "kustomize.toolkit.fluxcd.io/kustomization/v1"
|
||||
)
|
||||
|
||||
#ComponentConfig: {
|
||||
Name: _
|
||||
OutputBaseDir: _
|
||||
|
||||
let ArtifactPath = path.Join([OutputBaseDir, "gitops", "\(Name).kustomization.gen.yaml"], path.Unix)
|
||||
let ResourcesPath = path.Join(["deploy", OutputBaseDir, "components", Name], path.Unix)
|
||||
|
||||
Artifacts: "\(Name)-kustomization": {
|
||||
artifact: ArtifactPath
|
||||
generators: [{
|
||||
kind: "Resources"
|
||||
output: artifact
|
||||
resources: Kustomization: (Name): flux.#Kustomization & {
|
||||
metadata: name: Name
|
||||
metadata: namespace: "default"
|
||||
spec: {
|
||||
interval: "5m"
|
||||
timeout: "1m"
|
||||
prune: true
|
||||
path: ResourcesPath
|
||||
sourceRef: {
|
||||
kind: "GitRepository"
|
||||
name: "webapp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
## Inspecting the BuildPlan
|
||||
|
||||
Our customized `#ComponentConfig` results in the following `BuildPlan`.
|
||||
|
||||
:::note
|
||||
The second artifact around line 40 contains the configured `Kustomization`
|
||||
resource.
|
||||
:::
|
||||
|
||||
<Tabs groupId="55075C71-02E8-4222-88C0-2D52C82D18FC">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos cue export --expression holos --out=yaml ./components/podinfo
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
kind: BuildPlan
|
||||
apiVersion: v1alpha5
|
||||
metadata:
|
||||
name: podinfo
|
||||
spec:
|
||||
artifacts:
|
||||
- artifact: components/podinfo/podinfo.gen.yaml
|
||||
generators:
|
||||
- kind: Helm
|
||||
output: helm.gen.yaml
|
||||
helm:
|
||||
chart:
|
||||
name: podinfo
|
||||
version: 6.6.2
|
||||
release: podinfo
|
||||
repository:
|
||||
name: podinfo
|
||||
url: https://stefanprodan.github.io/podinfo
|
||||
values:
|
||||
ui:
|
||||
message: Hello World
|
||||
enableHooks: false
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
resources: {}
|
||||
validators: []
|
||||
transformers:
|
||||
- kind: Kustomize
|
||||
inputs:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
output: components/podinfo/podinfo.gen.yaml
|
||||
kustomize:
|
||||
kustomization:
|
||||
resources:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
kind: Kustomization
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
- artifact: gitops/podinfo.kustomization.gen.yaml
|
||||
generators:
|
||||
- kind: Resources
|
||||
output: gitops/podinfo.kustomization.gen.yaml
|
||||
resources:
|
||||
Kustomization:
|
||||
podinfo:
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: default
|
||||
spec:
|
||||
interval: 5m
|
||||
path: deploy/components/podinfo
|
||||
prune: true
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: webapp
|
||||
timeout: 1m
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Rendering manifests
|
||||
|
||||
<Tabs groupId="E150C802-7162-4FBF-82A7-77D9ADAEE847">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```
|
||||
rendered podinfo in 140.341417ms
|
||||
rendered platform in 140.441333ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Reviewing the Kustomization
|
||||
|
||||
The Artifact we added to `#ComponentConfig` will produce a Flux Kustomization
|
||||
resource for every component in the platform. The output in this example is
|
||||
located at:
|
||||
|
||||
```txt
|
||||
deploy/gitops/podinfo.kustomization.gen.yaml
|
||||
```
|
||||
```yaml showLineNumbers
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: default
|
||||
spec:
|
||||
interval: 5m
|
||||
path: deploy/components/podinfo
|
||||
prune: true
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: webapp
|
||||
timeout: 1m
|
||||
```
|
||||
|
||||
[podinfo]: https://github.com/stefanprodan/podinfo
|
||||
[CUE Module]: https://cuelang.org/docs/reference/modules/
|
||||
[CUE Tags]: https://cuelang.org/docs/howto/inject-value-into-evaluation-using-tag-attribute/
|
||||
[Kustomization]: https://fluxcd.io/flux/components/kustomize/kustomizations/
|
||||
[Platform]: ../../api/author.md#Platform
|
||||
[ComponentConfig]: ../../api/author.md#ComponentConfig
|
||||
[Artifact]: ../../api/core.md#Artifact
|
||||
20
doc/md/topics/kargo.mdx
Normal file
20
doc/md/topics/kargo.mdx
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
description: Kargo
|
||||
slug: kargo
|
||||
sidebar_position: 110
|
||||
---
|
||||
|
||||
# Kargo
|
||||
|
||||
Holos pairs nicely with [Kargo], offering a holistic solution for code
|
||||
promotion across stages.
|
||||
|
||||
Watch this space for a more detailed write up of the integration being
|
||||
developed.
|
||||
|
||||
If you're interested in this topic, please thumbs up the [Kargo
|
||||
Topic](https://github.com/holos-run/holos/issues/378) issue, or drop into
|
||||
[Discord] and let us know about your use case.
|
||||
|
||||
[Kargo]: https://kargo.io/
|
||||
[Discord]: https://discord.gg/JgDVbNpye7
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
description: Management Cluster
|
||||
slug: management-cluster
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
# Management Cluster
|
||||
|
||||
Key points:
|
||||
|
||||
1. Namespaces
|
||||
2. Certificates
|
||||
3. Secrets
|
||||
4. CronJobs
|
||||
5. GKE autopilot
|
||||
65
doc/md/topics/oci-helm-charts.mdx
Normal file
65
doc/md/topics/oci-helm-charts.mdx
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
description: OCI Helm Charts
|
||||
slug: oci-helm-charts
|
||||
sidebar_position: 710
|
||||
---
|
||||
|
||||
# OCI Helm Charts
|
||||
|
||||
Holos supports OCI Helm charts. Use the following example to get started.
|
||||
|
||||
```bash
|
||||
mkdir -p oci-helm && cd oci-helm
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
|
||||
```bash
|
||||
mkdir -p components/podinfo-oci
|
||||
cat <<EOF > components/podinfo-oci/podinfo-oci.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
Component: #Helm & {
|
||||
Chart: {
|
||||
name: "oci://ghcr.io/stefanprodan/charts/podinfo"
|
||||
release: "podinfo"
|
||||
version: "6.6.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
Register the component with the platform.
|
||||
|
||||
```bash
|
||||
cat <<EOF >platform/podinfo-oci.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
Platform: Components: podinfo: {
|
||||
name: "podinfo-oci"
|
||||
path: "components/podinfo-oci"
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
The OCI chart is cached in the vendor directory and rendered.
|
||||
|
||||
```bash
|
||||
holos render platform
|
||||
```
|
||||
|
||||
```txt
|
||||
Pulled: ghcr.io/stefanprodan/charts/podinfo:6.6.2
|
||||
Digest: sha256:83295d47de6d6ca634ed4b952a7572fc176bcc38854d0c11ca0fa197bc5f1154
|
||||
rendered podinfo-oci in 7.21581325s
|
||||
rendered platform in 7.216199167s
|
||||
```
|
||||
183
doc/md/topics/private-helm.mdx
Normal file
183
doc/md/topics/private-helm.mdx
Normal file
@@ -0,0 +1,183 @@
|
||||
---
|
||||
description: Private Helm Repositories
|
||||
slug: private-helm
|
||||
sidebar_position: 700
|
||||
---
|
||||
|
||||
# Private Helm
|
||||
|
||||
Holos supports private Helm repositories accessed with http basic authentication
|
||||
since `v0.101.4`. Use the following command to update your author and core
|
||||
schemas to support this configuration.
|
||||
|
||||
```bash
|
||||
holos init platform v1alpha5 --force
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Holos uses the Helm SDK and defers to it for authentication to private
|
||||
repositories. Each Helm Generator supports providing http basic authentication
|
||||
credentials from environment variables.
|
||||
|
||||
For example, the following BuildPlan causes `holos` to get the admin username
|
||||
password from the `HOLOS_TEST_PASS` environment variable.
|
||||
|
||||
```bash
|
||||
mkdir -p projects/holos/components/private-chart
|
||||
cat <<EOF > projects/holos/components/private-chart/private-chart.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
// Test holos can access a private repository with basic auth.
|
||||
// https://github.com/holos-run/holos/issues/370
|
||||
Component: #Helm & {
|
||||
Chart: {
|
||||
name: "mychart"
|
||||
version: "0.1.0"
|
||||
repository: {
|
||||
name: "holos-test"
|
||||
url: "https://charts.holos.localhost"
|
||||
// auth: username: fromEnv: "HOLOS_TEST_USER"
|
||||
auth: username: value: "admin"
|
||||
auth: password: fromEnv: "HOLOS_TEST_PASS"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
Verify `holos` can access a private Helm repository by setting [ChartMuseum] up
|
||||
on a [Local Cluster]. We'll use https with basic auth to authenticate to the
|
||||
chart repository.
|
||||
|
||||
Using the [bank of holos] repository, deploy chart museum:
|
||||
|
||||
```bash
|
||||
holos render platform -t ChartMuseum
|
||||
```
|
||||
|
||||
Apply the manifests:
|
||||
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/projects/holos/components/chart-museum
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/projects/network/components/httproutes
|
||||
```
|
||||
|
||||
Get the admin password:
|
||||
|
||||
```bash
|
||||
kubectl get secret -n holos chartmuseum-auth -o json \
|
||||
| jq --exit-status -r '.data.password | @base64d'
|
||||
```
|
||||
|
||||
Add a local repo:
|
||||
|
||||
```bash
|
||||
helm repo add holos-test https://charts.holos.localhost --username admin
|
||||
```
|
||||
```txt
|
||||
Password:
|
||||
"holos-test" has been added to your repositories
|
||||
```
|
||||
|
||||
:::note
|
||||
Helm by default stores this password in `~/Library/Preferences/helm/repositories.yaml`
|
||||
:::
|
||||
|
||||
Create a chart:
|
||||
|
||||
```bash
|
||||
helm create mychart
|
||||
```
|
||||
```txt
|
||||
Creating mychart
|
||||
```
|
||||
|
||||
Package it up.
|
||||
|
||||
```bash
|
||||
helm package mychart
|
||||
```
|
||||
```txt
|
||||
Successfully packaged chart and saved it to: mychart-0.1.0.tgz
|
||||
```
|
||||
|
||||
Publish it.
|
||||
|
||||
```bash
|
||||
curl --user "admin:$(pbpaste)" --data-binary "@mychart-0.1.0.tgz" https://charts.holos.localhost/api/charts
|
||||
```
|
||||
```json
|
||||
{"saved":true}
|
||||
```
|
||||
|
||||
Remove all cached charts:
|
||||
|
||||
```bash
|
||||
find . -name vendor | xargs rm -rf
|
||||
```
|
||||
|
||||
Render the chart:
|
||||
|
||||
```bash
|
||||
cat <<EOF > test-private-repo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
@if(TestPrivateRepo)
|
||||
package holos
|
||||
|
||||
// Test holos can access a private repository with basic auth.
|
||||
// https://github.com/holos-run/holos/issues/370
|
||||
Projects: holos: #ProjectBuilder & {
|
||||
team: "holos-authors"
|
||||
|
||||
namespaces: holos: _
|
||||
_components: "private-chart": _
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
```
|
||||
time holos render platform -t TestPrivateRepo
|
||||
```
|
||||
|
||||
Check the chart was pulled and cached:
|
||||
|
||||
```shell
|
||||
tree ./projects/holos/components/private-chart/vendor
|
||||
```
|
||||
```txt
|
||||
./projects/holos/components/private-chart/vendor
|
||||
└── 0.1.0
|
||||
├── mychart
|
||||
│ ├── Chart.yaml
|
||||
│ ├── mychart-0.1.0.tgz
|
||||
│ ├── templates
|
||||
│ │ ├── NOTES.txt
|
||||
│ │ ├── _helpers.tpl
|
||||
│ │ ├── deployment.yaml
|
||||
│ │ ├── hpa.yaml
|
||||
│ │ ├── ingress.yaml
|
||||
│ │ ├── service.yaml
|
||||
│ │ ├── serviceaccount.yaml
|
||||
│ │ └── tests
|
||||
│ │ └── test-connection.yaml
|
||||
│ └── values.yaml
|
||||
└── mychart-0.1.0.tgz
|
||||
|
||||
6 directories, 11 files
|
||||
```
|
||||
|
||||
[Local Cluster]: ./local-cluster.mdx
|
||||
[ChartMuseum]: https://chartmuseum.com/docs/
|
||||
[bank of holos]: https://github.com/holos-run/bank-of-holos
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
description: Secrets Management
|
||||
slug: secrets-management
|
||||
sidebar_position: 150
|
||||
---
|
||||
|
||||
# Secrets Management
|
||||
|
||||
Key points:
|
||||
|
||||
1. Namespaces
|
||||
2. ExternalSecrets
|
||||
@@ -39,11 +39,12 @@ mkdir holos-multiple-clusters && cd holos-multiple-clusters
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
|
||||
### Example Component
|
||||
### Using an example Component
|
||||
|
||||
<CommonComponent />
|
||||
|
||||
We'll integrate the component with the platform after we define clusters.
|
||||
We'll integrate the component with the platform after we define the
|
||||
configuration structures.
|
||||
|
||||
## Defining Clusters
|
||||
|
||||
@@ -320,7 +321,7 @@ Render the platform to configure `podinfo` on each cluster.
|
||||
<Tabs groupId="34A2D80B-0E86-4142-B65B-7DF70C47E1D2">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
|
||||
@@ -7,23 +7,515 @@ sidebar_position: 130
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CommonComponent from '../../common/example-component.mdx';
|
||||
|
||||
# Environments
|
||||
|
||||
## Overview
|
||||
|
||||
This topic covers how to model environments in Holos. We'll define schemas for
|
||||
`#Environment` and `#Environments` to represent one environment and a
|
||||
collection. The `Environments: #Environments` struct maps environment names to
|
||||
configurations.
|
||||
|
||||
:::note
|
||||
This approach unifies the component definition with the overall platform
|
||||
configuration, creating a tight coupling between the two.
|
||||
:::
|
||||
|
||||
This tight coupling is appropriate when you're configuring your own platform.
|
||||
For example:
|
||||
|
||||
1. When you're integrating third party software into your own platform.
|
||||
2. When you're configuring first party in-house software into your own platform.
|
||||
|
||||
This approach is not well suited to writing a component to share outside of your
|
||||
own organization, which we can think of as configuring someone else's platform.
|
||||
|
||||
## The Code
|
||||
|
||||
### Generating the structure
|
||||
|
||||
Use `holos init platform` to generate a minimal platform structure:
|
||||
|
||||
```shell
|
||||
mkdir holos-environments-tutorial && cd holos-environments-tutorial
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
|
||||
### Using an example Component
|
||||
|
||||
Create a directory for the example `podinfo` component we'll use to render
|
||||
platform manifests.
|
||||
|
||||
```bash
|
||||
mkdir -p components/podinfo
|
||||
```
|
||||
|
||||
Create the CUE configuration for the example `podinfo` component.
|
||||
|
||||
```bash
|
||||
cat <<EOF >components/podinfo/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
Component: #Helm & {
|
||||
Chart: {
|
||||
name: "podinfo"
|
||||
version: "6.6.2"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
Values: ui: {
|
||||
message: string | *"Hello World" @tag(message, type=string)
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
We'll integrate the component with the platform after we define the
|
||||
configuration structures.
|
||||
|
||||
## Defining Environments
|
||||
|
||||
### Defining one Environment
|
||||
We'll define an `#Environment` schema `#Environments` collection. We'll use
|
||||
these schemas to define an `Environments` struct of concrete configuration
|
||||
values.
|
||||
|
||||
### Defining a collection of Environments
|
||||
### Assumptions
|
||||
|
||||
## Rendering manifests
|
||||
There are two tiers of environments, prod and nonprod. Prod environments
|
||||
organized along broad jurisdictions, for example US and EU. Nonprod
|
||||
environments are organized by purpose, dev, test, and stage.
|
||||
|
||||
## Reviewing the Manifests
|
||||
### Prototyping the data
|
||||
|
||||
Before we define the schema, let's prototype the data structure we want to work
|
||||
with from the perspective of each component.
|
||||
|
||||
Let's imagine we're configuring `podinfo` to comply with regulations. When
|
||||
podinfo is deployed to production in the EU, we'll configure opt-in behavior.
|
||||
In the US we'll configure opt-out behavior.
|
||||
|
||||
We'll pass the environment name as a component parameter. The component
|
||||
definition can then look up the jurisdiction to determine the appropriate
|
||||
configuration values.
|
||||
|
||||
```shell
|
||||
holos cue export --out=yaml --expression Environments
|
||||
```
|
||||
|
||||
```yaml showLineNumbers
|
||||
prod-pdx:
|
||||
name: prod-pdx
|
||||
tier: prod
|
||||
jurisdiction: us
|
||||
state: oregon
|
||||
prod-cmh:
|
||||
name: prod-cmh
|
||||
tier: prod
|
||||
jurisdiction: us
|
||||
state: ohio
|
||||
prod-ams:
|
||||
name: prod-ams
|
||||
tier: prod
|
||||
jurisdiction: eu
|
||||
state: netherlands
|
||||
dev:
|
||||
name: dev
|
||||
tier: nonprod
|
||||
jurisdiction: us
|
||||
state: oregon
|
||||
test:
|
||||
name: test
|
||||
tier: nonprod
|
||||
jurisdiction: us
|
||||
state: oregon
|
||||
stage:
|
||||
name: stage
|
||||
tier: nonprod
|
||||
jurisdiction: us
|
||||
state: oregon
|
||||
```
|
||||
|
||||
### Defining the schema
|
||||
|
||||
Given the example structure, we can write a schema to define and validate the
|
||||
data.
|
||||
|
||||
```shell
|
||||
cat <<EOF > environments.schema.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
#Environment: {
|
||||
name: string
|
||||
tier: "prod" | "nonprod"
|
||||
jurisdiction: "us" | "eu" | "uk" | "global"
|
||||
state: "oregon" | "ohio" | "germany" | "netherlands" | "england" | "global"
|
||||
|
||||
// Prod environment names must be prefixed with prod for clarity.
|
||||
if tier == "prod" {
|
||||
name: "prod" | =~"^prod-"
|
||||
}
|
||||
}
|
||||
|
||||
#Environments: {
|
||||
[NAME=string]: #Environment & {
|
||||
name: NAME
|
||||
}
|
||||
}
|
||||
```
|
||||
```shell
|
||||
EOF
|
||||
```
|
||||
|
||||
### Adding configuration
|
||||
|
||||
With a schema defined, we can fill in the concrete values.
|
||||
|
||||
```shell
|
||||
cat <<EOF > environments.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Injected from Platform.spec.components.parameters.EnvironmentName
|
||||
EnvironmentName: string @tag(EnvironmentName)
|
||||
|
||||
Environments: #Environments & {
|
||||
"prod-pdx": {
|
||||
tier: "prod"
|
||||
jurisdiction: "us"
|
||||
state: "oregon"
|
||||
}
|
||||
"prod-cmh": {
|
||||
tier: "prod"
|
||||
jurisdiction: "us"
|
||||
state: "ohio"
|
||||
}
|
||||
"prod-ams": {
|
||||
tier: "prod"
|
||||
jurisdiction: "eu"
|
||||
state: "netherlands"
|
||||
}
|
||||
// Nonprod environments are colocated together.
|
||||
_nonprod: {
|
||||
tier: "nonprod"
|
||||
jurisdiction: "us"
|
||||
state: "oregon"
|
||||
}
|
||||
dev: _nonprod
|
||||
test: _nonprod
|
||||
stage: _nonprod
|
||||
}
|
||||
```
|
||||
```shell
|
||||
EOF
|
||||
```
|
||||
|
||||
### Inspecting the configuration
|
||||
|
||||
Inspect the `Environments` data structure to verify the schema and concrete
|
||||
values are what we want.
|
||||
|
||||
<Tabs groupId="FF820F5A-A85F-464D-B299-39CAAFFCE5C6">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos cue export --out=yaml --expression Environments
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
prod-pdx:
|
||||
name: prod-pdx
|
||||
tier: prod
|
||||
jurisdiction: us
|
||||
state: oregon
|
||||
prod-cmh:
|
||||
name: prod-cmh
|
||||
tier: prod
|
||||
jurisdiction: us
|
||||
state: ohio
|
||||
prod-ams:
|
||||
name: prod-ams
|
||||
tier: prod
|
||||
jurisdiction: eu
|
||||
state: netherlands
|
||||
dev:
|
||||
name: dev
|
||||
tier: nonprod
|
||||
jurisdiction: us
|
||||
state: oregon
|
||||
test:
|
||||
name: test
|
||||
tier: nonprod
|
||||
jurisdiction: us
|
||||
state: oregon
|
||||
stage:
|
||||
name: stage
|
||||
tier: nonprod
|
||||
jurisdiction: us
|
||||
state: oregon
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This looks like our prototype, we're confident we can iterate over each
|
||||
environment and get a handle on the configuration values we need.
|
||||
|
||||
## Integrating components
|
||||
|
||||
The `Environments` data structure unlocks the capability to look up concrete
|
||||
values specific to a named environment. We'll use this capability to configure
|
||||
the `podinfo` component in compliance with the regulations of the jurisdiction.
|
||||
|
||||
### Configuring the environment
|
||||
|
||||
Inject the environment name when we integrate `podinfo` with the platform.
|
||||
|
||||
```shell
|
||||
cat <<EOF > platform/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
Platform: Components: {
|
||||
podinfoPDX: ProdPodinfo & {_city: "pdx"}
|
||||
podinfoCMH: ProdPodinfo & {_city: "cmh"}
|
||||
podinfoAMS: ProdPodinfo & {_city: "ams"}
|
||||
podinfoDEV: {
|
||||
name: "podinfo-dev"
|
||||
path: "components/podinfo"
|
||||
labels: "app.holos.run/component": "podinfo"
|
||||
parameters: EnvironmentName: "dev"
|
||||
}
|
||||
}
|
||||
|
||||
let ProdPodinfo = {
|
||||
_city: string
|
||||
name: "podinfo-\(_city)"
|
||||
path: "components/podinfo"
|
||||
labels: "app.holos.run/component": "podinfo"
|
||||
labels: "app.holos.run/tier": "prod"
|
||||
labels: "app.holos.run/city": _city
|
||||
parameters: EnvironmentName: "prod-\(_city)"
|
||||
}
|
||||
```
|
||||
```
|
||||
EOF
|
||||
```
|
||||
|
||||
### Using the environment
|
||||
|
||||
Now we can configure `podinfo` based on the jurisdiction of the environment.
|
||||
|
||||
```shell
|
||||
cat <<EOF > components/podinfo/cookie-consent.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Schema definition for our configuration.
|
||||
#Values: {
|
||||
ui: enableCookieConsent: *true | false
|
||||
ui: message: string
|
||||
}
|
||||
|
||||
// Map jurisdiction to helm values
|
||||
JurisdictionValues: {
|
||||
// Enable cookie consent by default in any jurisdiction.
|
||||
[_]: #Values
|
||||
// Disable in the US.
|
||||
us: ui: enableCookieConsent: false
|
||||
eu: ui: enableCookieConsent: true
|
||||
}
|
||||
|
||||
// Look up the configuration values associated with the environment name.
|
||||
Component: Values: JurisdictionValues[Environments[EnvironmentName].jurisdiction]
|
||||
```
|
||||
```shell
|
||||
EOF
|
||||
```
|
||||
|
||||
### Inspecting the BuildPlans
|
||||
|
||||
With the above configuration, we can inspect the buildplans for this component.
|
||||
The prod environment in Amsterdam has cookie consent enabled on line 26.
|
||||
|
||||
<Tabs groupId="6EC991F3-F78C-43F1-8A6D-E68D8BDAF58B">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos show buildplans --selector app.holos.run/city=ams
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
kind: BuildPlan
|
||||
apiVersion: v1alpha5
|
||||
metadata:
|
||||
name: podinfo-ams
|
||||
labels:
|
||||
app.holos.run/city: ams
|
||||
app.holos.run/component: podinfo
|
||||
app.holos.run/name: podinfo-ams
|
||||
app.holos.run/tier: prod
|
||||
spec:
|
||||
artifacts:
|
||||
- artifact: components/podinfo-ams/podinfo-ams.gen.yaml
|
||||
generators:
|
||||
- kind: Helm
|
||||
output: helm.gen.yaml
|
||||
helm:
|
||||
chart:
|
||||
name: podinfo
|
||||
version: 6.6.2
|
||||
release: podinfo
|
||||
repository:
|
||||
name: podinfo
|
||||
url: https://stefanprodan.github.io/podinfo
|
||||
values:
|
||||
ui:
|
||||
# highlight-next-line
|
||||
enableCookieConsent: true
|
||||
message: Hello World
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
transformers:
|
||||
- kind: Kustomize
|
||||
inputs:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
output: components/podinfo-ams/podinfo-ams.gen.yaml
|
||||
kustomize:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
- artifact: gitops/podinfo-ams.application.gen.yaml
|
||||
generators:
|
||||
- kind: Resources
|
||||
output: gitops/podinfo-ams.application.gen.yaml
|
||||
resources:
|
||||
Application:
|
||||
podinfo-ams:
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo-ams
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: deploy/components/podinfo-ams
|
||||
repoURL: https://github.com/brenix/holos-demo.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
In Portland cookie consent is disabled.
|
||||
|
||||
<Tabs groupId="3438335B-1FFC-4838-B8DE-C54B8346CDB4">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos show buildplans --selector app.holos.run/city=pdx
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
kind: BuildPlan
|
||||
apiVersion: v1alpha5
|
||||
metadata:
|
||||
name: podinfo-pdx
|
||||
labels:
|
||||
app.holos.run/city: pdx
|
||||
app.holos.run/component: podinfo
|
||||
app.holos.run/name: podinfo-pdx
|
||||
app.holos.run/tier: prod
|
||||
spec:
|
||||
artifacts:
|
||||
- artifact: components/podinfo-pdx/podinfo-pdx.gen.yaml
|
||||
generators:
|
||||
- kind: Helm
|
||||
output: helm.gen.yaml
|
||||
helm:
|
||||
chart:
|
||||
name: podinfo
|
||||
version: 6.6.2
|
||||
release: podinfo
|
||||
repository:
|
||||
name: podinfo
|
||||
url: https://stefanprodan.github.io/podinfo
|
||||
values:
|
||||
ui:
|
||||
# highlight-next-line
|
||||
enableCookieConsent: false
|
||||
message: Hello World
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
transformers:
|
||||
- kind: Kustomize
|
||||
inputs:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
output: components/podinfo-pdx/podinfo-pdx.gen.yaml
|
||||
kustomize:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
- artifact: gitops/podinfo-pdx.application.gen.yaml
|
||||
generators:
|
||||
- kind: Resources
|
||||
output: gitops/podinfo-pdx.application.gen.yaml
|
||||
resources:
|
||||
Application:
|
||||
podinfo-pdx:
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo-pdx
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: deploy/components/podinfo-pdx
|
||||
repoURL: https://github.com/brenix/holos-demo.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Concluding Remarks
|
||||
|
||||
In this topic we covered how to use a CUE structure to define attributes of prod
|
||||
and nonprod environments.
|
||||
|
||||
1. We passed the environment name as a parameter to each component using a CUE `@tag`.
|
||||
2. The component definition uses the environment name as a key to get a handle
|
||||
on attributes. For example, the jurisdiction a service operates within.
|
||||
3. The example podinfo component uses an additional structure to map
|
||||
jurisdictions to concrete configuration values.
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
slug: owners
|
||||
title: Owners
|
||||
description: Managing and mapping projects to owners.
|
||||
sidebar_position: 150
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Owners
|
||||
|
||||
## Overview
|
||||
|
||||
## The Code
|
||||
|
||||
### Generating the structure
|
||||
|
||||
### Using an example Component
|
||||
|
||||
## Defining Owners
|
||||
|
||||
### Defining one Owner
|
||||
|
||||
### Defining a collection of Owners
|
||||
|
||||
## Rendering manifests
|
||||
|
||||
## Reviewing the Manifests
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
slug: projects
|
||||
title: Projects
|
||||
description: Managing components organizing them into projects.
|
||||
sidebar_position: 140
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Projects
|
||||
|
||||
## Overview
|
||||
|
||||
## The Code
|
||||
|
||||
### Generating the structure
|
||||
|
||||
### Using an example Component
|
||||
|
||||
## Defining Projects
|
||||
|
||||
### Defining one Project
|
||||
|
||||
### Defining a collection of Projects
|
||||
|
||||
## Rendering manifests
|
||||
|
||||
## Reviewing the Manifests
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
description: Workload Cluster
|
||||
slug: workload-cluster
|
||||
sidebar_position: 250
|
||||
---
|
||||
|
||||
# Workload Cluster
|
||||
|
||||
Key points:
|
||||
|
||||
1. Namespaces
|
||||
2. ExternalSecrets
|
||||
@@ -12,34 +12,34 @@ import TabItem from '@theme/TabItem';
|
||||
|
||||
## Overview
|
||||
|
||||
This tutorial demonstrates mixing additional resources into a component using
|
||||
CUE. Holos components frequently mix in resources so we don't need to modify
|
||||
existing charts or manifests. We'll add an [ExternalSecret] resource to the
|
||||
podinfo Helm chart we configured in the [Hello Holos] tutorial.
|
||||
This tutorial demonstrates how to add additional resources to a component using
|
||||
CUE. Holos components often mix in resources, eliminating the need to modify
|
||||
existing charts or manifests. In this tutorial, we'll add an [ExternalSecret]
|
||||
resource to the podinfo Helm chart configured in the [Hello Holos] tutorial.
|
||||
|
||||
Key concepts:
|
||||
|
||||
1. Resources are validated against `#Resources` defined at the root.
|
||||
2. Custom Resource Definitions need to be imported with timoni.
|
||||
3. Helm, Kustomize, and CUE can be mixed in together in the same component.
|
||||
2. Custom Resource Definitions need to be imported using Timoni.
|
||||
3. Helm, Kustomize, and CUE can be mixed together within the same component.
|
||||
|
||||
## The Code
|
||||
|
||||
### Generating the structure
|
||||
### Generating the Structure
|
||||
|
||||
Use `holos` to generate a minimal platform directory structure. First, create
|
||||
and cd into a blank directory. Then use the `holos generate platform` command to
|
||||
generate a minimal platform.
|
||||
Use `holos` to generate a minimal platform directory structure. First, create
|
||||
and navigate into a blank directory. Then, use the `holos generate platform`
|
||||
command to generate a minimal platform.
|
||||
|
||||
```shell
|
||||
mkdir holos-cue-tutorial && cd holos-cue-tutorial
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
|
||||
### Creating the component
|
||||
### Creating the Component
|
||||
|
||||
Create the directory for the `podinfo` component. Create an empty file and then
|
||||
add the following CUE configuration to it.
|
||||
Create the directory for the `podinfo` component. Create an empty file, then add
|
||||
the following CUE configuration to it.
|
||||
|
||||
```bash
|
||||
mkdir -p components/podinfo
|
||||
@@ -72,7 +72,7 @@ Component: #Helm & {
|
||||
EOF
|
||||
```
|
||||
|
||||
Integrate the component with the platform.
|
||||
Register the component with the platform.
|
||||
|
||||
```bash
|
||||
cat <<EOF > platform/podinfo.cue
|
||||
@@ -94,7 +94,7 @@ Render the platform.
|
||||
<Tabs groupId="tutorial-hello-render-manifests">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
@@ -161,12 +161,13 @@ field validates against the `#Resources` definition in [resources.cue].
|
||||
|
||||
### Importing CRDs
|
||||
|
||||
Holos includes CUE schema definitions of the ExternalSecret custom resource
|
||||
definition (CRD). These schemas are located in the `cue.mod` directory, written by
|
||||
the `holos init platform` command we executed at the start of this tutorial.
|
||||
Holos includes CUE schema definitions for the ExternalSecret Custom Resource
|
||||
Definition (CRD). These schemas are located in the `cue.mod` directory,
|
||||
generated by the `holos init platform` command executed at the start of this
|
||||
tutorial.
|
||||
|
||||
Import your own custom resource definitions using [timoni]. We imported the
|
||||
ExternalSecret CRDs embedded into `holos` with the following command.
|
||||
To import your own custom resource definitions, use [Timoni]. We imported the
|
||||
ExternalSecret CRDs embedded in `holos` using the following command.
|
||||
|
||||
<Tabs groupId="35B1A1A1-D7DF-4D27-A575-28556E182096">
|
||||
<TabItem value="command" label="Command">
|
||||
@@ -203,16 +204,16 @@ Take a look at
|
||||
the imported definitions.
|
||||
:::
|
||||
|
||||
Once imported, the last step is to add the resource kind to the `#Resources`
|
||||
struct. This is most often accomplished by adding a new file which cue unifies
|
||||
with the existing [resources.cue] file.
|
||||
Once imported, the final step is to add the resource kind to the `#Resources`
|
||||
struct. Typically, this is done by creating a new file that CUE unifies with the
|
||||
existing [resources.cue] file.
|
||||
|
||||
## Reviewing Changes
|
||||
|
||||
Render the platform with the `ExternalSecret` mixed into the podinfo component.
|
||||
|
||||
```shell
|
||||
holos render platform ./platform
|
||||
holos render platform
|
||||
```
|
||||
|
||||
Take a look at the diff to see the mixed in `ExternalSecret`.
|
||||
@@ -249,22 +250,20 @@ index 6e4aec0..f79e9d0 100644
|
||||
```
|
||||
|
||||
We saw how to mix in resources using the `Resources` field of the
|
||||
[ComponentConfig]. This technique approach works for every kind of component in
|
||||
Holos. We did this without needing to fork the upstream Helm chart so we can
|
||||
easily update to new podinfo versions as they're released.
|
||||
[ComponentConfig]. This approach works for every kind of component in Holos,
|
||||
allowing seamless integration without needing to fork the upstream Helm chart.
|
||||
This way, we can easily update to new podinfo versions as they're released.
|
||||
|
||||
## Trying Locally
|
||||
|
||||
Optionally apply the manifests Holos rendered to a [Local Cluster].
|
||||
Optionally, apply the manifests rendered by Holos to a [Local Cluster] for
|
||||
testing.
|
||||
|
||||
## Next Steps
|
||||
|
||||
This tutorial uses the `#Resources` structure to map resource kinds to their
|
||||
schema definitions in CUE. This structure is defined in `resources.cue` at the
|
||||
root of the tree. Take a look at [resources.cue] to see this mapping structure.
|
||||
|
||||
Continue to the next tutorial to learn how to define your own data structures
|
||||
similar to this `#Resources` structure.
|
||||
schema definitions in CUE. This structure is defined in `resources.cue` at the
|
||||
root of the tree. Take a look at [resources.cue] to see this mapping structure.
|
||||
|
||||
[Local Cluster]: ../topics/local-cluster.mdx
|
||||
[ExternalSecret]: https://external-secrets.io/latest/api/externalsecret/
|
||||
|
||||
@@ -15,32 +15,22 @@ import ComponentSequence from '@site/src/diagrams/render-component-sequence.mdx'
|
||||
|
||||
## Overview
|
||||
|
||||
One of the first exercises we do when learning a new programming language is
|
||||
printing out a "Hello World!" greeting. Hello Holos configures the [podinfo Helm
|
||||
chart][podinfo] producing a similar greeting from a Kubernetes Service.
|
||||
Like a traditional "Hello World" program, we'll start by configuring the
|
||||
[podinfo Helm chart][podinfo] to output a greeting from a Kubernetes Service.
|
||||
This introduces the core concept of wrapping Helm charts as Holos Components.
|
||||
|
||||
By the end of this tutorial you have an understanding of how to wrap a Helm
|
||||
Chart as a Holos Component.
|
||||
## Implementation
|
||||
|
||||
## The Code
|
||||
### Initialize Platform Structure
|
||||
|
||||
### Generating the structure
|
||||
|
||||
Use `holos` to generate a minimal platform directory structure. Start by
|
||||
creating a blank directory to hold the platform configuration.
|
||||
Create and initialize a minimal platform:
|
||||
|
||||
```shell
|
||||
mkdir holos-tutorial && cd holos-tutorial
|
||||
```
|
||||
|
||||
Use the `holos init platform` command to initialize a minimal platform in the
|
||||
blank directory.
|
||||
|
||||
```shell
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
|
||||
Here's the filesystem tree we'll build in this tutorial.
|
||||
The resulting directory structure:
|
||||
|
||||
<Tabs groupId="80D04C6A-BC83-44D0-95CC-CE01B439B159">
|
||||
<TabItem value="tree" label="Tree">
|
||||
@@ -104,10 +94,9 @@ initialization.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Creating a component
|
||||
### Create the Component
|
||||
|
||||
Start by creating a directory for the `podinfo` component. Create an empty file
|
||||
and then add the following CUE configuration to it.
|
||||
Configure the `podinfo` component:
|
||||
|
||||
```bash
|
||||
mkdir -p components/podinfo
|
||||
@@ -145,20 +134,19 @@ EOF
|
||||
```
|
||||
|
||||
:::important
|
||||
CUE loads all of `*.cue` files in the component directory to define component,
|
||||
similar to Go packages.
|
||||
Like Go packages, CUE loads all `*.cue` files in the component directory to
|
||||
define the component.
|
||||
:::
|
||||
|
||||
:::note
|
||||
CUE _also_ loads all `*.cue` files from the component leaf directory to the
|
||||
platform root directory. In this example, `#Helm` on line 6 is defined in
|
||||
`schema.cue` at the root.
|
||||
CUE recursively loads `*.cue` files from the component directory up to the
|
||||
platform root. For example, `#Helm` referenced on line 6 is defined in
|
||||
root-level `schema.cue`.
|
||||
:::
|
||||
|
||||
### Integrating the component
|
||||
### Add to Platform
|
||||
|
||||
Integrate the `podinfo` component into the platform by creating a new CUE file
|
||||
in the `platform` directory with the following content.
|
||||
Register the `podinfo` component in `platform/podinfo.cue`:
|
||||
|
||||
```bash
|
||||
cat <<EOF > platform/podinfo.cue
|
||||
@@ -178,19 +166,17 @@ EOF
|
||||
```
|
||||
|
||||
:::tip
|
||||
Component parameters may have any name as long as they don't start with
|
||||
`holos_`.
|
||||
Parameter names are unrestricted, except for the reserved `holos_` prefix.
|
||||
:::
|
||||
|
||||
## Rendering manifests
|
||||
## Generate Manifests
|
||||
|
||||
Render a manifest for `podinfo` using the `holos render platform ./platform`
|
||||
command. The `platform/` directory is the main entrypoint for this command.
|
||||
Render the `podinfo` configuration:
|
||||
|
||||
<Tabs groupId="E150C802-7162-4FBF-82A7-77D9ADAEE847">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
@@ -202,10 +188,7 @@ rendered platform in 1.938759417s
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::important
|
||||
Holos rendered the following manifest file by executing `helm template` after
|
||||
caching `podinfo` locally.
|
||||
:::
|
||||
Holos executes `helm template` with locally cached charts to generate:
|
||||
|
||||
```txt
|
||||
deploy/components/podinfo/podinfo.gen.yaml
|
||||
@@ -348,21 +331,24 @@ grep -B2 Hello deploy/components/podinfo/podinfo.gen.yaml
|
||||
|
||||
## Breaking it down
|
||||
|
||||
We run `holos render platform ./platform` because the CUE files in the platform
|
||||
directory export a [Platform] resource to `holos`. The platform directory is
|
||||
the entrypoint to the platform rendering process.
|
||||
We run `holos render platform` because the CUE files in the platform directory
|
||||
export a [Platform] resource to `holos`.
|
||||
|
||||
Components are the building blocks for a Platform. The `platform/podinfo.cue`
|
||||
file integrates the `podinfo` Component with the Platform.
|
||||
:::important
|
||||
The `platform/` directory is the default entry point to the platform rendering
|
||||
process. Override with `--platform <dir>`.
|
||||
:::
|
||||
|
||||
Holos requires two fields to integrate a component with the platform.
|
||||
Components are the building blocks of a Platform. The `platform/podinfo.cue`
|
||||
file integrates the `podinfo` component with the Platform.
|
||||
|
||||
Holos requires two fields to integrate a component with the platform:
|
||||
|
||||
1. A unique name for the component.
|
||||
2. The component path to the directory containing the CUE files exporting a
|
||||
2. The component path to the directory containing the CUE files that export a
|
||||
`BuildPlan` defining the component.
|
||||
|
||||
Component parameters are optional. They allow re-use of the same component.
|
||||
Refer to the [Component Parameters] topic for more information.
|
||||
Component parameters are optional and allow re-use of the same component.
|
||||
|
||||
<Tabs groupId="67C1EE71-3EA8-4568-9F6D-0072BA09FF12">
|
||||
<TabItem value="overview" label="Rendering Overview">
|
||||
@@ -379,12 +365,12 @@ Refer to the [Component Parameters] topic for more information.
|
||||
|
||||
## Next Steps
|
||||
|
||||
We've shown how to integrate one Helm chart to the Platform, but we haven't yet
|
||||
covered multiple Helm charts. Continue on with the next tutorial to learn how
|
||||
Holos makes it easy to inject values into multiple components safely and easily.
|
||||
We've shown how to integrate one Helm chart into the Platform, but we haven't
|
||||
yet covered multiple Helm charts. Continue with the next tutorial to learn how
|
||||
Holos makes it easy to inject values into multiple components safely and
|
||||
efficiently.
|
||||
|
||||
[podinfo]: https://github.com/stefanprodan/podinfo
|
||||
[CUE Module]: https://cuelang.org/docs/reference/modules/
|
||||
[CUE Tags]: https://cuelang.org/docs/howto/inject-value-into-evaluation-using-tag-attribute/
|
||||
[Platform]: ../api/author.md#Platform
|
||||
[Component Parameters]: ../topics/component-parameters.mdx
|
||||
|
||||
@@ -7,6 +7,8 @@ sidebar_position: 40
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import YouTube from '@site/src/components/YouTube';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
<head>
|
||||
<meta property="og:title" content="Helm Values | Holos" />
|
||||
@@ -17,260 +19,176 @@ import TabItem from '@theme/TabItem';
|
||||
|
||||
## Overview
|
||||
|
||||
Holos makes it easier to integrate multiple Helm charts together. Holos adds
|
||||
valuable capabilities to Helm and Kustomize.
|
||||
Holos simplifies integrating multiple Helm charts by adding valuable
|
||||
capabilities to Helm and Kustomize:
|
||||
|
||||
1. Inject the same value into two or more charts to integrate them safer than Helm alone.
|
||||
2. Add strong type checking and validation of constraints for Helm input values.
|
||||
3. Implementation of the [rendered manifests pattern].
|
||||
1. Inject the same value into multiple charts more safely than using Helm alone.
|
||||
2. Add strong type checking and validation for Helm input values.
|
||||
3. Implement the [rendered manifests pattern].
|
||||
|
||||
We'll manage the [prometheus] and [blackbox] Helm Charts in this tutorial.
|
||||
Unfortunately, the upstream `values.yaml` files are misconfigured by default.
|
||||
Prometheus tries to connect to Blackbox at the wrong host and port.
|
||||
In this tutorial, we'll manage the [prometheus] and [blackbox] Helm charts. By
|
||||
default, the upstream `values.yaml` files are misconfigured, causing Prometheus
|
||||
to connect to Blackbox at the wrong host and port.
|
||||
|
||||
:::tip
|
||||
Holos and CUE makes it easy to fix this problem by integrating them correctly.
|
||||
The integrated charts will stay in lock step over time.
|
||||
:::
|
||||
## The Video
|
||||
|
||||
The video below enhances this tutorial by offering greater detail on the issue
|
||||
of poorly integrated Helm charts and the solution we've provided. If you're
|
||||
looking for a deeper explanation of the code being presented, this video is a great
|
||||
resource.
|
||||
|
||||
{/* cspell:disable-next-line */}
|
||||
<YouTube id="PSdceGlhHGo"/>
|
||||
|
||||
## The Code
|
||||
|
||||
### Holos Version
|
||||
|
||||
Ensure you have a current version of `holos` installed. This document was
|
||||
tested with the following version.
|
||||
|
||||
import HolosVersionCommand from '!!raw-loader!../_markdown-tests/script-01-holos-version/command.sh';
|
||||
import HolosVersionOutput from '!!raw-loader!../_markdown-tests/script-01-holos-version/output.txt';
|
||||
|
||||
<CodeBlock language="bash">{HolosVersionCommand}</CodeBlock>
|
||||
<CodeBlock language="txt">{HolosVersionOutput}</CodeBlock>
|
||||
|
||||
### Generating the structure
|
||||
|
||||
Use `holos` to generate a minimal platform directory structure. First, create
|
||||
and cd into a blank directory. Then use the `holos init platform` command.
|
||||
Use `holos` to generate a minimal platform directory structure. First, create
|
||||
and navigate into a blank directory, then use the `holos init platform` command:
|
||||
|
||||
```shell
|
||||
mkdir holos-helm-values-tutorial
|
||||
cd holos-helm-values-tutorial
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
import MkdirAndInit from '!!raw-loader!../_markdown-tests/script-02-helm-values/mkdir.and.init.sh';
|
||||
|
||||
Make a commit to track changes.
|
||||
<CodeBlock language="bash">{MkdirAndInit}</CodeBlock>
|
||||
|
||||
```bash
|
||||
git init . && git add . && git commit -m initial
|
||||
```
|
||||
Make an initial commit to track changes:
|
||||
|
||||
import GitInit from '!!raw-loader!../_markdown-tests/script-02-helm-values/git.init.sh';
|
||||
|
||||
<CodeBlock language="bash">{GitInit}</CodeBlock>
|
||||
|
||||
### Managing the Components
|
||||
|
||||
Create the `prometheus` and `blackbox` component directories, then add each of
|
||||
the following file contents.
|
||||
|
||||
```bash
|
||||
mkdir -p components/prometheus components/blackbox
|
||||
```
|
||||
import MkdirComponents from '!!raw-loader!../_markdown-tests/script-02-helm-values/mkdir.components.sh';
|
||||
import PrometheusComponentHeader from '!!raw-loader!../_markdown-tests/script-02-helm-values/prometheus.component.header.sh';
|
||||
import PrometheusComponentBody from '!!raw-loader!../_markdown-tests/script-02-helm-values/prometheus.component.body.cue';
|
||||
import BlackboxComponentHeader from '!!raw-loader!../_markdown-tests/script-02-helm-values/blackbox.component.header.sh';
|
||||
import BlackboxComponentBody from '!!raw-loader!../_markdown-tests/script-02-helm-values/blackbox.component.body.cue';
|
||||
import EofTrailer from '!!raw-loader!../_markdown-tests/script-02-helm-values/eof.trailer.sh';
|
||||
|
||||
|
||||
<CodeBlock language="bash">{MkdirComponents}</CodeBlock>
|
||||
|
||||
<Tabs groupId="D15A3008-1EFC-4D34-BED1-15BC0C736CC3">
|
||||
<TabItem value="prometheus.cue" label="prometheus.cue">
|
||||
```bash
|
||||
cat <<EOF > components/prometheus/prometheus.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: Helm.BuildPlan
|
||||
|
||||
Helm: #Helm & {
|
||||
Chart: {
|
||||
name: "prometheus"
|
||||
version: "25.27.0"
|
||||
repository: {
|
||||
name: "prometheus-community"
|
||||
url: "https://prometheus-community.github.io/helm-charts"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
<CodeBlock language="bash">{PrometheusComponentHeader}</CodeBlock>
|
||||
<CodeBlock language="cue" showLineNumbers>{PrometheusComponentBody}</CodeBlock>
|
||||
<CodeBlock language="bash">{EofTrailer}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="blackbox.cue" label="blackbox.cue">
|
||||
```bash
|
||||
cat <<EOF > components/blackbox/blackbox.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: Helm.BuildPlan
|
||||
|
||||
Helm: #Helm & {
|
||||
Chart: {
|
||||
name: "prometheus-blackbox-exporter"
|
||||
version: "9.0.1"
|
||||
repository: {
|
||||
name: "prometheus-community"
|
||||
url: "https://prometheus-community.github.io/helm-charts"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
<CodeBlock language="bash">{BlackboxComponentHeader}</CodeBlock>
|
||||
<CodeBlock language="cue" showLineNumbers>{BlackboxComponentBody}</CodeBlock>
|
||||
<CodeBlock language="bash">{EofTrailer}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Integrating the Components
|
||||
### Register the Components
|
||||
|
||||
Integrate the components with the platform by adding the following file to the
|
||||
platform directory.
|
||||
Register the components with the platform by adding the following file to the platform directory.
|
||||
|
||||
```bash
|
||||
cat <<EOF > platform/prometheus.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
import RegisterComponentsHeader from '!!raw-loader!../_markdown-tests/script-02-helm-values/register.components.header.sh';
|
||||
import RegisterComponentsBody from '!!raw-loader!../_markdown-tests/script-02-helm-values/register.components.body.cue';
|
||||
|
||||
Platform: Components: {
|
||||
prometheus: {
|
||||
name: "prometheus"
|
||||
path: "components/prometheus"
|
||||
}
|
||||
blackbox: {
|
||||
name: "blackbox"
|
||||
path: "components/blackbox"
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
<CodeBlock language="bash">{RegisterComponentsHeader}</CodeBlock>
|
||||
<CodeBlock language="cue" showLineNumbers>{RegisterComponentsBody}</CodeBlock>
|
||||
<CodeBlock language="bash">{EofTrailer}</CodeBlock>
|
||||
|
||||
Render the platform.
|
||||
|
||||
import RenderCommand from '!!raw-loader!../_markdown-tests/script-02-helm-values/render.sh';
|
||||
import RegisterComponentsRenderOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/register.components.output.txt';
|
||||
|
||||
<Tabs groupId="33D6BFED-62D8-4A42-A26A-F3121D57C4E5">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
<CodeBlock language="bash">{RenderCommand}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
cached prometheus-blackbox-exporter 9.0.1
|
||||
rendered blackbox in 3.825430417s
|
||||
cached prometheus 25.27.0
|
||||
rendered prometheus in 4.840089667s
|
||||
rendered platform in 4.840137792s
|
||||
```
|
||||
<CodeBlock language="txt">{RegisterComponentsRenderOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Commit the results.
|
||||
|
||||
import GitCommitRegisterComponents from '!!raw-loader!../_markdown-tests/script-02-helm-values/register.components.git.commit.sh';
|
||||
import RegisterComponentsGitOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/register.components.git.commit.output.txt';
|
||||
|
||||
<Tabs groupId="446CC550-A634-45C0-BEC7-992E5C56D4FA">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add . && git commit -m 'add blackbox and prometheus'
|
||||
```
|
||||
<CodeBlock language="bash">{GitCommitRegisterComponents}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main b5df111] add blackbox and prometheus
|
||||
5 files changed, 1550 insertions(+)
|
||||
create mode 100644 components/blackbox/blackbox.cue
|
||||
create mode 100644 components/prometheus/prometheus.cue
|
||||
create mode 100644 deploy/components/blackbox/blackbox.gen.yaml
|
||||
create mode 100644 deploy/components/prometheus/prometheus.gen.yaml
|
||||
create mode 100644 platform/prometheus.cue
|
||||
```
|
||||
<CodeBlock language="txt">{RegisterComponentsGitOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Importing Helm Values
|
||||
|
||||
Holos renders the helm charts with their default values. We can import these
|
||||
default values into CUE so we can easily work with them as structured data
|
||||
instead of text markup.
|
||||
Holos renders Helm charts with their default values. We can import these default
|
||||
values into CUE to work with them as structured data instead of text markup.
|
||||
|
||||
```bash
|
||||
holos cue import \
|
||||
--package holos \
|
||||
--path 'Helm: Values:' \
|
||||
--outfile components/prometheus/values.cue \
|
||||
components/prometheus/vendor/25.27.0/prometheus/values.yaml
|
||||
```
|
||||
import ImportPrometheusValues from '!!raw-loader!../_markdown-tests/script-02-helm-values/import.prometheus.values.sh';
|
||||
import ImportBlackboxValues from '!!raw-loader!../_markdown-tests/script-02-helm-values/import.blackbox.values.sh';
|
||||
|
||||
```bash
|
||||
holos cue import \
|
||||
--package holos \
|
||||
--path 'Helm: Values:' \
|
||||
--outfile components/blackbox/values.cue \
|
||||
components/blackbox/vendor/9.0.1/prometheus-blackbox-exporter/values.yaml
|
||||
```
|
||||
<CodeBlock language="bash">{ImportPrometheusValues}</CodeBlock>
|
||||
<CodeBlock language="bash">{ImportBlackboxValues}</CodeBlock>
|
||||
|
||||
These commands convert the YAML data into CUE code and nest the values under the
|
||||
`Values` field of the `Helm` struct.
|
||||
|
||||
:::important
|
||||
CUE unifies `values.cue` with the other `*.cue` files in the same directory.
|
||||
CUE unifies `values.cue` with the other `\*.cue` files in the same directory.
|
||||
:::
|
||||
|
||||
Render the platform and commit the results.
|
||||
Render the platform using `holos render platform` and commit the results.
|
||||
|
||||
import ImportValuesRenderOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/import.values.render.output.txt';
|
||||
import ImportValuesGitCommit from '!!raw-loader!../_markdown-tests/script-02-helm-values/import.values.git.commit.sh';
|
||||
import ImportValuesGitOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/import.values.git.output.txt';
|
||||
|
||||
<Tabs groupId="BDDCD65A-2E9D-4BA6-AAE2-8099494D5E4B">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
<CodeBlock language="bash">{RenderCommand}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered blackbox in 365.936792ms
|
||||
rendered prometheus in 371.855875ms
|
||||
rendered platform in 372.109916ms
|
||||
```
|
||||
<CodeBlock language="txt">{ImportValuesRenderOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="1636C619-258E-4D49-8052-F64B588C9177">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add . && git commit -m 'import values'
|
||||
```
|
||||
<CodeBlock language="bash">{ImportValuesGitCommit}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main 52e90ea] import values
|
||||
2 files changed, 1815 insertions(+)
|
||||
create mode 100644 components/blackbox/values.cue
|
||||
create mode 100644 components/prometheus/values.cue
|
||||
```
|
||||
<CodeBlock language="txt">{ImportValuesGitOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Managing Common Configuration
|
||||
|
||||
Define a structure to hold the configuration values we want both helm charts to
|
||||
use. We add this configuration to the `components` directory so it's in scope
|
||||
for all components.
|
||||
To manage shared configuration for both Helm charts, define a structure that
|
||||
holds the common configuration values. Place this configuration in the
|
||||
`components` directory to ensure it is accessible to all components.
|
||||
|
||||
```bash
|
||||
cat <<EOF > components/blackbox.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
import BlackboxCommonConfigHeader from '!!raw-loader!../_markdown-tests/script-02-helm-values/blackbox.common.config.header.sh';
|
||||
import BlackboxCommonConfigBody from '!!raw-loader!../_markdown-tests/script-02-helm-values/blackbox.common.config.body.cue';
|
||||
|
||||
// Schema Definition
|
||||
#Blackbox: {
|
||||
// host constrained to a lower case dns label
|
||||
host: string & =~"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"
|
||||
// port constrained to a valid range
|
||||
port: int & >0 & <=65535
|
||||
}
|
||||
|
||||
// Concrete values must validate against the schema.
|
||||
Blackbox: #Blackbox & {
|
||||
host: "blackbox"
|
||||
port: 9115
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
<CodeBlock language="bash">{BlackboxCommonConfigHeader}</CodeBlock>
|
||||
<CodeBlock language="cue" showLineNumbers>{BlackboxCommonConfigBody}</CodeBlock>
|
||||
<CodeBlock language="bash" showLineNumbers>{EofTrailer}</CodeBlock>
|
||||
|
||||
:::important
|
||||
1. CUE loads and unifies all `*.cue` files from the root directory containing
|
||||
@@ -281,75 +199,39 @@ languages with only type checking.
|
||||
|
||||
Add and commit the configuration.
|
||||
|
||||
import BlackboxCommonConfigGit from '!!raw-loader!../_markdown-tests/script-02-helm-values/blackbox.common.config.git.commit.sh';
|
||||
import BlackboxCommonConfigGitOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/blackbox.common.config.git.output.txt';
|
||||
|
||||
<Tabs groupId="A738CCE4-F0C6-4CC7-BE1F-2B92F0E86FDC">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add . && git commit -m 'add blackbox configuration'
|
||||
```
|
||||
<CodeBlock language="bash">{BlackboxCommonConfigGit}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main 1adcd08] add blackbox configuration
|
||||
1 file changed, 15 insertions(+)
|
||||
create mode 100644 components/blackbox.cue
|
||||
```
|
||||
<CodeBlock language="bash">{BlackboxCommonConfigGitOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Referring to Common Configuration
|
||||
### Using Common Configuration Across Components
|
||||
|
||||
Referencing common configuration from multiple components is easy and safe with
|
||||
Holos and CUE.
|
||||
Referencing common configuration across multiple components is straightforward
|
||||
and reliable using Holos and CUE.
|
||||
|
||||
Patch the two `values.cue` files, or edit them by hand, to reference
|
||||
`Blackbox.host` and `Blackbox.port`.
|
||||
To apply the common configuration, patch the two `values.cue` files, or manually
|
||||
edit them to reference `Blackbox.host` and `Blackbox.port`.
|
||||
|
||||
import CommonConfigPatchCommand from '!!raw-loader!../_markdown-tests/script-02-helm-values/common.config.patch.sh';
|
||||
import CommonConfigPatchDiff from '!!raw-loader!../_markdown-tests/script-02-helm-values/values.patch';
|
||||
import CommonConfigPatchOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/common.config.patch.txt';
|
||||
|
||||
<Tabs groupId="5FFCE892-B8D4-4F5B-B2E2-39EC9E9F87A4">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
patch -p1 < values.patch
|
||||
```
|
||||
<CodeBlock language="bash">{CommonConfigPatchCommand}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="patch" label="values.patch">
|
||||
```diff
|
||||
--- a/components/blackbox/values.cue
|
||||
+++ b/components/blackbox/values.cue
|
||||
@@ -1,6 +1,8 @@
|
||||
package holos
|
||||
|
||||
Helm: Values: {
|
||||
+ fullnameOverride: Blackbox.host
|
||||
+
|
||||
global: {
|
||||
//# Global image registry to use if it needs to be overriden for some specific use cases (e.g local registries, custom images, ...)
|
||||
//#
|
||||
@@ -192,7 +194,7 @@ Helm: Values: {
|
||||
annotations: {}
|
||||
labels: {}
|
||||
type: "ClusterIP"
|
||||
- port: 9115
|
||||
+ port: Blackbox.port
|
||||
ipDualStack: {
|
||||
enabled: false
|
||||
ipFamilies: ["IPv6", "IPv4"]
|
||||
--- a/components/prometheus/values.cue
|
||||
+++ b/components/prometheus/values.cue
|
||||
@@ -1083,7 +1083,7 @@ Helm: Values: {
|
||||
target_label: "__param_target"
|
||||
}, {
|
||||
target_label: "__address__"
|
||||
- replacement: "blackbox"
|
||||
+ replacement: "\(Blackbox.host):\(Blackbox.port)"
|
||||
}, {
|
||||
source_labels: ["__param_target"]
|
||||
target_label: "instance"
|
||||
```
|
||||
<CodeBlock language="diff">{CommonConfigPatchDiff}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
patching file 'components/blackbox/values.cue'
|
||||
patching file 'components/prometheus/values.cue'
|
||||
```
|
||||
<CodeBlock language="txt">{CommonConfigPatchOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -360,160 +242,86 @@ safely and easily.
|
||||
|
||||
Remove the patch file, then commit the changes.
|
||||
|
||||
import CommonConfigPatchRm from '!!raw-loader!../_markdown-tests/script-02-helm-values/common.config.rm.sh';
|
||||
import CommonConfigPatchGitCommit from '!!raw-loader!../_markdown-tests/script-02-helm-values/common.config.git.sh';
|
||||
import CommonConfigPatchGitCommitOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/common.config.git.output.txt';
|
||||
|
||||
<Tabs groupId="6498B00E-FADA-4EB2-885C-808F1D22E04D">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
rm values.patch
|
||||
```
|
||||
```bash
|
||||
git add . && git commit -m 'integrate blackbox and prometheus together'
|
||||
```
|
||||
<CodeBlock language="bash">{CommonConfigPatchRm}</CodeBlock>
|
||||
<CodeBlock language="bash">{CommonConfigPatchGitCommit}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main 4221803] integrate blackbox and prometheus together
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
```
|
||||
<CodeBlock language="txt">{CommonConfigPatchGitCommitOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Reviewing Changes
|
||||
|
||||
Holos makes it easy to see and review platform wide changes. Render the
|
||||
platform to see how both prometheus and blackbox change in lock step.
|
||||
Holos makes it easy to view and review platform-wide changes. Render the
|
||||
platform to observe how both Prometheus and Blackbox update in sync.
|
||||
|
||||
import ReviewingChangesRenderOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/reviewing.changes.render.output.txt';
|
||||
|
||||
<Tabs groupId="E7F6D8B1-22FA-4075-9B44-D9F2815FE0D3">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
<CodeBlock language="bash">{RenderCommand}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered blackbox in 374.810666ms
|
||||
rendered prometheus in 382.899334ms
|
||||
rendered platform in 383.270625ms
|
||||
```
|
||||
<CodeBlock language="txt">{ReviewingChangesRenderOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Changes are easily visible with version control.
|
||||
Changes are easily visible in version control.
|
||||
|
||||
import GitDiffCommand from '!!raw-loader!../_markdown-tests/script-02-helm-values/git.diff.sh';
|
||||
import GitDiff from '!!raw-loader!../_markdown-tests/script-02-helm-values/git.diff';
|
||||
|
||||
<Tabs groupId="9789A0EF-24D4-4FB9-978A-3895C2778789">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git diff
|
||||
```
|
||||
<CodeBlock language="bash">{GitDiffCommand}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```diff
|
||||
diff --git a/deploy/components/blackbox/blackbox.gen.yaml b/deploy/components/blackbox/blackbox.gen.yaml
|
||||
index 3db20cd..5336f44 100644
|
||||
--- a/deploy/components/blackbox/blackbox.gen.yaml
|
||||
+++ b/deploy/components/blackbox/blackbox.gen.yaml
|
||||
@@ -7,7 +7,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -31,7 +31,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -43,7 +43,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
spec:
|
||||
ports:
|
||||
@@ -65,7 +65,7 @@ metadata:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/version: v0.25.0
|
||||
helm.sh/chart: prometheus-blackbox-exporter-9.0.1
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
@@ -119,8 +119,8 @@ spec:
|
||||
name: config
|
||||
hostNetwork: false
|
||||
restartPolicy: Always
|
||||
- serviceAccountName: prometheus-blackbox-exporter
|
||||
+ serviceAccountName: blackbox
|
||||
volumes:
|
||||
- configMap:
|
||||
- name: prometheus-blackbox-exporter
|
||||
+ name: blackbox
|
||||
name: config
|
||||
diff --git a/deploy/components/prometheus/prometheus.gen.yaml b/deploy/components/prometheus/prometheus.gen.yaml
|
||||
index 9e02bce..ab638f0 100644
|
||||
--- a/deploy/components/prometheus/prometheus.gen.yaml
|
||||
+++ b/deploy/components/prometheus/prometheus.gen.yaml
|
||||
@@ -589,7 +589,7 @@ data:
|
||||
- source_labels:
|
||||
- __address__
|
||||
target_label: __param_target
|
||||
- - replacement: blackbox
|
||||
+ - replacement: blackbox:9115
|
||||
target_label: __address__
|
||||
- source_labels:
|
||||
- __param_target
|
||||
|
||||
```
|
||||
<CodeBlock language="diff">{GitDiff}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
From the diff we know this change will:
|
||||
From the diff, we can see this change will:
|
||||
|
||||
1. Reconfigure the blackbox exporter host from `prometheus-blackbox-exporter` to `blackbox`.
|
||||
2. Have no effect on the blackbox service port. It was already using the default 9115.
|
||||
3. Reconfigure prometheus to query the blackbox exporter at the correct host and
|
||||
port, `blackbox:9115`.
|
||||
1. Reconfigure the Blackbox Exporter host from `prometheus-blackbox-exporter` to `blackbox`.
|
||||
2. Have no effect on the Blackbox service port, as it was already using the default `9115`.
|
||||
3. Reconfigure Prometheus to query the Blackbox Exporter at the correct host and port, `blackbox:9115`.
|
||||
|
||||
Without this change prometheus incorrectly assumed blackbox was listening at
|
||||
Without this change, Prometheus incorrectly assumed Blackbox was listening at
|
||||
`blackbox` on port `80` when it was actually listening at
|
||||
`prometheus-blackbox-exporter` port `9115`. Going forward, changing the
|
||||
blackbox host or port will reconfigure both charts correctly.
|
||||
`prometheus-blackbox-exporter` on port `9115`. Going forward, changing the
|
||||
Blackbox host or port will reconfigure both charts correctly.
|
||||
|
||||
Commit the changes and move on to deploying them.
|
||||
Commit the changes and proceed to deploy them.
|
||||
|
||||
import ReviewingChangesGitCommit from '!!raw-loader!../_markdown-tests/script-02-helm-values/reviewing.changes.git.commit.sh';
|
||||
import ReviewingChangesGitOutput from '!!raw-loader!../_markdown-tests/script-02-helm-values/reviewing.changes.git.output.txt';
|
||||
|
||||
<Tabs groupId="F8C9A98D-DE1E-4EF6-92C1-017A9166F6C7">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add . && git commit -m 'render integrated blackbox and prometheus manifests'
|
||||
```
|
||||
<CodeBlock language="bash">{ReviewingChangesGitCommit}</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main 67efe0d] render integrated blackbox and prometheus manifests
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
```
|
||||
<CodeBlock language="txt">{ReviewingChangesGitOutput}</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Trying Locally
|
||||
|
||||
Optionally apply the manifests Holos rendered to a [Local Cluster].
|
||||
Optionally, apply the manifests rendered by Holos to a [Local Cluster].
|
||||
|
||||
## Next Steps
|
||||
|
||||
In this tutorial we learned how Holos makes it easier to holistically integrate
|
||||
the [prometheus] and [blackbox] charts so they're configured in lock step with
|
||||
each other. If we relied on Helm alone, there is no good way to configure both
|
||||
charts to use the same service endpoint.
|
||||
In this tutorial, we learned how Holos simplifies the holistic integration of
|
||||
the [prometheus] and [blackbox] charts, ensuring they are configured
|
||||
consistently. By using Holos, we overcome the limitations of relying solely on
|
||||
Helm, which lacks an effective method to configure both charts to use the same
|
||||
service endpoint.
|
||||
|
||||
[rendered manifests pattern]: https://akuity.io/blog/the-rendered-manifests-pattern
|
||||
[prometheus]: https://github.com/prometheus-community/helm-charts/tree/prometheus-25.27.0/charts/prometheus
|
||||
|
||||
@@ -12,14 +12,14 @@ import TabItem from '@theme/TabItem';
|
||||
|
||||
## Overview
|
||||
|
||||
In the previous tutorial we learned how Holos makes it easier to holistically
|
||||
integrate the [prometheus] and [blackbox] charts so they're configured in lock
|
||||
step with each other.
|
||||
In the previous tutorial, we learned how Holos simplifies the holistic
|
||||
integration of the [prometheus] and [blackbox] charts, ensuring they are
|
||||
configured in sync.
|
||||
|
||||
This tutorial goes further by integrating the [httpbin] service with prometheus
|
||||
and blackbox to automatically probe for availability.
|
||||
In this tutorial, we'll go a step further by integrating the [httpbin] service
|
||||
with Prometheus and Blackbox to automatically probe for availability.
|
||||
|
||||
We'll explore how Holos manages [kustomize] bases similar to the Helm kind
|
||||
We'll also explore how Holos manages [kustomize] bases, similar to the Helm kind
|
||||
covered in the [Helm Values] tutorial.
|
||||
|
||||
## The Code
|
||||
@@ -34,8 +34,10 @@ Otherwise click the **Generate** tab to generate a blank platform now.
|
||||
:::
|
||||
</TabItem>
|
||||
<TabItem value="generate" label="Generate">
|
||||
Use `holos` to generate a minimal platform directory structure. First, create
|
||||
and cd into a blank directory. Then use the `holos init platform` command.
|
||||
|
||||
Use `holos` to generate a minimal platform directory structure. First, create
|
||||
and navigate into a blank directory. Then, run the `holos init platform`
|
||||
command.
|
||||
|
||||
```shell
|
||||
mkdir holos-kustomize-tutorial
|
||||
@@ -54,8 +56,8 @@ git init . && git add . && git commit -m initial
|
||||
|
||||
### Managing the Component
|
||||
|
||||
Create the `httpbin` component directory and add the `httpbin.cue` and
|
||||
`httpbin.yaml` files to it.
|
||||
Create the `httpbin` component directory, and add the `httpbin.cue` and
|
||||
`httpbin.yaml` files to it for configuration and setup.
|
||||
|
||||
<Tabs groupId="800C3AE7-E7F8-4AFC-ABF1-6AFECD945958">
|
||||
<TabItem value="setup" label="Setup">
|
||||
@@ -154,9 +156,9 @@ EOF
|
||||
Holos knows the `httpbin.yaml` file is part of the BuildPlan because of the
|
||||
`KustomizeConfig: Files: "httpbin.yaml": _` line in the `httpbin.cue`.
|
||||
|
||||
### Integrating the Components
|
||||
### Register the Components
|
||||
|
||||
Integrate `httpbin` with the platform by adding the following file to the
|
||||
Register `httpbin` with the platform by adding the following file to the
|
||||
platform directory.
|
||||
|
||||
```bash
|
||||
@@ -181,7 +183,7 @@ Render the platform.
|
||||
<Tabs groupId="B120D5D1-0EAB-41E0-AD21-15526EBDD53D">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
@@ -212,10 +214,10 @@ git add . && git commit -m 'add httpbin'
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Inspecting the BuildPlan
|
||||
### Inspecting the Build Plan
|
||||
|
||||
We can see the [BuildPlan] exported to `holos` by the `holos:
|
||||
Kustomize.BuildPlan` line in `httpbin.cue`. Holos processes this build plan to
|
||||
Kustomize.BuildPlan` line in `httpbin.cue`. Holos processes this build plan to
|
||||
produce the fully rendered manifests.
|
||||
|
||||
<Tabs groupId="DD697D65-5BEC-4B92-BB33-59BE4FEC112F">
|
||||
@@ -270,19 +272,21 @@ source:
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Transforming manifests
|
||||
### Transforming Manifests
|
||||
|
||||
Reviewing the BuildPlan exported in the previous command:
|
||||
Review the BuildPlan exported in the previous command:
|
||||
|
||||
1. The [File Generator] copies the plain `httpbin.yaml` file into the build.
|
||||
2. The [Kustomize Transformer] uses `httpbin.yaml` as an input resource.
|
||||
3. The final artifact is the output from Kustomize.
|
||||
|
||||
This BuildPlan transforms the raw yaml by labeling all of the resources with
|
||||
This BuildPlan transforms the raw YAML by labeling all of the resources with
|
||||
`"app.kubernetes.io/name": "httpbin"` using the [KustomizeConfig] `CommonLabels`
|
||||
field. We still need to integrate `httpbin` with `prometheus`. Annotate the
|
||||
Service with `prometheus.io/probe: "true"` to complete the integration. Holos
|
||||
makes this easier with CUE. We don't need to edit any yaml files.
|
||||
field.
|
||||
|
||||
To complete the integration with Prometheus, annotate the Service with
|
||||
`prometheus.io/probe: "true"`. Holos makes this easier with CUE, so there's no
|
||||
need to edit any YAML files manually.
|
||||
|
||||
Add a new `patches.cue` file to the `httpbin` component with the following
|
||||
content.
|
||||
@@ -324,7 +328,7 @@ Render the platform to see the result of the kustomization patch.
|
||||
<Tabs groupId="5D1812DD-8E7B-4F97-B349-275214F38B6E">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
@@ -382,17 +386,19 @@ git add . && git commit -m 'annotate httpbin for prometheus probes'
|
||||
|
||||
## Trying Locally
|
||||
|
||||
Optionally apply the manifests Holos rendered to a [Local Cluster].
|
||||
Optionally, apply the manifests rendered by Holos to a [Local Cluster] for
|
||||
testing and validation.
|
||||
|
||||
## Next Steps
|
||||
|
||||
We learned how Holos makes it easier to manage [httpbin], distributed as a
|
||||
Kustomize base, using a kustomize Component similar to the helm component we saw
|
||||
previously. Holos offers a clear way to kustomize any component, patching an
|
||||
annotation onto the `httpbin` Service in this example.
|
||||
In this tutorial, we learned how Holos simplifies managing [httpbin], which is
|
||||
distributed as a Kustomize base. We used a Kustomize component similar to the
|
||||
Helm component covered previously. Holos provides a straightforward way to
|
||||
customize any component, demonstrated by patching an annotation onto the
|
||||
`httpbin` Service.
|
||||
|
||||
Continue on with the tutorial to explore how Holos makes it easier to manage
|
||||
certificates and make services accessible outside of a cluster.
|
||||
Continue with the tutorial to learn how Holos facilitates certificate management
|
||||
and makes services accessible outside of a cluster.
|
||||
|
||||
[httpbin]: https://github.com/mccutchen/go-httpbin/tree/v2.15.0
|
||||
[prometheus]: https://github.com/prometheus-community/helm-charts/tree/prometheus-25.27.0/charts/prometheus
|
||||
|
||||
@@ -6,68 +6,71 @@ sidebar_position: 10
|
||||
---
|
||||
|
||||
import RenderingOverview from '@site/src/diagrams/rendering-overview.mdx';
|
||||
import YouTube from '@site/src/components/YouTube';
|
||||
|
||||
# Tutorial
|
||||
|
||||
## Overview
|
||||
|
||||
Holos is a configuration management tool for Kubernetes resources. It provides
|
||||
the building blocks needed for implementing the [rendered manifests pattern].
|
||||
It gives the flexibility to manage a wide range of configurations, from large
|
||||
software delivery platforms spanning multiple clusters and regions to generating
|
||||
a single resource on your local device.
|
||||
Holos is a configuration management tool for Kubernetes implementing the
|
||||
[rendered manifests pattern]. It handles configurations ranging from single
|
||||
resources to multi-cluster platforms across regions.
|
||||
|
||||
{/* truncate */}
|
||||
|
||||
At a high level, Holos provides a few major components:
|
||||
|
||||
- A Platform schema for specifying how components integrate together into a platform.
|
||||
- Component building blocks for Helm, Kustomize, and Kubernetes to unify configuration with CUE.
|
||||
- A BuildPlan orchestrating generators, transformers, and validators to produce manifest files.
|
||||
Key components:
|
||||
- Platform schemas defining component integration
|
||||
- Building blocks unifying Helm, Kustomize and Kubernetes configs with CUE
|
||||
- BuildPlan pipeline for generating, transforming and validating manifests
|
||||
|
||||
<RenderingOverview />
|
||||
|
||||
{/* TODO: Replace this with the Advantages diagram we talked about. */}
|
||||
|
||||
## Video
|
||||
|
||||
The video below offers a basic overview of Holos by walking you through the
|
||||
tooling gap at the Kubernetes integration layer and demonstrating how to
|
||||
integrate multiple Helm charts using data from CUE.
|
||||
|
||||
{/* cspell:disable-next-line */}
|
||||
<YouTube id="PSdceGlhHGo"/>
|
||||
|
||||
## Holos' role in your organization
|
||||
|
||||
Platform engineers run the `holos render platform` command locally and in CI to
|
||||
produce Kubernetes manifests which are committed to version control. GitOps
|
||||
tools like ArgoCD or Flux deploy the manifests produced by Holos.
|
||||
Platform engineers use Holos to generate Kubernetes manifests, both locally and
|
||||
in CI pipelines. The manifests are committed to version control and deployed via
|
||||
GitOps tools like ArgoCD or Flux.
|
||||
|
||||
Holos works well with your existing Helm charts, kustomize bases, and any other
|
||||
configuration data you currently store in version control.
|
||||
Holos integrates seamlessly with existing Helm charts, Kustomize bases, and
|
||||
other version-controlled configurations.
|
||||
|
||||
## Advantages of Holos
|
||||
|
||||
### Safe
|
||||
|
||||
Holos uses [CUE] to provide strong typing and constraints to configuration data.
|
||||
Additionally, holos adds strong validation to verify the output produced by Helm
|
||||
and other tools.
|
||||
Holos leverages [CUE] for strong typing and validation of configuration data,
|
||||
ensuring consistent output from Helm and other tools.
|
||||
|
||||
### Consistent
|
||||
|
||||
Holos offers a consistent way to incorporate a wide variety of tools into a well
|
||||
defined data pipeline. Configuration produced from CUE, Helm, and Kustomize are
|
||||
all handled with the same consistent process.
|
||||
A unified pipeline processes all configurations - whether from CUE, Helm, or
|
||||
Kustomize - through the same well-defined stages.
|
||||
|
||||
### Flexible
|
||||
|
||||
Holos is designed to be flexible. Holos offers flexible building blocks for
|
||||
data generation, transformation, validation, and integration. Find the perfect
|
||||
fit for your team by assembling these building blocks to your unique needs.
|
||||
Composable building blocks for generation, transformation, validation and
|
||||
integration let teams assemble workflows that match their needs.
|
||||
|
||||
Holos does not have an opinion on many common aspects of platform configuration.
|
||||
For example, environments and clusters are explicitly kept out of the core and
|
||||
instead are provided as flexible, user-customizable [topics] organized as a
|
||||
recipes.
|
||||
The core is intentionally unopinionated about platform configuration patterns.
|
||||
Common needs like environments and clusters are provided as customizable
|
||||
[topics] recipes rather than enforced structures.
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you get stuck, you can get help on [Discord] or [GitHub discussions]. Don't
|
||||
worry about asking "beginner" questions, configuration is often complex even for
|
||||
the most experienced among us. We all start somewhere and are happy to help.
|
||||
Get support through our [Discord] channel or [GitHub discussions]. Configuration
|
||||
challenges arise at all experience levels - we welcome your questions and are
|
||||
here to help.
|
||||
|
||||
[rendered manifests pattern]: https://akuity.io/blog/the-rendered-manifests-pattern
|
||||
[CUE]: https://cuelang.org/
|
||||
|
||||
@@ -11,22 +11,23 @@ import RenderPlatformDiagram from '@site/src/diagrams/render-platform-sequence.m
|
||||
|
||||
# Setup
|
||||
|
||||
## Overview
|
||||
|
||||
This tutorial will guide you through the installation of Holos and its
|
||||
dependencies, as well as the initialization of a minimal Platform that you can
|
||||
extend to meet your specific needs.
|
||||
|
||||
## Installing
|
||||
|
||||
Holos is distributed as a single file executable that can be installed in a
|
||||
couple of ways.
|
||||
Holos is a single executable that can be installed via:
|
||||
|
||||
<Tabs groupId="FE2C74C8-B3A3-4AEA-BBD3-F57FAA654B6F">
|
||||
<TabItem value="brew" label="Install with brew">
|
||||
<TabItem value="brew" label="macOS">
|
||||
```bash
|
||||
brew install holos-run/tap/holos
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="linux" label="Linux">
|
||||
Download holos from the [releases] page and place the executable into your shell
|
||||
path.
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
Download holos from the [releases] page and place the executable into your shell
|
||||
path.
|
||||
</TabItem>
|
||||
<TabItem value="go" label="Go">
|
||||
```bash
|
||||
@@ -37,8 +38,23 @@ go install github.com/holos-run/holos/cmd/holos@latest
|
||||
|
||||
### Completion
|
||||
|
||||
:::tip
|
||||
Completion is automatically enabled if [brew shell
|
||||
completion](https://docs.brew.sh/Shell-Completion) is also enabled.
|
||||
:::
|
||||
|
||||
<Tabs groupId="65F79D28-2E57-4A90-8EBA-3D8758C80233">
|
||||
<TabItem value="zsh" label="zsh">
|
||||
|
||||
Add the following to `~/.zshrc` if not already present to initialize zsh completion.
|
||||
|
||||
```bash
|
||||
autoload -Uz compinit
|
||||
compinit
|
||||
```
|
||||
|
||||
Then load holos completion after zsh completion has been initialized.
|
||||
|
||||
```bash
|
||||
source <(holos completion zsh)
|
||||
```
|
||||
@@ -60,31 +76,22 @@ holos completion powershell | Invoke-Expression
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Releases
|
||||
|
||||
Download `holos` from the [releases] page and place the executable into your
|
||||
shell path.
|
||||
|
||||
### Dependencies
|
||||
|
||||
Holos integrates with the following tools that should be installed to enable
|
||||
their functionality.
|
||||
Install these tools to use Holos's full capabilities:
|
||||
|
||||
- [Helm] to fetch and render Helm chart Components.
|
||||
- [Kubectl] to [kustomize] components.
|
||||
- [Helm] for chart management and rendering
|
||||
- [Kubectl] for [kustomize] operations
|
||||
|
||||
:::note
|
||||
Holos is tested with Helm version `v3.16.2`.
|
||||
Holos is tested with Helm `v3.16.2`. If you see `Error: chart requires
|
||||
kubeVersion` errors, try upgrading Helm.
|
||||
:::
|
||||
|
||||
Please try upgrading helm if you encounter `Error: chart requires kubeVersion
|
||||
...` errors.
|
||||
|
||||
## Next Steps
|
||||
|
||||
You've got the structure of your platform configuration in place. Continue on to
|
||||
[Hello Holos] where you'll learn how easy it is to manage a Helm chart with
|
||||
holos.
|
||||
With your platform structure initialized, proceed to [Hello Holos] to learn Helm
|
||||
chart management.
|
||||
|
||||
[Helm]: https://github.com/helm/helm/releases
|
||||
[Kubectl]: https://kubernetes.io/docs/tasks/tools/
|
||||
|
||||
428
doc/md/tutorial/validators.mdx
Normal file
428
doc/md/tutorial/validators.mdx
Normal file
@@ -0,0 +1,428 @@
|
||||
---
|
||||
slug: validators
|
||||
title: Validators
|
||||
description: Validate rendered manifests against policy definitions.
|
||||
sidebar_position: 60
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import RenderingOverview from '@site/src/diagrams/rendering-overview.mdx';
|
||||
|
||||
# Validators
|
||||
|
||||
## Overview
|
||||
|
||||
Sometimes Helm charts render Secrets we do not wanted committed to version
|
||||
control for security. Helm charts often render incorrect manifests, even if
|
||||
they're accepted by the api server. For example, passing `null` to collection
|
||||
fields. We'll solve both of these issues using a [Validator] to block artifacts
|
||||
with a Secret resource, and verifying the artifact against Kubernetes type
|
||||
definitions.
|
||||
|
||||
1. If a Helm chart renders a Secret, Holos errors before writing the artifact
|
||||
and suggests an ExternalSecret instead.
|
||||
2. Each resource is validated against a field named by the value of the kind
|
||||
field. For example, a `kind: Secret` resource validates against `secret: {}` in
|
||||
CUE. `kind: Deployment` validates against `deployment: {}` in CUE.
|
||||
3. The final artifact is validated, covering the output of all generators and
|
||||
transformers.
|
||||
|
||||
<RenderingOverview />
|
||||
|
||||
## The Code
|
||||
|
||||
### Generating the Structure
|
||||
|
||||
Use `holos` to generate a minimal platform directory structure. First, create
|
||||
and navigate into a blank directory. Then, use the `holos generate platform`
|
||||
command to generate a minimal platform.
|
||||
|
||||
```shell
|
||||
mkdir holos-validators-tutorial && cd holos-validators-tutorial
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
|
||||
### Creating the Component
|
||||
|
||||
Create the directory for the `podinfo` component. Create an empty file, then add
|
||||
the following CUE configuration to it.
|
||||
|
||||
```bash
|
||||
mkdir -p components/podinfo
|
||||
```
|
||||
```bash
|
||||
cat <<EOF > components/podinfo/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// export the component build plan to holos
|
||||
holos: Component.BuildPlan
|
||||
|
||||
// Component is a Helm chart
|
||||
Component: #Helm & {
|
||||
Name: "podinfo"
|
||||
Namespace: "default"
|
||||
// Add metadata.namespace to all resources with kustomize.
|
||||
KustomizeConfig: Kustomization: namespace: Namespace
|
||||
Chart: {
|
||||
version: "6.6.2"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
Register the component with the platform.
|
||||
|
||||
```bash
|
||||
cat <<EOF > platform/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
Platform: Components: podinfo: {
|
||||
name: "podinfo"
|
||||
path: "components/podinfo"
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
Render the platform.
|
||||
|
||||
<Tabs groupId="tutorial-hello-render-manifests">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```
|
||||
cached podinfo 6.6.2
|
||||
rendered podinfo in 1.938665041s
|
||||
rendered platform in 1.938759417s
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Add and commit the initial configuration.
|
||||
|
||||
```bash
|
||||
git init . && git add . && git commit -m initial
|
||||
```
|
||||
|
||||
### Define the Valid Schema
|
||||
|
||||
We'll use a CUE package named `policy` so the entire platform configuration in
|
||||
package `holos` isn't loaded every time we validate an artifact.
|
||||
|
||||
Create `policy/validation-schema.cue` with the following content.
|
||||
|
||||
```shell
|
||||
mkdir -p policy
|
||||
cat <<EOF > policy/validation-schema.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package policy
|
||||
|
||||
import apps "k8s.io/api/apps/v1"
|
||||
|
||||
// Organize by kind then name to avoid conflicts.
|
||||
kind: [KIND=string]: [NAME=string]: {...}
|
||||
|
||||
// Useful when one component manages the same resource kind and name across
|
||||
// multiple namespaces.
|
||||
let KIND = kind
|
||||
namespace: [NS=string]: KIND
|
||||
|
||||
// Block Secret resources. kind will not unify with "Secret"
|
||||
kind: secret: [NAME=string]: kind: "Use an ExternalSecret instead. Forbidden by security policy. secret/\(NAME)"
|
||||
|
||||
// Validate Deployment against Kubernetes type definitions.
|
||||
kind: deployment: [_]: apps.#Deployment
|
||||
```
|
||||
```shell
|
||||
EOF
|
||||
```
|
||||
|
||||
### Configuring Validators
|
||||
|
||||
Configure the Validators [ComponentConfig] field to configure each [BuildPlan]
|
||||
to validate the rendered [Artifact] files.
|
||||
|
||||
```shell
|
||||
cat <<EOF > validators.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Configure all component kinds to validate against the policy directory.
|
||||
#ComponentConfig: Validators: cue: {
|
||||
kind: "Command"
|
||||
// Note --path maps each resource to a top level field named by the kind.
|
||||
command: args: [
|
||||
"holos",
|
||||
"cue",
|
||||
"vet",
|
||||
"./policy",
|
||||
"--path=\"namespace\"",
|
||||
"--path=metadata.namespace",
|
||||
"--path=strings.ToLower(kind)",
|
||||
"--path=metadata.name",
|
||||
]
|
||||
}
|
||||
```
|
||||
```shell
|
||||
EOF
|
||||
```
|
||||
|
||||
### Patching Errors
|
||||
|
||||
Render the platform to see validation fail. The podinfo chart has no Secret,
|
||||
but it produces an invalid Deployment because it sets the container resource
|
||||
limits field to `null`.
|
||||
|
||||
```shell
|
||||
holos render platform
|
||||
```
|
||||
|
||||
```txt
|
||||
deployment.spec.template.spec.containers.0.resources.limits: conflicting values null and {[string]:"k8s.io/apimachinery/pkg/api/resource".#Quantity} (mismatched types null and struct):
|
||||
./cue.mod/gen/k8s.io/api/apps/v1/types_go_gen.cue:355:9
|
||||
./cue.mod/gen/k8s.io/api/apps/v1/types_go_gen.cue:376:12
|
||||
./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:2840:11
|
||||
./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:2968:14
|
||||
./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:3882:15
|
||||
./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:3882:18
|
||||
./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:5027:9
|
||||
./cue.mod/gen/k8s.io/api/core/v1/types_go_gen.cue:6407:16
|
||||
./policy/validation-schema.cue:9:13
|
||||
../../../../../var/folders/22/T/holos.validate1636392304/components/podinfo/podinfo.gen.yaml:104:19
|
||||
could not run: terminating because of errors
|
||||
could not run: could not validate podinfo path ./components/podinfo: could not run command: holos cue vet ./policy --path strings.ToLower(kind) /var/folders/22/T/holos.validate1636392304/components/podinfo/podinfo.gen.yaml: exit status 1 at builder/v1alpha5/builder.go:411
|
||||
could not run: could not render component: could not run command: holos --log-level info --log-format console render component --inject holos_component_name=podinfo --inject holos_component_path=components/podinfo ./components/podinfo: exit status 1 at cli/render/render.go:155
|
||||
```
|
||||
|
||||
We'll use a [Kustomize] patch [Transformer] to replace the `null` limits field
|
||||
with a valid equivalent value.
|
||||
|
||||
:::important
|
||||
This configuration is defined in CUE, not YAML, even though we're configuring a
|
||||
Kustomize patch transformer. CUE gives us access to the unified platform
|
||||
configuration.
|
||||
:::
|
||||
|
||||
```shell
|
||||
cat <<EOF > components/podinfo/patch.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
|
||||
Component: KustomizeConfig: Kustomization: {
|
||||
_patches: limits: {
|
||||
target: kind: "Deployment"
|
||||
patch: yaml.Marshal([{
|
||||
op: "test"
|
||||
path: "/spec/template/spec/containers/0/resources/limits"
|
||||
value: null
|
||||
}, {
|
||||
op: "replace"
|
||||
path: "/spec/template/spec/containers/0/resources/limits"
|
||||
value: {}
|
||||
}])
|
||||
}
|
||||
patches: [for x in _patches {x}]
|
||||
}
|
||||
```
|
||||
```shell
|
||||
EOF
|
||||
```
|
||||
|
||||
Now the platform renders.
|
||||
|
||||
<Tabs groupId="3A050092-8E56-49D4-84A9-71E544A21276">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered podinfo in 181.875083ms
|
||||
rendered platform in 181.975833ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Inspecting the BuildPlan
|
||||
|
||||
The BuildPlan patches the output of the upstream helm chart without modifying
|
||||
it, then validates the artifact against the Kubernetes type definitions.
|
||||
|
||||
<Tabs groupId="1DAB4C46-0793-4CCA-8930-7B2E60BDA1BE">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos show buildplans
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
kind: BuildPlan
|
||||
apiVersion: v1alpha5
|
||||
metadata:
|
||||
name: podinfo
|
||||
spec:
|
||||
artifacts:
|
||||
- artifact: components/podinfo/podinfo.gen.yaml
|
||||
generators:
|
||||
- kind: Helm
|
||||
output: helm.gen.yaml
|
||||
helm:
|
||||
chart:
|
||||
name: podinfo
|
||||
version: 6.6.2
|
||||
release: podinfo
|
||||
repository:
|
||||
name: podinfo
|
||||
url: https://stefanprodan.github.io/podinfo
|
||||
values: {}
|
||||
namespace: default
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
transformers:
|
||||
- kind: Kustomize
|
||||
inputs:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
output: components/podinfo/podinfo.gen.yaml
|
||||
kustomize:
|
||||
kustomization:
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: default
|
||||
patches:
|
||||
- patch: |
|
||||
- op: test
|
||||
path: /spec/template/spec/containers/0/resources/limits
|
||||
value: null
|
||||
- op: replace
|
||||
path: /spec/template/spec/containers/0/resources/limits
|
||||
value: {}
|
||||
target:
|
||||
kind: Deployment
|
||||
name: ""
|
||||
resources:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
validators:
|
||||
- kind: Command
|
||||
inputs:
|
||||
- components/podinfo/podinfo.gen.yaml
|
||||
command:
|
||||
args:
|
||||
- holos
|
||||
- cue
|
||||
- vet
|
||||
- ./policy
|
||||
- --path
|
||||
- strings.ToLower(kind)
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Catching Mistakes
|
||||
|
||||
Suppose a teammate downloads a helm chart that includes a Secret unbeknown to
|
||||
them. Holos catches the problem and suggests an ExternalSecret instead.
|
||||
|
||||
Mix in a Secret to see what happens
|
||||
|
||||
```shell
|
||||
cat <<EOF > components/podinfo/secret.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
Component: Resources: Secret: example: metadata: name: "example"
|
||||
```
|
||||
```shell
|
||||
EOF
|
||||
```
|
||||
|
||||
Render the platform to see the error.
|
||||
|
||||
```shell
|
||||
holos render platform
|
||||
```
|
||||
```txt
|
||||
secret.kind: conflicting values "Use an ExternalSecret instead. Forbidden by security policy." and "Secret":
|
||||
./policy/validation-schema.cue:6:15
|
||||
../../../../../var/folders/22/T/holos.validate2549739170/components/podinfo/podinfo.gen.yaml:1:7
|
||||
could not run: terminating because of errors
|
||||
could not run: could not validate podinfo path ./components/podinfo: could not run command: holos cue vet ./policy --path strings.ToLower(kind) /var/folders/22/T/holos.validate2549739170/components/podinfo/podinfo.gen.yaml: exit status 1 at builder/v1alpha5/builder.go:411
|
||||
could not run: could not render component: could not run command: holos --log-level info --log-format console render component --inject holos_component_name=podinfo --inject holos_component_path=components/podinfo ./components/podinfo: exit status 1 at cli/render/render.go:155
|
||||
```
|
||||
|
||||
:::important
|
||||
Holos quickly returns an error if validated artifacts have a Secret.
|
||||
:::
|
||||
|
||||
Remove the secret to resolve the issue.
|
||||
|
||||
```shell
|
||||
rm components/podinfo/secret.cue
|
||||
```
|
||||
|
||||
## Inspecting the diff
|
||||
|
||||
The validation and patch results in a correct Deployment, verified against the
|
||||
Kubernetes type definitions.
|
||||
|
||||
```shell
|
||||
git diff
|
||||
```
|
||||
```diff
|
||||
diff --git a/deploy/components/podinfo/podinfo.gen.yaml b/deploy/components/podinfo/podinfo.gen.yaml
|
||||
index 6e4aec0..a145e3f 100644
|
||||
--- a/deploy/components/podinfo/podinfo.gen.yaml
|
||||
+++ b/deploy/components/podinfo/podinfo.gen.yaml
|
||||
@@ -101,7 +101,7 @@ spec:
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
resources:
|
||||
- limits: null
|
||||
+ limits: {}
|
||||
requests:
|
||||
cpu: 1m
|
||||
memory: 16Mi
|
||||
```
|
||||
|
||||
## Trying Locally
|
||||
|
||||
Optionally, apply the manifests rendered by Holos to a [Local Cluster] for
|
||||
testing.
|
||||
|
||||
[Local Cluster]: ../topics/local-cluster.mdx
|
||||
[ExternalSecret]: https://external-secrets.io/latest/api/externalsecret/
|
||||
[Artifact]: ../api/core.md#Artifact
|
||||
[BuildPlan]: ../api/core.md#BuildPlan
|
||||
[Resources]: ../api/core.md#Resources
|
||||
[Validator]: ../api/core.md#Validator
|
||||
[Transformer]: ../api/core.md#Transformer
|
||||
[Kustomize]: ../api/core.md#Kustomize
|
||||
[Generator]: ../api/core.md#Generator
|
||||
[Hello Holos]: ./hello-holos.mdx
|
||||
[cue.mod/gen/external-secrets.io/externalsecret/v1beta1/types_gen.cue]: https://github.com/holos-run/holos/blob/main/internal/generate/platforms/cue.mod/gen/external-secrets.io/externalsecret/v1beta1/types_gen.cue#L13
|
||||
[ComponentConfig]: ../api/author.md#ComponentConfig
|
||||
[timoni]: https://timoni.sh/install/
|
||||
[resources.cue]: https://github.com/holos-run/holos/blob/main/internal/generate/platforms/v1alpha5/resources.cue#L33
|
||||
35
doc/website/blog/2024-11-25-validators.mdx
Normal file
35
doc/website/blog/2024-11-25-validators.mdx
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
slug: validators-feature
|
||||
title: Validators added in Holos v0.101.0
|
||||
authors: [jeff]
|
||||
tags: [holos, feature]
|
||||
image: /img/cards/validators.png
|
||||
description: Validators are useful to enforce policy and catch Helm errors.
|
||||
---
|
||||
|
||||
import RenderingOverview from '@site/src/diagrams/rendering-overview.mdx';
|
||||
import RenderPlatformDiagram from '@site/src/diagrams/render-platform-sequence.mdx';
|
||||
|
||||
We've added support for [Validators] in [v0.101.0]. Validators are useful to
|
||||
enforce policies and ensure consistency early in the process. This feature
|
||||
addresses two primary use cases:
|
||||
|
||||
1. Prevent insecure configuration early in the process. For example, prevent
|
||||
Helm from rendering a `Secret` which would otherwise be committed to version control.
|
||||
2. Prevent unsafe configuration by validating manifests against Kubernetes core
|
||||
and custom resource type definitions.
|
||||
|
||||
Check out the [Validators] tutorial for examples of both use cases.
|
||||
|
||||
[Validators]: https://holos.run/docs/v1alpha5/tutorial/validators/
|
||||
[v0.101.0]: https://github.com/holos-run/holos/releases/tag/v0.101.0
|
||||
|
||||
{/* truncate */}
|
||||
|
||||
<RenderingOverview />
|
||||
|
||||
Validators complete the core functionality of the Holos manifest rendering
|
||||
pipeline. We are seeking design partners to help enhance Generators and
|
||||
Transformers. Validators are implemented using a generic `Command` kind, and
|
||||
we're considering a similar kind for Generators and Transformers. Please
|
||||
connect with us if you'd like to help design these enhancements.
|
||||
39
doc/website/package-lock.json
generated
39
doc/website/package-lock.json
generated
@@ -15,6 +15,7 @@
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
@@ -14477,6 +14478,44 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-loader": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
|
||||
"integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loader-utils": "^2.0.0",
|
||||
"schema-utils": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"webpack": "^4.0.0 || ^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-loader/node_modules/schema-utils": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
|
||||
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"ajv": "^6.12.5",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
|
||||
16
doc/website/src/components/YouTube/index.tsx
Normal file
16
doc/website/src/components/YouTube/index.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import styles from './styles.module.css';
|
||||
|
||||
//Pulled from: https://gaudion.dev/blog/mdx-youtube-embed
|
||||
//components/mdx/YouTube.tsx
|
||||
export default function YouTube({ id }: { id: string }) {
|
||||
return (
|
||||
<div className={styles.videoWrapper}>
|
||||
<iframe
|
||||
className="aspect-video w-full"
|
||||
src={"https://www.youtube.com/embed/" + id + "?rel=0"}
|
||||
title="YouTube Video Player"
|
||||
allow="picture-in-picture; fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope;"
|
||||
></iframe>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
14
doc/website/src/components/YouTube/styles.module.css
Normal file
14
doc/website/src/components/YouTube/styles.module.css
Normal file
@@ -0,0 +1,14 @@
|
||||
.videoWrapper {
|
||||
position: relative;
|
||||
padding-bottom: 56.25%; /* 16:9 */
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.videoWrapper iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -3,21 +3,21 @@
|
||||
title: Rendering Overview
|
||||
---
|
||||
graph LR
|
||||
Platform[<a href="/docs/v1alpha5/api/author/#Platform">Platform</a>]
|
||||
Component[<a href="/docs/v1alpha5/api/author/#ComponentConfig">Components</a>]
|
||||
Platform[<a href="https://holos.run/docs/v1alpha5/api/author/#Platform">Platform</a>]
|
||||
Component[<a href="https://holos.run/docs/v1alpha5/api/author/#ComponentConfig">Components</a>]
|
||||
|
||||
Helm[<a href="/docs/v1alpha5/api/author/#Helm">Helm</a>]
|
||||
Kustomize[<a href="/docs/v1alpha5/api/author/#Kustomize">Kustomize</a>]
|
||||
Kubernetes[<a href="/docs/v1alpha5/api/author/#Kubernetes">Kubernetes</a>]
|
||||
Helm[<a href="https://holos.run/docs/v1alpha5/api/author/#Helm">Helm</a>]
|
||||
Kustomize[<a href="https://holos.run/docs/v1alpha5/api/author/#Kustomize">Kustomize</a>]
|
||||
Kubernetes[<a href="https://holos.run/docs/v1alpha5/api/author/#Kubernetes">Kubernetes</a>]
|
||||
|
||||
BuildPlan[<a href="/docs/v1alpha5/api/core/#BuildPlan">BuildPlan</a>]
|
||||
BuildPlan[<a href="https://holos.run/docs/v1alpha5/api/core/#BuildPlan">BuildPlan</a>]
|
||||
|
||||
ResourcesArtifact[<a href="/docs/v1alpha5/api/core/#Artifact">Resources<br/>Artifact</a>]
|
||||
GitOpsArtifact[<a href="/docs/v1alpha5/api/core/#Artifact">GitOps<br/>Artifact</a>]
|
||||
ResourcesArtifact[<a href="https://holos.run/docs/v1alpha5/api/core/#Artifact">Resources<br/>Artifact</a>]
|
||||
GitOpsArtifact[<a href="https://holos.run/docs/v1alpha5/api/core/#Artifact">GitOps<br/>Artifact</a>]
|
||||
|
||||
Generators[<a href="/docs/v1alpha5/api/core/#Generator">Generators</a>]
|
||||
Transformers[<a href="/docs/v1alpha5/api/core/#Transformer">Transformers</a>]
|
||||
Validators[Validators]
|
||||
Generators[<a href="https://holos.run/docs/v1alpha5/api/core/#Generator">Generators</a>]
|
||||
Transformers[<a href="https://holos.run/docs/v1alpha5/api/core/#Transformer">Transformers</a>]
|
||||
Validators[<a href="https://holos.run/docs/v1alpha5/api/core/#Validator">Validators</a>]
|
||||
Files[Manifest<br/>Files]
|
||||
|
||||
Platform --> Component
|
||||
|
||||
22
doc/website/static/_redirects
Normal file
22
doc/website/static/_redirects
Normal file
@@ -0,0 +1,22 @@
|
||||
/docs /docs/v1alpha5/ 301
|
||||
/docs/ /docs/v1alpha5/ 301
|
||||
/docs/tutorial /docs/v1alpha5/tutorial/overview/ 301
|
||||
/docs/tutorial/ /docs/v1alpha5/tutorial/overview/ 301
|
||||
/docs/quickstart /docs/v1alpha5/tutorial/overview/ 301
|
||||
/docs/quickstart/ /docs/v1alpha5/tutorial/overview/ 301
|
||||
/docs/overview /docs/v1alpha5/tutorial/overview/ 301
|
||||
/docs/overview/ /docs/v1alpha5/tutorial/overview/ 301
|
||||
/docs/topics /docs/v1alpha5/topics/ 301
|
||||
/docs/topics/ /docs/v1alpha5/topics/ 301
|
||||
/docs/setup /docs/v1alpha5/tutorial/setup/ 301
|
||||
/docs/setup/ /docs/v1alpha5/tutorial/setup/ 301
|
||||
/docs/local-cluster /docs/v1alpha5/topics/local-cluster/ 301
|
||||
/docs/local-cluster/ /docs/v1alpha5/topics/local-cluster/ 301
|
||||
/docs/guides/helm /docs/v1alpha5/tutorial/helm-values/ 301
|
||||
/docs/guides/helm/ /docs/v1alpha5/tutorial/helm-values/ 301
|
||||
/docs/kargo /docs/v1alpha5/topics/kargo/ 301
|
||||
/docs/kargo/ /docs/v1alpha5/topics/kargo/ 301
|
||||
/docs/comparison /docs/v1alpha5/topics/comparison/ 301
|
||||
/docs/comparison/ /docs/v1alpha5/topics/comparison/ 301
|
||||
/docs/support /docs/v1alpha5/tutorial/overview/#getting-help 301
|
||||
/docs/support/ /docs/v1alpha5/tutorial/overview/#getting-help 301
|
||||
BIN
doc/website/static/img/cards/validators.png
Normal file
BIN
doc/website/static/img/cards/validators.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
128
go.mod
128
go.mod
@@ -10,7 +10,7 @@ require (
|
||||
connectrpc.com/grpcreflect v1.2.0
|
||||
connectrpc.com/otelconnect v0.7.0
|
||||
connectrpc.com/validate v0.1.0
|
||||
cuelang.org/go v0.10.1
|
||||
cuelang.org/go v0.11.1
|
||||
entgo.io/ent v0.13.1
|
||||
github.com/bufbuild/buf v1.35.1
|
||||
github.com/choria-io/machine-room v0.0.0-20240417064836-c604da2f005e
|
||||
@@ -27,24 +27,26 @@ require (
|
||||
github.com/mennanov/fieldmask-utils v1.1.2
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/princjef/gomarkdoc v1.1.0
|
||||
github.com/prometheus/client_golang v1.19.0
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/rogpeppe/go-internal v1.13.1
|
||||
github.com/sethvargo/go-retry v0.2.4
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/net v0.28.0
|
||||
golang.org/x/net v0.30.0
|
||||
golang.org/x/sync v0.8.0
|
||||
golang.org/x/tools v0.24.0
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4
|
||||
golang.org/x/tools v0.26.0
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094
|
||||
google.golang.org/protobuf v1.34.2
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
helm.sh/helm/v3 v3.16.3
|
||||
honnef.co/go/tools v0.4.7
|
||||
k8s.io/api v0.29.2
|
||||
k8s.io/apimachinery v0.29.4
|
||||
k8s.io/client-go v0.29.2
|
||||
k8s.io/kubectl v0.29.2
|
||||
k8s.io/api v0.31.1
|
||||
k8s.io/apimachinery v0.31.1
|
||||
k8s.io/client-go v0.31.1
|
||||
k8s.io/kubectl v0.31.1
|
||||
modernc.org/sqlite v1.29.6
|
||||
sigs.k8s.io/kustomize/kustomize/v5 v5.5.0
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
)
|
||||
|
||||
@@ -52,9 +54,11 @@ require (
|
||||
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect
|
||||
buf.build/gen/go/bufbuild/registry/connectrpc/go v1.16.2-20240610164129-660609bc46d3.1 // indirect
|
||||
buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.34.2-20240610164129-660609bc46d3.2 // indirect
|
||||
cel.dev/expr v0.15.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240807094312-a32ad29eed79 // indirect
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
@@ -68,11 +72,13 @@ require (
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b // indirect
|
||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/OneOfOne/xxhash v1.2.8 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect
|
||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||
@@ -107,6 +113,7 @@ require (
|
||||
github.com/bufbuild/protoyaml-go v0.1.9 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.2 // indirect
|
||||
github.com/cheekybits/genny v1.0.0 // indirect
|
||||
github.com/cheggaaa/pb/v3 v3.0.8 // indirect
|
||||
github.com/choria-io/fisk v0.6.2 // indirect
|
||||
@@ -117,11 +124,15 @@ require (
|
||||
github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect
|
||||
github.com/cloudevents/sdk-go/v2 v2.15.2 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b // indirect
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
|
||||
github.com/containerd/containerd v1.7.23 // indirect
|
||||
github.com/containerd/errdefs v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.3.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
@@ -130,6 +141,7 @@ require (
|
||||
github.com/docker/docker v27.0.0+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.8.2 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
@@ -138,18 +150,22 @@ require (
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.12.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
|
||||
github.com/expr-lang/expr v1.16.4 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/felixge/fgprof v0.9.4 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.14 // indirect
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.11.0 // indirect
|
||||
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
@@ -166,7 +182,7 @@ require (
|
||||
github.com/go-openapi/strfmt v0.22.0 // indirect
|
||||
github.com/go-openapi/swag v0.22.9 // indirect
|
||||
github.com/go-openapi/validate v0.22.4 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.2.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
@@ -174,6 +190,7 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/cel-go v0.20.1 // indirect
|
||||
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
@@ -185,18 +202,22 @@ require (
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d // indirect
|
||||
github.com/goss-org/go-ps v0.0.0-20230609005227-7b318e6a56e5 // indirect
|
||||
github.com/goss-org/goss v0.4.6 // indirect
|
||||
github.com/gosuri/uilive v0.0.4 // indirect
|
||||
github.com/gosuri/uiprogress v0.0.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
|
||||
github.com/gosuri/uitable v0.0.4 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
|
||||
github.com/guptarohit/asciigraph v0.7.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
||||
github.com/hashicorp/logutils v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/int128/listener v1.1.0 // indirect
|
||||
@@ -209,14 +230,18 @@ require (
|
||||
github.com/jdx/go-netrc v1.0.0 // indirect
|
||||
github.com/jhump/protoreflect v1.16.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/jmoiron/sqlx v1.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/logrusorgru/aurora/v4 v4.0.0 // indirect
|
||||
github.com/looplab/fsm v1.0.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 // indirect
|
||||
@@ -233,12 +258,16 @@ require (
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/spdystream v0.4.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.7.1 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/nats-io/jsm.go v0.1.1 // indirect
|
||||
github.com/nats-io/jwt/v2 v2.5.5 // indirect
|
||||
github.com/nats-io/nats-server/v2 v2.10.14 // indirect
|
||||
@@ -249,14 +278,15 @@ require (
|
||||
github.com/nxadm/tail v1.4.11 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/oleiade/reflections v1.0.1 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 // indirect
|
||||
github.com/onsi/gomega v1.32.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
|
||||
github.com/onsi/gomega v1.33.1 // indirect
|
||||
github.com/open-policy-agent/opa v0.63.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
@@ -266,14 +296,15 @@ require (
|
||||
github.com/princjef/mageutil v1.0.0 // indirect
|
||||
github.com/princjef/termdiff v0.1.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.52.3 // indirect
|
||||
github.com/prometheus/procfs v0.13.0 // indirect
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20231025115547-084445ff1adf // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20240823084532-8e6b51fa9bef // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/robfig/cron v1.2.0 // indirect
|
||||
github.com/rs/cors v1.11.0 // indirect
|
||||
github.com/rubenv/sql-migrate v1.7.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
@@ -292,7 +323,7 @@ require (
|
||||
github.com/skeema/knownhosts v1.2.1 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
@@ -307,45 +338,52 @@ require (
|
||||
github.com/tklauser/numcpus v0.7.0 // indirect
|
||||
github.com/vbatts/tar-split v0.11.5 // indirect
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5 // indirect
|
||||
github.com/xlab/treeprint v1.2.0 // indirect
|
||||
github.com/yashtewari/glob-intersection v0.2.0 // indirect
|
||||
github.com/yuin/goldmark v1.7.4 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.13.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.25.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||
go.opentelemetry.io/otel v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.28.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/automaxprocs v1.5.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/oauth2 v0.22.0 // indirect
|
||||
golang.org/x/sys v0.23.0 // indirect
|
||||
golang.org/x/term v0.23.0 // indirect
|
||||
golang.org/x/text v0.17.0 // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/term v0.25.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect
|
||||
google.golang.org/grpc v1.64.0 // indirect
|
||||
google.golang.org/grpc v1.65.0 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.110.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8 // indirect
|
||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.31.1 // indirect
|
||||
k8s.io/apiserver v0.31.1 // indirect
|
||||
k8s.io/cli-runtime v0.31.1 // indirect
|
||||
k8s.io/component-base v0.31.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||
modernc.org/libc v1.41.0 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
@@ -353,7 +391,11 @@ require (
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
mvdan.cc/xurls/v2 v2.2.0 // indirect
|
||||
oras.land/oras-go v1.2.5 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/kind v0.23.0 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.18.0 // indirect
|
||||
sigs.k8s.io/kustomize/cmd/config v0.15.0 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
)
|
||||
|
||||
366
go.sum
366
go.sum
@@ -6,6 +6,8 @@ buf.build/gen/go/bufbuild/registry/connectrpc/go v1.16.2-20240610164129-660609bc
|
||||
buf.build/gen/go/bufbuild/registry/connectrpc/go v1.16.2-20240610164129-660609bc46d3.1/go.mod h1:4ptL49VoWyYwajT6j4zu5vmQ/k/om4tGMB9atY2FhEo=
|
||||
buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.34.2-20240610164129-660609bc46d3.2 h1:y1+UxFIWzj/eF2RCPqt9egR7Rt9vgQkXNUzSdmR6iEU=
|
||||
buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.34.2-20240610164129-660609bc46d3.2/go.mod h1:psseUmlKRo9v5LZJtR/aTpdTLuyp9o3X7rnLT87SZEo=
|
||||
cel.dev/expr v0.15.0 h1:O1jzfJCQBfL5BFoYktaxwIhuttaQPsVWerH9/EEKx0w=
|
||||
cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
@@ -48,15 +50,19 @@ connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY
|
||||
connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc=
|
||||
connectrpc.com/validate v0.1.0 h1:r55jirxMK7HO/xZwVHj3w2XkVFarsUM77ZDy367NtH4=
|
||||
connectrpc.com/validate v0.1.0/go.mod h1:GU47c9/x/gd+u9wRSPkrQOP46gx2rMN+Wo37EHgI3Ow=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240807094312-a32ad29eed79 h1:EceZITBGET3qHneD5xowSTY/YHbNybvMWGh62K2fG/M=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240807094312-a32ad29eed79/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg=
|
||||
cuelang.org/go v0.10.1 h1:vDRRsd/5CICzisZ/13kBmXt3M+9eDl/pI06rrHyhlgA=
|
||||
cuelang.org/go v0.10.1/go.mod h1:HzlaqqqInHNiqE6slTP6+UtxT9hN6DAzgJgdbNxXvX8=
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 h1:R5wwEcbEZSBmeyg91MJZTxfd7WpBo2jPof3AYjRbxwY=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg=
|
||||
cuelang.org/go v0.11.1 h1:pV+49MX1mmvDm8Qh3Za3M786cty8VKPWzQ1Ho4gZRP0=
|
||||
cuelang.org/go v0.11.1/go.mod h1:PBY6XvPUswPPJ2inpvUozP9mebDVTXaeehQikhZPBz0=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
entgo.io/ent v0.13.1 h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE=
|
||||
entgo.io/ent v0.13.1/go.mod h1:qCEmo+biw3ccBn9OyL4ZK5dfpwg++l1Gxwac5B1206A=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
||||
@@ -90,28 +96,35 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||
github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b h1:IltY1fRcdIshI/c8KOdmaO8P4lBwDXHJYPymMisvvDs=
|
||||
github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b/go.mod h1:VGwG8f2pQ8SAFjTSH3PEDmLdlvi0XTd7a4C4AZn+pVw=
|
||||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
|
||||
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
|
||||
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
|
||||
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
|
||||
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.11.7 h1:vl/nj3Bar/CvJSYo7gIQPyRWc9f3c6IeSNavBTSZNZQ=
|
||||
github.com/Microsoft/hcsshim v0.11.7/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
|
||||
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX7IL/m9Y5LO+KQYv+t1CQOiFe6+SV2J7bE=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||
@@ -121,6 +134,8 @@ github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tj
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
|
||||
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
@@ -168,12 +183,16 @@ github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q=
|
||||
github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
|
||||
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20240514230400-03fa26f5508f h1:Z0kS9pJDQgCg3u2lH6+CdYaFbyQtyukVTiUCG6re0E4=
|
||||
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20240514230400-03fa26f5508f/go.mod h1:rAE739ssmE5O5fLuQ2y8uHdmOJaelE5I0Es3SxV0y1A=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/brutella/hc v1.2.5 h1:P1tHqJtrGngob6Lv5E7RVGlLcdo54X/03Gseo5+soVw=
|
||||
github.com/brutella/hc v1.2.5/go.mod h1:kluioDmG4z8OweN0boeTf08696sH8odlhPDdq3gwuZw=
|
||||
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
|
||||
github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
||||
github.com/bufbuild/buf v1.35.1 h1:aiCi/YFOg7eXKZeveWb2ZhnmLFwUMM/FnDCM0roFp+M=
|
||||
github.com/bufbuild/buf v1.35.1/go.mod h1:SM7b5QW3FkQPNkkqIa/9UWzLOoe51la+GGZpEgH9b68=
|
||||
github.com/bufbuild/protocompile v0.14.0 h1:z3DW4IvXE5G/uTOnSQn+qwQQxvhckkTWLS/0No/o7KU=
|
||||
@@ -184,6 +203,12 @@ github.com/bufbuild/protovalidate-go v0.6.2 h1:U/V3CGF0kPlR12v41rjO4DrYZtLcS4ZON
|
||||
github.com/bufbuild/protovalidate-go v0.6.2/go.mod h1:4BR3rKEJiUiTy+sqsusFn2ladOf0kYmA2Reo6BHSBgQ=
|
||||
github.com/bufbuild/protoyaml-go v0.1.9 h1:anV5UtF1Mlvkkgp4NWA6U/zOnJFng8Orq4Vf3ZUQHBU=
|
||||
github.com/bufbuild/protoyaml-go v0.1.9/go.mod h1:KCBItkvZOK/zwGueLdH1Wx1RLyFn5rCH7YjQrdty2Wc=
|
||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng=
|
||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA=
|
||||
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q=
|
||||
@@ -197,6 +222,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
|
||||
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
|
||||
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
|
||||
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||
github.com/cheggaaa/pb v2.0.7+incompatible/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
@@ -238,12 +265,22 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 h1:DBmgJDC9dTfkVyGgipamEh2BpGYxScCH1TOF1LL1cXc=
|
||||
github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM=
|
||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
|
||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg=
|
||||
github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ=
|
||||
github.com/containerd/containerd v1.7.23/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
|
||||
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
|
||||
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
|
||||
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
|
||||
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
|
||||
github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU=
|
||||
@@ -254,8 +291,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8=
|
||||
github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
@@ -269,6 +306,8 @@ github.com/dgryski/trifles v0.0.0-20220729183022-231ecf6ed548 h1:acdRTG6Vp8kMaN3
|
||||
github.com/dgryski/trifles v0.0.0-20220729183022-231ecf6ed548/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
||||
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/cli v26.1.4+incompatible h1:I8PHdc0MtxEADqYJZvhBrW9bo8gawKwwenxRM7/rLu8=
|
||||
@@ -281,8 +320,14 @@ github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZ
|
||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
|
||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w=
|
||||
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
@@ -305,10 +350,12 @@ github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/Ir
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls=
|
||||
github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
|
||||
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||
github.com/expr-lang/expr v1.16.4 h1:1Mq5RHw5T5jxXMUvyb+eT546mJREm1yFyNHkybYQ81c=
|
||||
github.com/expr-lang/expr v1.16.4/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@@ -334,12 +381,16 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fullstorydev/grpcurl v1.9.1 h1:YxX1aCcCc4SDBQfj9uoWcTLe8t4NWrZe1y+mk83BQgo=
|
||||
github.com/fullstorydev/grpcurl v1.9.1/go.mod h1:i8gKLIC6s93WdU3LSmkE5vtsCxyRmihUj5FK1cNW5EM=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||
github.com/go-chi/chi/v5 v5.0.14 h1:PyEwo2Vudraa0x/Wl6eDRRW2NXBvekgfxyydcM0WGE0=
|
||||
github.com/go-chi/chi/v5 v5.0.14/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
|
||||
@@ -351,14 +402,18 @@ github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lK
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
|
||||
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
|
||||
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
@@ -390,9 +445,12 @@ github.com/go-openapi/validate v0.22.4 h1:5v3jmMyIPKTR8Lv9syBAIRxG6lY0RqeBPB1LKE
|
||||
github.com/go-openapi/validate v0.22.4/go.mod h1:qm6O8ZIcPVdSY5219468Jv7kBdGvkiZLPOmqnqTUZ2A=
|
||||
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
||||
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
||||
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
@@ -406,6 +464,7 @@ github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1
|
||||
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM=
|
||||
github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
@@ -415,8 +474,8 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=
|
||||
github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4=
|
||||
github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@@ -452,8 +511,12 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
|
||||
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=
|
||||
github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
|
||||
github.com/google/flatbuffers v23.3.3+incompatible h1:5PJI/WbJkaMTvpGxsHVKG/LurN/KnWXNyGpwSCDgen0=
|
||||
@@ -500,7 +563,6 @@ github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2/go.mod h1:Tv1PlzqC
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -508,8 +570,12 @@ github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
|
||||
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
||||
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d h1:50mlZKtg8BUvBtFs0ioVpSgMMwcKaJefg/2pZ+lQf98=
|
||||
github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d/go.mod h1:MBdRlloGIbpQVDuH5Gxg3hjqwZBCZsmFqbYPaeR6r0M=
|
||||
github.com/goss-org/go-ps v0.0.0-20230609005227-7b318e6a56e5 h1:NW0Jo4leMIrQxNOyOkBu4yBnygI37m0Ey0EUUgvzr+8=
|
||||
@@ -520,13 +586,25 @@ github.com/gosuri/uilive v0.0.4 h1:hUEBpQDj8D8jXgtCdBu7sWsy5sbW/5GhuO8KBwJ2jyY=
|
||||
github.com/gosuri/uilive v0.0.4/go.mod h1:V/epo5LjjlDE5RJUcqx8dbw+zc93y5Ya3yg8tfZ74VI=
|
||||
github.com/gosuri/uiprogress v0.0.1 h1:0kpv/XY/qTmFWl/SkaJykZXrBBzwwadmW8fRb7RJSxw=
|
||||
github.com/gosuri/uiprogress v0.0.1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
|
||||
github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
|
||||
github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
|
||||
github.com/guptarohit/asciigraph v0.7.1 h1:K+JWbRc04XEfv8BSZgNuvhCmpbvX4+9NYd/UxXVnAuk=
|
||||
github.com/guptarohit/asciigraph v0.7.1/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM=
|
||||
@@ -539,14 +617,12 @@ github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4Dvx
|
||||
github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 h1:AgcIVYPa6XJnU3phs104wLj8l5GEththEw6+F79YsIY=
|
||||
github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
|
||||
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
|
||||
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
@@ -580,12 +656,17 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs=
|
||||
github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
@@ -597,6 +678,8 @@ github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -607,11 +690,17 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||
github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 h1:WGrKdjHtWC67RX96eTkYD2f53NDHhrq/7robWTAfk4s=
|
||||
github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491/go.mod h1:o158RFmdEbYyIZmXAbrvmJWesbyxlLKee6X64VPVuOc=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc=
|
||||
github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
|
||||
github.com/logrusorgru/aurora/v4 v4.0.0 h1:sRjfPpun/63iADiSvGGjgA1cAYegEWMPCJdUpJYn9JA=
|
||||
@@ -647,6 +736,7 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mennanov/fieldmask-utils v1.1.2 h1:f5hd3hYeWdl+q2thiKYyZZmqTqn90uayWG03bca9U+E=
|
||||
github.com/mennanov/fieldmask-utils v1.1.2/go.mod h1:xRqd9Fjz/gFEDYCQw7pxGouxqLhSPrkOdx2yhEAXEls=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
@@ -658,7 +748,6 @@ github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
|
||||
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
@@ -667,25 +756,37 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8=
|
||||
github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
|
||||
github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
|
||||
github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nats-io/jsm.go v0.1.1 h1:6vjllz276SdC+3Fb3XI71p9B6toxkCruuB1K6unQEr0=
|
||||
github.com/nats-io/jsm.go v0.1.1/go.mod h1:cFz5wR1pW0zLFotntS4HA7V8Wm+sf8zpF+iQJHbsS6M=
|
||||
github.com/nats-io/jwt/v2 v2.5.5 h1:ROfXb50elFq5c9+1ztaUbdlrArNFl2+fQWP6B8HGEq4=
|
||||
@@ -715,14 +816,14 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
|
||||
github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
|
||||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
|
||||
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
|
||||
github.com/open-policy-agent/opa v0.63.0 h1:ztNNste1v8kH0/vJMJNquE45lRvqwrM5mY9Ctr9xIXw=
|
||||
github.com/open-policy-agent/opa v0.63.0/go.mod h1:9VQPqEfoB2N//AToTxzZ1pVTVPUoF2Mhd64szzjWPpU=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
@@ -734,13 +835,18 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
|
||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -752,6 +858,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
|
||||
github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/princjef/gomarkdoc v1.1.0 h1:xtl7mESKQWVuGiFdd1AO3dFA6OenWG86bZu97IqBNPE=
|
||||
@@ -760,17 +868,27 @@ github.com/princjef/mageutil v1.0.0 h1:1OfZcJUMsooPqieOz2ooLjI+uHUo618pdaJsbCXcF
|
||||
github.com/princjef/mageutil v1.0.0/go.mod h1:mkShhaUomCYfAoVvTKRcbAs8YSVPdtezI5j6K+VXhrs=
|
||||
github.com/princjef/termdiff v0.1.0 h1:O3PWhfPFzX6GqzQ+41B3XzzJpMlx0+9Vysm+Pv76C9U=
|
||||
github.com/princjef/termdiff v0.1.0/go.mod h1:JJOfCA/eR6T1JfsoxQQ6jsG3LGoQDoKUIRQrKqAO+p4=
|
||||
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
|
||||
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
|
||||
github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||
github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
|
||||
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20231025115547-084445ff1adf h1:014O62zIzQwvoD7Ekj3ePDF5bv9Xxy0w6AZk0qYbjUk=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20231025115547-084445ff1adf/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20240823084532-8e6b51fa9bef h1:ej+64jiny5VETZTqcc1GFVAPEtaSk6U1D0kKC2MS5Yc=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20240823084532-8e6b51fa9bef/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
@@ -788,6 +906,8 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
|
||||
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rubenv/sql-migrate v1.7.0 h1:HtQq1xyTN2ISmQDggnh0c9U3JlP8apWh8YO2jzlXpTI=
|
||||
github.com/rubenv/sql-migrate v1.7.0/go.mod h1:S4wtDEG1CKn+0ShpTtzWhFpHHI5PvCUtiGI+C+Z2THE=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
@@ -812,7 +932,6 @@ github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFt
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/sigstore/cosign/v2 v2.2.3 h1:WX7yawI+EXu9h7S5bZsfYCbB9XW6Jc43ctKy/NoOSiA=
|
||||
@@ -821,6 +940,7 @@ github.com/sigstore/rekor v1.3.4 h1:RGIia1iOZU7fOiiP2UY/WFYhhp50S5aUm7YrM8aiA6E=
|
||||
github.com/sigstore/rekor v1.3.4/go.mod h1:1GubPVO2yO+K0m0wt/3SHFqnilr/hWbsjSOe7Vzxrlg=
|
||||
github.com/sigstore/sigstore v1.8.1 h1:mAVposMb14oplk2h/bayPmIVdzbq2IhCgy4g6R0ZSjo=
|
||||
github.com/sigstore/sigstore v1.8.1/go.mod h1:02SL1158BSj15bZyOFz7m+/nJzLZfFd9A8ab3Kz7w/E=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
@@ -830,9 +950,8 @@ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9yS
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@@ -842,6 +961,7 @@ github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMV
|
||||
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
||||
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
@@ -888,17 +1008,24 @@ github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5 h1:gmD7q6cCJfBbcuobWQe/KzLsd9Cd3amS1Mq5f3uU1qo=
|
||||
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5/go.mod h1:fVwOndYN3s5IaGlMucfgxwMhqwcaJtlGejBU6zX6Yxw=
|
||||
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
|
||||
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||
github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg=
|
||||
github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
@@ -912,6 +1039,12 @@ github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
|
||||
github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
|
||||
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
|
||||
@@ -923,24 +1056,24 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k=
|
||||
go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
|
||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
||||
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM=
|
||||
go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA=
|
||||
go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s=
|
||||
go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo=
|
||||
go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw=
|
||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
||||
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.19.0 h1:EJoTO5qysMsYCa+w4UghwFV/ptQgqSL/8Ni+hx+8i1k=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.19.0/go.mod h1:XjG0jQyFJrv2PbMvwND7LwCEhsJzCzV5210euduKcKY=
|
||||
go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM=
|
||||
go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I=
|
||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
@@ -954,6 +1087,7 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@@ -963,13 +1097,12 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -1007,11 +1140,12 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -1019,6 +1153,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -1048,16 +1183,16 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -1073,7 +1208,9 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1084,6 +1221,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1138,8 +1276,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
@@ -1147,8 +1285,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
||||
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1163,8 +1301,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -1217,8 +1355,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -1280,8 +1418,8 @@ google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/b
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -1297,8 +1435,8 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -1317,6 +1455,7 @@ google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/VividCortex/ewma.v1 v1.1.1/go.mod h1:TekXuFipeiHWiAlO1+wSS23vTcyFau5u3rxXUSXj710=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -1324,6 +1463,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v2 v2.0.7/go.mod h1:0CiZ1p8pvtxBlQpLXkHuUTpdJ1shm3OqCF1QugkjHL4=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/fatih/color.v1 v1.7.0/go.mod h1:P7yosIhqIl/sX8J8UypY5M+dDpD2KmyfP5IRs5v/fo0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs=
|
||||
@@ -1339,6 +1480,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -1352,6 +1494,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
helm.sh/helm/v3 v3.16.3 h1:kb8bSxMeRJ+knsK/ovvlaVPfdis0X3/ZhYCSFRP+YmY=
|
||||
helm.sh/helm/v3 v3.16.3/go.mod h1:zeVWGDR4JJgiRbT3AnNsjYaX8OTJlIE9zC+Q7F7iUSU=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -1361,20 +1505,28 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs=
|
||||
honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0=
|
||||
k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A=
|
||||
k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0=
|
||||
k8s.io/apimachinery v0.29.4 h1:RaFdJiDmuKs/8cm1M6Dh1Kvyh59YQFDcFuFTSmXes6Q=
|
||||
k8s.io/apimachinery v0.29.4/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
|
||||
k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg=
|
||||
k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA=
|
||||
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
|
||||
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
|
||||
k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8 h1:vzKzxN5uyJZLY8HL1/OovW7BJefnsBIWt8T7Gjh2boQ=
|
||||
k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
||||
k8s.io/kubectl v0.29.2 h1:uaDYaBhumvkwz0S2XHt36fK0v5IdNgL7HyUniwb2IUo=
|
||||
k8s.io/kubectl v0.29.2/go.mod h1:BhizuYBGcKaHWyq+G7txGw2fXg576QbPrrnQdQDZgqI=
|
||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
|
||||
k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU=
|
||||
k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
|
||||
k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40=
|
||||
k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ=
|
||||
k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
|
||||
k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c=
|
||||
k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM=
|
||||
k8s.io/cli-runtime v0.31.1 h1:/ZmKhmZ6hNqDM+yf9s3Y4KEYakNXUn5sod2LWGGwCuk=
|
||||
k8s.io/cli-runtime v0.31.1/go.mod h1:pKv1cDIaq7ehWGuXQ+A//1OIF+7DI+xudXtExMCbe9U=
|
||||
k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
|
||||
k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
|
||||
k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8=
|
||||
k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
||||
k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24=
|
||||
k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
||||
@@ -1393,6 +1545,8 @@ modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
mvdan.cc/xurls/v2 v2.2.0 h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=
|
||||
mvdan.cc/xurls/v2 v2.2.0/go.mod h1:EV1RMtya9D6G5DMYPGD8zTQzaHet6Jh8gFlRgGRJeO8=
|
||||
oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo=
|
||||
oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
@@ -1400,6 +1554,14 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMm
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/kind v0.23.0 h1:8fyDGWbWTeCcCTwA04v4Nfr45KKxbSPH1WO9K+jVrBg=
|
||||
sigs.k8s.io/kind v0.23.0/go.mod h1:ZQ1iZuJLh3T+O8fzhdi3VWcFTzsdXtNv2ppsHc8JQ7s=
|
||||
sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo=
|
||||
sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U=
|
||||
sigs.k8s.io/kustomize/cmd/config v0.15.0 h1:WkdY8V2+8J+W00YbImXa2ke9oegfrHH79e+kywW7EdU=
|
||||
sigs.k8s.io/kustomize/cmd/config v0.15.0/go.mod h1:Jq57b0nPaoYUlOqg//0JtAh6iibboqMcfbtCYoWPM00=
|
||||
sigs.k8s.io/kustomize/kustomize/v5 v5.5.0 h1:o1mtt6vpxsxDYaZKrw3BnEtc+pAjLz7UffnIvHNbvW0=
|
||||
sigs.k8s.io/kustomize/kustomize/v5 v5.5.0/go.mod h1:AeFCmgCrXzmvjWWaeZCyBp6XzG1Y0w1svYus8GhJEOE=
|
||||
sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E=
|
||||
sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
|
||||
@@ -20,6 +20,7 @@ var _ Store = NewStore()
|
||||
type Store interface {
|
||||
Get(path string) (data []byte, ok bool)
|
||||
Set(path string, data []byte) error
|
||||
// Save previously set path to dir preserving directories.
|
||||
Save(dir, path string) error
|
||||
}
|
||||
|
||||
|
||||
@@ -5,17 +5,75 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/interpreter/embed"
|
||||
"cuelang.org/go/cue/load"
|
||||
"cuelang.org/go/encoding/yaml"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/util"
|
||||
)
|
||||
|
||||
func LoadInstance(path string, tags []string) (*Instance, error) {
|
||||
// cue context and loading is not safe for concurrent use.
|
||||
var cueMutex sync.Mutex
|
||||
|
||||
// ExtractYAML extracts yaml encoded data from file paths. The data is unified
|
||||
// into one [cue.Value]. If a path element is a directory, all files in the
|
||||
// directory are loaded non-recursively.
|
||||
//
|
||||
// Attribution: https://github.com/cue-lang/cue/issues/3504
|
||||
// Deprecated: Use cue embed instead.
|
||||
func ExtractYAML(ctxt *cue.Context, filepaths []string) (cue.Value, error) {
|
||||
value := ctxt.CompileString("")
|
||||
files := make([]string, 0, 10*len(filepaths))
|
||||
|
||||
for _, path := range filepaths {
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return value, errors.Wrap(err)
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
files = append(files, path)
|
||||
continue
|
||||
}
|
||||
|
||||
entries, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return value, errors.Wrap(err)
|
||||
}
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
files = append(files, filepath.Join(path, entry.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
f, err := yaml.Extract(file, nil)
|
||||
if err != nil {
|
||||
return value, errors.Wrap(err)
|
||||
}
|
||||
value = value.Unify(ctxt.BuildFile(f))
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// LoadInstance loads the cue configuration instance at path. External data
|
||||
// file paths are loaded by calling [ExtractYAML] providing filepaths. The
|
||||
// extracted data values are unified with the platform configuration [cue.Value]
|
||||
// in the returned [Instance].
|
||||
func LoadInstance(path string, filepaths []string, tags []string) (*Instance, error) {
|
||||
cueMutex.Lock()
|
||||
defer cueMutex.Unlock()
|
||||
root, leaf, err := util.FindRootLeaf(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
@@ -26,20 +84,25 @@ func LoadInstance(path string, tags []string) (*Instance, error) {
|
||||
ModuleRoot: root,
|
||||
Tags: tags,
|
||||
}
|
||||
ctxt := cuecontext.New(cuecontext.Interpreter(embed.New()))
|
||||
|
||||
ctx := cuecontext.New()
|
||||
|
||||
instances := load.Instances([]string{leaf}, cfg)
|
||||
values, err := ctx.BuildInstances(instances)
|
||||
bis := load.Instances([]string{path}, cfg)
|
||||
values, err := ctxt.BuildInstances(bis)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
value, err := ExtractYAML(ctxt, filepaths)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
value = value.Unify(values[0])
|
||||
|
||||
inst := &Instance{
|
||||
path: leaf,
|
||||
ctx: ctx,
|
||||
ctx: ctxt,
|
||||
cfg: cfg,
|
||||
value: values[0],
|
||||
value: value,
|
||||
}
|
||||
|
||||
return inst, nil
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
// PlatformOpts represents build options when processing the components in a
|
||||
// platform.
|
||||
type PlatformOpts struct {
|
||||
Fn BuildFunc
|
||||
Selector holos.Selector
|
||||
Fn func(context.Context, int, holos.Component) error
|
||||
Selectors holos.Selectors
|
||||
Concurrency int
|
||||
InfoEnabled bool
|
||||
}
|
||||
@@ -31,7 +31,7 @@ type Platform struct {
|
||||
func (p *Platform) Build(ctx context.Context, opts PlatformOpts) error {
|
||||
limit := max(opts.Concurrency, 1)
|
||||
parentStart := time.Now()
|
||||
components := p.Select(opts.Selector)
|
||||
components := p.Select(opts.Selectors...)
|
||||
total := len(components)
|
||||
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
@@ -89,9 +89,6 @@ func (p *Platform) Build(ctx context.Context, opts PlatformOpts) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuildFunc is executed concurrently when processing platform components.
|
||||
type BuildFunc func(context.Context, int, holos.Component) error
|
||||
|
||||
func LoadPlatform(i *Instance) (platform Platform, err error) {
|
||||
err = i.Discriminate(func(tm holos.TypeMeta) error {
|
||||
if tm.Kind != "Platform" {
|
||||
|
||||
@@ -9,18 +9,19 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
core "github.com/holos-run/holos/api/core/v1alpha5"
|
||||
"github.com/holos-run/holos/internal/artifact"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/helm"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/holos-run/holos/internal/util"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"gopkg.in/yaml.v3"
|
||||
"helm.sh/helm/v3/pkg/cli"
|
||||
)
|
||||
|
||||
// Platform represents a platform builder.
|
||||
@@ -106,157 +107,113 @@ func (c *Component) Path() string {
|
||||
return util.DotSlash(c.Component.Path)
|
||||
}
|
||||
|
||||
var _ holos.BuildPlan = &BuildPlan{}
|
||||
|
||||
// BuildPlan represents a component builder.
|
||||
type BuildPlan struct {
|
||||
core.BuildPlan
|
||||
Opts holos.BuildOpts
|
||||
}
|
||||
|
||||
// Build builds a BuildPlan into Artifact files.
|
||||
func (b *BuildPlan) Build(ctx context.Context) error {
|
||||
name := b.BuildPlan.Metadata.Name
|
||||
path := b.Opts.Path
|
||||
log := logger.FromContext(ctx).With("name", name, "path", path)
|
||||
msg := fmt.Sprintf("could not build %s", name)
|
||||
if b.BuildPlan.Spec.Disabled {
|
||||
log.WarnContext(ctx, fmt.Sprintf("%s: disabled", msg))
|
||||
return nil
|
||||
// ExtractYAML returns the path values for the --extract-yaml command line flag.
|
||||
func (c *Component) ExtractYAML() ([]string, error) {
|
||||
if c == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
// One more for the producer
|
||||
g.SetLimit(b.Opts.Concurrency + 1)
|
||||
|
||||
// Producer.
|
||||
g.Go(func() error {
|
||||
for _, a := range b.BuildPlan.Spec.Artifacts {
|
||||
msg := fmt.Sprintf("%s artifact %s", msg, a.Artifact)
|
||||
log := log.With("artifact", a.Artifact)
|
||||
if a.Skip {
|
||||
log.WarnContext(ctx, fmt.Sprintf("%s: skipped field is true", msg))
|
||||
continue
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
// https://golang.org/doc/faq#closures_and_goroutines
|
||||
a := a
|
||||
// Worker. Blocks if limit has been reached.
|
||||
g.Go(func() error {
|
||||
for _, gen := range a.Generators {
|
||||
switch gen.Kind {
|
||||
case "Resources":
|
||||
if err := b.resources(log, gen, b.Opts.Store); err != nil {
|
||||
return errors.Format("could not generate resources: %w", err)
|
||||
}
|
||||
case "Helm":
|
||||
if err := b.helm(ctx, log, gen, b.Opts.Store); err != nil {
|
||||
return errors.Format("could not generate helm: %w", err)
|
||||
}
|
||||
case "File":
|
||||
if err := b.file(log, gen, b.Opts.Store); err != nil {
|
||||
return errors.Format("could not generate file: %w", err)
|
||||
}
|
||||
default:
|
||||
return errors.Format("%s: unsupported kind %s", msg, gen.Kind)
|
||||
}
|
||||
}
|
||||
|
||||
for _, t := range a.Transformers {
|
||||
switch t.Kind {
|
||||
case "Kustomize":
|
||||
if err := b.kustomize(ctx, log, t, b.Opts.Store); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
case "Join":
|
||||
s := make([][]byte, 0, len(t.Inputs))
|
||||
for _, input := range t.Inputs {
|
||||
if data, ok := b.Opts.Store.Get(string(input)); ok {
|
||||
s = append(s, data)
|
||||
} else {
|
||||
return errors.Format("%s: missing %s", msg, input)
|
||||
}
|
||||
}
|
||||
data := bytes.Join(s, []byte(t.Join.Separator))
|
||||
if err := b.Opts.Store.Set(string(t.Output), data); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
log.Debug("set artifact: " + string(t.Output))
|
||||
default:
|
||||
return errors.Format("%s: unsupported kind %s", msg, t.Kind)
|
||||
}
|
||||
}
|
||||
|
||||
// Write the final artifact
|
||||
if err := b.Opts.Store.Save(b.Opts.WriteTo, string(a.Artifact)); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
log.DebugContext(ctx, "wrote "+filepath.Join(b.Opts.WriteTo, string(a.Artifact)))
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
instances := make([]string, 0, len(c.Component.Instances))
|
||||
for _, instance := range c.Component.Instances {
|
||||
if instance.Kind == "ExtractYAML" {
|
||||
instances = append(instances, instance.ExtractYAML.Path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// Wait for completion and return the first error (if any)
|
||||
return g.Wait()
|
||||
}
|
||||
return instances, nil
|
||||
}
|
||||
|
||||
func (b *BuildPlan) Export(idx int, encoder holos.OrderedEncoder) error {
|
||||
if err := encoder.Encode(idx, &b.BuildPlan); err != nil {
|
||||
return errors.Wrap(err)
|
||||
var _ holos.BuildPlan = &BuildPlan{}
|
||||
var _ task = generatorTask{}
|
||||
var _ task = transformersTask{}
|
||||
var _ task = validatorTask{}
|
||||
|
||||
type task interface {
|
||||
id() string
|
||||
run(ctx context.Context) error
|
||||
}
|
||||
|
||||
type taskParams struct {
|
||||
taskName string
|
||||
buildPlanName string
|
||||
opts holos.BuildOpts
|
||||
}
|
||||
|
||||
func (t taskParams) id() string {
|
||||
return fmt.Sprintf("%s:%s/%s", t.opts.Path, t.buildPlanName, t.taskName)
|
||||
}
|
||||
|
||||
type generatorTask struct {
|
||||
taskParams
|
||||
generator core.Generator
|
||||
wg *sync.WaitGroup
|
||||
}
|
||||
|
||||
func (t generatorTask) run(ctx context.Context) error {
|
||||
defer t.wg.Done()
|
||||
msg := fmt.Sprintf("could not build %s", t.id())
|
||||
switch t.generator.Kind {
|
||||
case "Resources":
|
||||
if err := t.resources(); err != nil {
|
||||
return errors.Format("%s: could not generate resources: %w", msg, err)
|
||||
}
|
||||
case "Helm":
|
||||
if err := t.helm(ctx); err != nil {
|
||||
return errors.Format("%s: could not generate helm: %w", msg, err)
|
||||
}
|
||||
case "File":
|
||||
if err := t.file(); err != nil {
|
||||
return errors.Format("%s: could not generate file: %w", msg, err)
|
||||
}
|
||||
default:
|
||||
return errors.Format("%s: unsupported kind %s", msg, t.generator.Kind)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BuildPlan) Load(v cue.Value) error {
|
||||
return errors.Wrap(v.Decode(&b.BuildPlan))
|
||||
}
|
||||
|
||||
func (b *BuildPlan) file(
|
||||
log *slog.Logger,
|
||||
g core.Generator,
|
||||
store artifact.Store,
|
||||
) error {
|
||||
data, err := os.ReadFile(filepath.Join(string(b.Opts.Path), string(g.File.Source)))
|
||||
func (t generatorTask) file() error {
|
||||
data, err := os.ReadFile(filepath.Join(string(t.opts.Path), string(t.generator.File.Source)))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
if err := store.Set(string(g.Output), data); err != nil {
|
||||
if err := t.opts.Store.Set(string(t.generator.Output), data); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.Debug("set artifact: " + string(g.Output))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BuildPlan) helm(
|
||||
ctx context.Context,
|
||||
log *slog.Logger,
|
||||
g core.Generator,
|
||||
store artifact.Store,
|
||||
) error {
|
||||
chartName := g.Helm.Chart.Name
|
||||
log = log.With("chart", chartName)
|
||||
// Unnecessary? cargo cult copied from internal/cli/render/render.go
|
||||
if chartName == "" {
|
||||
return errors.New("missing chart name")
|
||||
func (t generatorTask) helm(ctx context.Context) error {
|
||||
h := t.generator.Helm
|
||||
// Cache the chart by version to pull new versions. (#273)
|
||||
cacheDir := filepath.Join(string(t.opts.Path), "vendor", t.generator.Helm.Chart.Version)
|
||||
cachePath := filepath.Join(cacheDir, filepath.Base(h.Chart.Name))
|
||||
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
username := h.Chart.Repository.Auth.Username.Value
|
||||
if username == "" {
|
||||
username = os.Getenv(h.Chart.Repository.Auth.Username.FromEnv)
|
||||
}
|
||||
password := h.Chart.Repository.Auth.Password.Value
|
||||
if password == "" {
|
||||
password = os.Getenv(h.Chart.Repository.Auth.Password.FromEnv)
|
||||
}
|
||||
|
||||
// Cache the chart by version to pull new versions. (#273)
|
||||
cacheDir := filepath.Join(string(b.Opts.Path), "vendor", g.Helm.Chart.Version)
|
||||
cachePath := filepath.Join(cacheDir, filepath.Base(chartName))
|
||||
|
||||
if _, err := os.Stat(cachePath); os.IsNotExist(err) {
|
||||
timeout, cancel := context.WithTimeout(ctx, 5*time.Minute)
|
||||
defer cancel()
|
||||
err := onceWithLock(log, timeout, cachePath, func() error {
|
||||
return b.cacheChart(ctx, log, cacheDir, g.Helm.Chart)
|
||||
})
|
||||
err := func() error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Minute)
|
||||
defer cancel()
|
||||
return onceWithLock(log, ctx, cachePath, func() error {
|
||||
return errors.Wrap(helm.PullChart(
|
||||
ctx,
|
||||
cli.New(),
|
||||
h.Chart.Name,
|
||||
h.Chart.Version,
|
||||
h.Chart.Repository.URL,
|
||||
cacheDir,
|
||||
username,
|
||||
password,
|
||||
))
|
||||
})
|
||||
}()
|
||||
if err != nil {
|
||||
return errors.Format("could not cache chart: %w", err)
|
||||
}
|
||||
@@ -269,7 +226,7 @@ func (b *BuildPlan) helm(
|
||||
}
|
||||
defer util.Remove(ctx, tempDir)
|
||||
|
||||
data, err := yaml.Marshal(g.Helm.Values)
|
||||
data, err := yaml.Marshal(t.generator.Helm.Values)
|
||||
if err != nil {
|
||||
return errors.Format("could not marshal values: %w", err)
|
||||
}
|
||||
@@ -282,22 +239,22 @@ func (b *BuildPlan) helm(
|
||||
|
||||
// Run charts
|
||||
args := []string{"template"}
|
||||
if !g.Helm.EnableHooks {
|
||||
if !t.generator.Helm.EnableHooks {
|
||||
args = append(args, "--no-hooks")
|
||||
}
|
||||
for _, apiVersion := range g.Helm.APIVersions {
|
||||
for _, apiVersion := range t.generator.Helm.APIVersions {
|
||||
args = append(args, "--api-versions", apiVersion)
|
||||
}
|
||||
if kubeVersion := g.Helm.KubeVersion; kubeVersion != "" {
|
||||
if kubeVersion := t.generator.Helm.KubeVersion; kubeVersion != "" {
|
||||
args = append(args, "--kube-version", kubeVersion)
|
||||
}
|
||||
args = append(args,
|
||||
"--include-crds",
|
||||
"--values", valuesPath,
|
||||
"--namespace", g.Helm.Namespace,
|
||||
"--namespace", t.generator.Helm.Namespace,
|
||||
"--kubeconfig", "/dev/null",
|
||||
"--version", g.Helm.Chart.Version,
|
||||
g.Helm.Chart.Release,
|
||||
"--version", t.generator.Helm.Chart.Version,
|
||||
t.generator.Helm.Chart.Release,
|
||||
cachePath,
|
||||
)
|
||||
helmOut, err := util.RunCmd(ctx, "helm", args...)
|
||||
@@ -314,36 +271,31 @@ func (b *BuildPlan) helm(
|
||||
}
|
||||
|
||||
// Set the artifact
|
||||
if err := store.Set(string(g.Output), helmOut.Stdout.Bytes()); err != nil {
|
||||
if err := t.opts.Store.Set(string(t.generator.Output), helmOut.Stdout.Bytes()); err != nil {
|
||||
return errors.Format("could not store helm output: %w", err)
|
||||
}
|
||||
log.Debug("set artifact: " + string(g.Output))
|
||||
log.Debug("set artifact: " + string(t.generator.Output))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BuildPlan) resources(
|
||||
log *slog.Logger,
|
||||
g core.Generator,
|
||||
store artifact.Store,
|
||||
) error {
|
||||
func (t generatorTask) resources() error {
|
||||
var size int
|
||||
for _, m := range g.Resources {
|
||||
for _, m := range t.generator.Resources {
|
||||
size += len(m)
|
||||
}
|
||||
list := make([]core.Resource, 0, size)
|
||||
|
||||
for _, m := range g.Resources {
|
||||
for _, m := range t.generator.Resources {
|
||||
for _, r := range m {
|
||||
list = append(list, r)
|
||||
}
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf(
|
||||
"could not generate %s for %s path %s",
|
||||
g.Output,
|
||||
b.BuildPlan.Metadata.Name,
|
||||
b.Opts.Path,
|
||||
"could not generate %s for %s",
|
||||
t.generator.Output,
|
||||
t.id(),
|
||||
)
|
||||
|
||||
buf, err := marshal(list)
|
||||
@@ -351,70 +303,220 @@ func (b *BuildPlan) resources(
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
|
||||
if err := store.Set(string(g.Output), buf.Bytes()); err != nil {
|
||||
if err := t.opts.Store.Set(string(t.generator.Output), buf.Bytes()); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
|
||||
log.Debug("set artifact " + string(g.Output))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BuildPlan) kustomize(
|
||||
ctx context.Context,
|
||||
log *slog.Logger,
|
||||
t core.Transformer,
|
||||
store artifact.Store,
|
||||
) error {
|
||||
tempDir, err := os.MkdirTemp("", "holos.kustomize")
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
defer util.Remove(ctx, tempDir)
|
||||
msg := fmt.Sprintf(
|
||||
"could not transform %s for %s path %s",
|
||||
t.Output,
|
||||
b.BuildPlan.Metadata.Name,
|
||||
b.Opts.Path,
|
||||
)
|
||||
type transformersTask struct {
|
||||
taskParams
|
||||
transformers []core.Transformer
|
||||
wg *sync.WaitGroup
|
||||
}
|
||||
|
||||
// Write the kustomization
|
||||
data, err := yaml.Marshal(t.Kustomize.Kustomization)
|
||||
if err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
path := filepath.Join(tempDir, "kustomization.yaml")
|
||||
if err := os.WriteFile(path, data, 0666); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
log.DebugContext(ctx, "wrote "+path)
|
||||
|
||||
// Write the inputs
|
||||
for _, input := range t.Inputs {
|
||||
path := string(input)
|
||||
if err := store.Save(tempDir, path); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
func (t transformersTask) run(ctx context.Context) error {
|
||||
defer t.wg.Done()
|
||||
for idx, transformer := range t.transformers {
|
||||
msg := fmt.Sprintf("could not build %s/%d", t.id(), idx)
|
||||
switch transformer.Kind {
|
||||
case "Kustomize":
|
||||
if err := kustomize(ctx, transformer, t.taskParams); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
case "Join":
|
||||
s := make([][]byte, 0, len(transformer.Inputs))
|
||||
for _, input := range transformer.Inputs {
|
||||
if data, ok := t.opts.Store.Get(string(input)); ok {
|
||||
s = append(s, data)
|
||||
} else {
|
||||
return errors.Format("%s: missing %s", msg, input)
|
||||
}
|
||||
}
|
||||
data := bytes.Join(s, []byte(transformer.Join.Separator))
|
||||
if err := t.opts.Store.Set(string(transformer.Output), data); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
default:
|
||||
return errors.Format("%s: unsupported kind %s", msg, transformer.Kind)
|
||||
}
|
||||
log.DebugContext(ctx, "wrote "+filepath.Join(tempDir, path))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Execute kustomize
|
||||
r, err := util.RunCmd(ctx, "kubectl", "kustomize", tempDir)
|
||||
if err != nil {
|
||||
kErr := r.Stderr.String()
|
||||
err = errors.Format("%s: could not run kustomize: %w", msg, err)
|
||||
log.ErrorContext(ctx, fmt.Sprintf("%s: stderr:\n%s", err.Error(), kErr), "err", err, "stderr", kErr)
|
||||
return err
|
||||
type validatorTask struct {
|
||||
taskParams
|
||||
validator core.Validator
|
||||
wg *sync.WaitGroup
|
||||
}
|
||||
|
||||
func (t validatorTask) run(ctx context.Context) error {
|
||||
defer t.wg.Done()
|
||||
msg := fmt.Sprintf("could not validate %s", t.id())
|
||||
switch kind := t.validator.Kind; kind {
|
||||
case "Command":
|
||||
if err := validate(ctx, t.validator, t.taskParams); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
default:
|
||||
return errors.Format("%s: unsupported kind %s", msg, kind)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Store the artifact
|
||||
if err := store.Set(string(t.Output), r.Stdout.Bytes()); err != nil {
|
||||
func worker(ctx context.Context, idx int, tasks chan task) error {
|
||||
log := logger.FromContext(ctx).With("worker", idx)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case task, ok := <-tasks:
|
||||
if !ok {
|
||||
log.DebugContext(ctx, fmt.Sprintf("worker %d returning: tasks chan closed", idx))
|
||||
return nil
|
||||
}
|
||||
log.DebugContext(ctx, fmt.Sprintf("worker %d task %s starting", idx, task.id()))
|
||||
if err := task.run(ctx); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.DebugContext(ctx, fmt.Sprintf("worker %d task %s finished ok", idx, task.id()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildArtifact(ctx context.Context, idx int, artifact core.Artifact, tasks chan task, buildPlanName string, opts holos.BuildOpts) error {
|
||||
var wg sync.WaitGroup
|
||||
msg := fmt.Sprintf("could not build %s artifact %s", buildPlanName, artifact.Artifact)
|
||||
// Process Generators concurrently
|
||||
for gid, gen := range artifact.Generators {
|
||||
task := generatorTask{
|
||||
taskParams: taskParams{
|
||||
taskName: fmt.Sprintf("artifact/%d/generator/%d", idx, gid),
|
||||
buildPlanName: buildPlanName,
|
||||
opts: opts,
|
||||
},
|
||||
generator: gen,
|
||||
wg: &wg,
|
||||
}
|
||||
wg.Add(1)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case tasks <- task:
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
// Process Transformers sequentially
|
||||
task := transformersTask{
|
||||
taskParams: taskParams{
|
||||
taskName: fmt.Sprintf("artifact/%d/transformers", idx),
|
||||
buildPlanName: buildPlanName,
|
||||
opts: opts,
|
||||
},
|
||||
transformers: artifact.Transformers,
|
||||
wg: &wg,
|
||||
}
|
||||
wg.Add(1)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case tasks <- task:
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
// Process Validators concurrently
|
||||
for vid, val := range artifact.Validators {
|
||||
task := validatorTask{
|
||||
taskParams: taskParams{
|
||||
taskName: fmt.Sprintf("artifact/%d/validator/%d", idx, vid),
|
||||
buildPlanName: buildPlanName,
|
||||
opts: opts,
|
||||
},
|
||||
validator: val,
|
||||
wg: &wg,
|
||||
}
|
||||
wg.Add(1)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case tasks <- task:
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
// Write the final artifact
|
||||
out := string(artifact.Artifact)
|
||||
if err := opts.Store.Save(opts.WriteTo, out); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
log.Debug("set artifact " + string(t.Output))
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, fmt.Sprintf("wrote %s", filepath.Join(opts.WriteTo, out)))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuildPlan represents a component builder.
|
||||
type BuildPlan struct {
|
||||
core.BuildPlan
|
||||
Opts holos.BuildOpts
|
||||
}
|
||||
|
||||
func (b *BuildPlan) Build(ctx context.Context) error {
|
||||
name := b.BuildPlan.Metadata.Name
|
||||
path := b.Opts.Path
|
||||
log := logger.FromContext(ctx).With("name", name, "path", path)
|
||||
|
||||
msg := fmt.Sprintf("could not build %s", name)
|
||||
if b.BuildPlan.Spec.Disabled {
|
||||
log.WarnContext(ctx, fmt.Sprintf("%s: disabled", msg))
|
||||
return nil
|
||||
}
|
||||
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
tasks := make(chan task)
|
||||
|
||||
// Start the worker pool.
|
||||
for idx := 0; idx < max(1, b.Opts.Concurrency); idx++ {
|
||||
g.Go(func() error {
|
||||
return worker(ctx, idx, tasks)
|
||||
})
|
||||
}
|
||||
|
||||
// Start one producer that fans out to one pipeline per artifact.
|
||||
g.Go(func() error {
|
||||
// Close the tasks chan when the producer returns.
|
||||
defer func() {
|
||||
log.DebugContext(ctx, "producer returning: closing tasks chan")
|
||||
close(tasks)
|
||||
}()
|
||||
// Separate error group for producers.
|
||||
p, ctx := errgroup.WithContext(ctx)
|
||||
for idx, a := range b.BuildPlan.Spec.Artifacts {
|
||||
p.Go(func() error {
|
||||
return buildArtifact(ctx, idx, a, tasks, b.Metadata.Name, b.Opts)
|
||||
})
|
||||
}
|
||||
// Wait on producers to finish.
|
||||
return errors.Wrap(p.Wait())
|
||||
})
|
||||
|
||||
// Wait on workers to finish.
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
func (b *BuildPlan) Export(idx int, encoder holos.OrderedEncoder) error {
|
||||
if err := encoder.Encode(idx, &b.BuildPlan); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BuildPlan) Load(v cue.Value) error {
|
||||
return errors.Wrap(v.Decode(&b.BuildPlan))
|
||||
}
|
||||
|
||||
func marshal(list []core.Resource) (buf bytes.Buffer, err error) {
|
||||
encoder := yaml.NewEncoder(&buf)
|
||||
defer encoder.Close()
|
||||
@@ -427,95 +529,6 @@ func marshal(list []core.Resource) (buf bytes.Buffer, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// cacheChart stores a cached copy of Chart in the chart subdirectory of path.
|
||||
//
|
||||
// We assume the only method responsible for writing to chartDir is cacheChart
|
||||
// itself. cacheChart runs concurrently when rendering a platform.
|
||||
//
|
||||
// We rely on the atomicity of moving temporary directories into place on the
|
||||
// same filesystem via os.Rename. If a syscall.EEXIST error occurs during
|
||||
// renaming, it indicates that the cached chart already exists, which is
|
||||
// expected when this function is called concurrently.
|
||||
//
|
||||
// TODO(jeff): Break the dependency on v1alpha5, make it work across versions as
|
||||
// a utility function.
|
||||
func (b *BuildPlan) cacheChart(
|
||||
ctx context.Context,
|
||||
log *slog.Logger,
|
||||
cacheDir string,
|
||||
chart core.Chart,
|
||||
) error {
|
||||
// Add repositories
|
||||
repo := chart.Repository
|
||||
stderr := b.Opts.Stderr
|
||||
if repo.URL == "" {
|
||||
// repo update not needed for oci charts so this is debug instead of warn.
|
||||
log.DebugContext(ctx, "skipped helm repo add and update: repo url is empty")
|
||||
} else {
|
||||
if _, err := util.RunCmdW(ctx, stderr, "helm", "repo", "add", repo.Name, repo.URL); err != nil {
|
||||
return errors.Format("could not run helm repo add: %w", err)
|
||||
}
|
||||
if _, err := util.RunCmdW(ctx, stderr, "helm", "repo", "update", repo.Name); err != nil {
|
||||
return errors.Format("could not run helm repo update: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
cacheTemp, err := os.MkdirTemp(cacheDir, chart.Name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
defer util.Remove(ctx, cacheTemp)
|
||||
|
||||
cn := chart.Name
|
||||
if chart.Repository.Name != "" {
|
||||
cn = fmt.Sprintf("%s/%s", chart.Repository.Name, chart.Name)
|
||||
}
|
||||
helmOut, err := util.RunCmdW(ctx, stderr, "helm", "pull", "--destination", cacheTemp, "--untar=true", "--version", chart.Version, cn)
|
||||
if err != nil {
|
||||
stderr := helmOut.Stderr.String()
|
||||
lines := strings.Split(stderr, "\n")
|
||||
for _, line := range lines {
|
||||
log.DebugContext(ctx, line)
|
||||
if strings.HasPrefix(line, "Error:") {
|
||||
err = fmt.Errorf("%s: %w", line, err)
|
||||
}
|
||||
}
|
||||
return errors.Format("could not run helm pull: %w", err)
|
||||
}
|
||||
log.Debug("helm pull", "stdout", helmOut.Stdout, "stderr", helmOut.Stderr)
|
||||
|
||||
items, err := os.ReadDir(cacheTemp)
|
||||
if err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not read directory: %w", err))
|
||||
}
|
||||
if len(items) != 1 {
|
||||
return errors.Format("want: exactly one item, have: %+v", items)
|
||||
}
|
||||
item := items[0]
|
||||
|
||||
src := filepath.Join(cacheTemp, item.Name())
|
||||
dst := filepath.Join(cacheDir, chart.Name)
|
||||
if err := os.Rename(src, dst); err != nil {
|
||||
var linkErr *os.LinkError
|
||||
if errors.As(err, &linkErr) && errors.Is(linkErr.Err, syscall.EEXIST) {
|
||||
log.DebugContext(ctx, "cache already exists", "chart", chart.Name, "chart_version", chart.Version, "path", dst)
|
||||
} else {
|
||||
return errors.Wrap(fmt.Errorf("could not rename: %w", err))
|
||||
}
|
||||
} else {
|
||||
log.DebugContext(ctx, fmt.Sprintf("renamed %s to %s", src, dst), "src", src, "dst", dst)
|
||||
}
|
||||
|
||||
log.InfoContext(ctx,
|
||||
fmt.Sprintf("cached %s %s", chart.Name, chart.Version),
|
||||
"chart", chart.Name,
|
||||
"chart_version", chart.Version,
|
||||
"path", dst,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// onceWithLock obtains a filesystem lock with mkdir, then executes fn. If the
|
||||
// lock is already locked, onceWithLock waits for it to be released then returns
|
||||
// without calling fn.
|
||||
@@ -564,3 +577,83 @@ func onceWithLock(log *slog.Logger, ctx context.Context, path string, fn func()
|
||||
// Unexpected error
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
func kustomize(ctx context.Context, t core.Transformer, p taskParams) error {
|
||||
tempDir, err := os.MkdirTemp("", "holos.kustomize")
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
defer util.Remove(ctx, tempDir)
|
||||
msg := fmt.Sprintf(
|
||||
"could not transform %s for %s path %s",
|
||||
t.Output,
|
||||
p.buildPlanName,
|
||||
p.opts.Path,
|
||||
)
|
||||
|
||||
// Write the kustomization
|
||||
data, err := yaml.Marshal(t.Kustomize.Kustomization)
|
||||
if err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
path := filepath.Join(tempDir, "kustomization.yaml")
|
||||
if err := os.WriteFile(path, data, 0666); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
|
||||
// Write the inputs
|
||||
for _, input := range t.Inputs {
|
||||
path := string(input)
|
||||
if err := p.opts.Store.Save(tempDir, path); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Execute kustomize
|
||||
r, err := util.RunCmdW(ctx, p.opts.Stderr, "kubectl", "kustomize", tempDir)
|
||||
if err != nil {
|
||||
return errors.Format("%s: could not run kustomize: %w", msg, err)
|
||||
}
|
||||
|
||||
// Store the artifact
|
||||
if err := p.opts.Store.Set(string(t.Output), r.Stdout.Bytes()); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validate(ctx context.Context, validator core.Validator, p taskParams) error {
|
||||
store := p.opts.Store
|
||||
tempDir, err := os.MkdirTemp("", "holos.validate")
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// defer util.Remove(ctx, tempDir)
|
||||
msg := fmt.Sprintf("could not validate %s", p.id())
|
||||
|
||||
// Write the inputs
|
||||
for _, input := range validator.Inputs {
|
||||
path := string(input)
|
||||
if err := store.Save(tempDir, path); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(validator.Command.Args) < 1 {
|
||||
return errors.Format("%s: command args length must be at least 1", msg)
|
||||
}
|
||||
size := len(validator.Command.Args) + len(validator.Inputs)
|
||||
args := make([]string, 0, size)
|
||||
args = append(args, validator.Command.Args...)
|
||||
for _, input := range validator.Inputs {
|
||||
args = append(args, filepath.Join(tempDir, string(input)))
|
||||
}
|
||||
|
||||
// Execute the validator
|
||||
if _, err = util.RunCmdA(ctx, p.opts.Stderr, args[0], args[1:]...); err != nil {
|
||||
return errors.Format("%s: %w", msg, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,71 +1 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
cue "cuelang.org/go/cue/errors"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
)
|
||||
|
||||
// MakeMain makes a main function for the cli or tests.
|
||||
func MakeMain(options ...holos.Option) func() int {
|
||||
return func() (exitCode int) {
|
||||
cfg := holos.New(options...)
|
||||
slog.SetDefault(cfg.Logger())
|
||||
ctx := context.Background()
|
||||
feature := &holos.EnvFlagger{}
|
||||
if err := New(cfg, feature).ExecuteContext(ctx); err != nil {
|
||||
return HandleError(ctx, err, cfg)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// HandleError is the top level error handler that unwraps and logs errors.
|
||||
func HandleError(ctx context.Context, err error, hc *holos.Config) (exitCode int) {
|
||||
// Connect errors have codes, log them.
|
||||
log := hc.NewTopLevelLogger().With("code", connect.CodeOf(err))
|
||||
var cueErr cue.Error
|
||||
var errAt *errors.ErrorAt
|
||||
|
||||
if errors.As(err, &errAt) {
|
||||
loc := errAt.Source.Loc()
|
||||
err2 := errAt.Unwrap()
|
||||
log.ErrorContext(ctx, fmt.Sprintf("could not run: %s at %s", err2, loc), "err", err2, "loc", loc)
|
||||
} else {
|
||||
log.ErrorContext(ctx, fmt.Sprintf("could not run: %s", err), "err", err)
|
||||
}
|
||||
|
||||
// cue errors are bundled up as a list and refer to multiple files / lines.
|
||||
if errors.As(err, &cueErr) {
|
||||
msg := cue.Details(cueErr, nil)
|
||||
if _, err := fmt.Fprint(hc.Stderr(), msg); err != nil {
|
||||
log.ErrorContext(ctx, "could not write CUE error details: "+err.Error(), "err", err)
|
||||
}
|
||||
}
|
||||
// connect errors have details and codes.
|
||||
// Refer to https://connectrpc.com/docs/go/errors
|
||||
if connectErr := new(connect.Error); errors.As(err, &connectErr) {
|
||||
for _, detail := range connectErr.Details() {
|
||||
msg, valueErr := detail.Value()
|
||||
if valueErr != nil {
|
||||
log.WarnContext(ctx, "could not decode error detail", "err", err, "type", detail.Type(), "note", "this usually means we don't have the schema for the protobuf message type")
|
||||
continue
|
||||
}
|
||||
if info, ok := msg.(*errdetails.ErrorInfo); ok {
|
||||
logDetail := log.With("reason", info.GetReason(), "domain", info.GetDomain())
|
||||
for k, v := range info.GetMetadata() {
|
||||
logDetail = logDetail.With(k, v)
|
||||
}
|
||||
logDetail.ErrorContext(ctx, info.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user