Compare commits

...

40 Commits

Author SHA1 Message Date
Jeff McCune
e346e10c07 v0.91.0 2024-07-21 21:23:48 -07:00
Jeff McCune
f1dc54650e builder: fill #UserData from userdata/**/*.json (#210)
Now that we have multi-platform images, we need a way to easily deploy
them.  This involves changing the image tag.  kustomize edit is often
used to bump image tags, but we can do better providing it directly in
the unified CUE configuration.

This patch modifies the builder to unify user data *.json files
recursively under userdata/ into the #UserData definition of the holos
entrypoint.

This is to support automation that writes simple json files to version
control, executes holos render platform, then commits and pushes the
results for git ops to take over deployment.

The make deploy target is the reason this change exists, to demonstrate
how to automatically deploy a new container image.
2024-07-21 21:22:22 -07:00
Jeff McCune
9ed5d588d0 makefile: make image for Multi-Platform Images (#209)
Use ko to build a multi-platform image.

Closes: #209
2024-07-21 20:12:09 -07:00
Nate McCurdy
6eb24faf63 cli/delete: improve platform deletion help text and output (#200)
- Clarify help text to indicate one or more platform IDs as arguments.
- Show platform name and ID in `delete platform` output for clarity.
2024-07-21 09:55:12 -07:00
Jeff McCune
daa13906b5 add make tag target 2024-07-21 09:33:24 -07:00
Jeff McCune
b2ce455aa2 generate/platform: use platform metadata as source of truth (#200)
This patch addresses Nate's feedback that it's difficult to know what
platform is being operated on.

Previously it wasn't clear where the platform id used for push and pull
comes from.  The source of truth is the platform.metadata.json file
created when the platform is first generated using `holos generate
platform k3d`.

This patch removes the platformId field from the platform.config.json
file, renames the platform.config.json file to platform.model.json and
renames the internal symbols to match the domain language of "Platform
Model" instead of the less clear "config"

This patch also changes the API between holos and CUE to use the proto
json imported from the proto file instead of generated from the go code
generated from the proto file.  The purpose is to ensure protojson
encoding is used end to end.

Default log handler:

The patch also changes the default log output to print only the message
to stderr.  This addresses similar feedback from both Gary and Nate that
the output is skipped over because it feels like internal debug logs.

We still want 100% of output to go through the logger so we can ensure
each line can be made into valid json.  Info messages however are meant
for the user and all other attributes can be stripped off by default.
If additional source location is necessary, enable the text or json
output format.

Protobuf JSON:

This patch modifies the API contract between holos and CUE to ensure
data is exchanged exclusively using protojson.  This is necessary
because protobuf has a canonical json format which is not compatible
with the go json package struct tags.  When Holos handles a protobuf
message, it must marshal and unmarshal it using the protojson package.

Similarly, when importing protobuf messages into CUE, we must use `cue
import` instead of `cue go get` so that the canonical format is used
instead of the invalid go json struct tags.

Finally, when a Go struct like v1alpha1.Form is used to represent data
defined in cue which contains a nested protobuf message, Holos should
use a cue.Value to lookup the nested path, marshal it into json bytes,
then unmarshal it again using protojson.
2024-07-21 09:31:09 -07:00
Jeff McCune
90629b84b5 cli/delete: delete platform by uuid (#200)
Previously there was no way to delete a platform.  This patch adds a
basic delete subcommand which deletes platforms by their id using the
rpc api.

    ❯ holos get platform
    NAME         DESCRIPTION        AGE    ID
    k3d          Holos Local k3d    20h    0190c78a-4027-7a7e-82d0-0b9f400f4bc9
    k3d2         Holos Local k3d    20h    0190c7b3-382b-7212-81d6-ffcfc4a3fe7e
    k3dasdf      Holos Local k3d    20h    0190c7b3-728a-7212-b56d-2d2edf389003
    k3d9         Holos Local k3d    20h    0190c7b8-4c4e-7cea-9d3d-a6b9434ae438
    k3d-8581     Holos Local k3d    20h    0190c7ba-1de9-7cea-bff8-f15b51a56bdd
    k3d-13974    Holos Local k3d    20h    0190c7ba-5833-7cea-b863-8e5ffb926810
    k3d-20760    Holos Local k3d    19h    0190c7ba-7a12-7cea-a350-d55b4817d8bc

    ❯ holos delete platform 0190c7ba-1de9-7cea-bff8-f15b51a56bdd 0190c7ba-5833-7cea-b863-8e5ffb926810 0190c7ba-7a12-7cea-a350-d55b4817d8bc
    deleted platform k3d-8581
    deleted platform k3d-13974
    deleted platform k3d-20760
2024-07-19 09:54:48 -07:00
Jeff McCune
7f077f5347 cli/get: list platforms (#200)
Previously there was no way to get/list platforms.  This patch adds a
basic get subcommand with list as an alias to get the platforms
currently defined in the organization.

    ❯ holos get platform
    NAME         DESCRIPTION        AGE    ID
    k3d          Holos Local k3d    18h    0190c78a-4027-7a7e-82d0-0b9f400f4bc9
    k3d2         Holos Local k3d    17h    0190c7b3-382b-7212-81d6-ffcfc4a3fe7e
    k3dasdf      Holos Local k3d    17h    0190c7b3-728a-7212-b56d-2d2edf389003
    k3d9         Holos Local k3d    17h    0190c7b8-4c4e-7cea-9d3d-a6b9434ae438
    k3d-8581     Holos Local k3d    17h    0190c7ba-1de9-7cea-bff8-f15b51a56bdd
    k3d-13974    Holos Local k3d    17h    0190c7ba-5833-7cea-b863-8e5ffb926810
    k3d-20760    Holos Local k3d    17h    0190c7ba-7a12-7cea-a350-d55b4817d8bc
    k3d-13916    Holos Local k3d    17h    0190c7ba-8313-7cea-be37-41491c95ae79
    k3d-26154    Holos Local k3d    17h    0190c7ba-a117-7cea-8229-ce27da84135e

    ❯ holos get platform foo
    7:16AM ERR could not execute version=0.89.1 code=unknown err="not found"

    ❯ holos get platform foo k3d
    NAME    DESCRIPTION        AGE    ID
    k3d     Holos Local k3d    18h    0190c78a-4027-7a7e-82d0-0b9f400f4bc9
2024-07-19 07:16:43 -07:00
Jeff McCune
327193215b version: 0.89.1 2024-07-18 14:42:24 -07:00
Jeff McCune
b98b5cae3f PlatformService: do nothing when platform already exists
Previously the CreatePlatform rpc wrote over all fields when the
platform already exists.  This is surprising and basically the
UpdatePlatform rpc.

This patch changes the behavior to do nothing except set the
already_exists flag in the response message.

Users who have the use case of needing to know if the creation actually
created a new resource should use the API to check the already_exists
flag.  The CLI has no affordance for this other than parsing the log
messages.
2024-07-18 14:27:03 -07:00
Jeff McCune
ddba69517f version 0.89.0 2024-07-18 12:00:49 -07:00
Jeff McCune
e28642bca7 platform service: make (#205) create platform should be idempotent
Previously holos.platform.v1alpha1.PlatformService.CreatePlatform
returns an error for a request to create a platform of the same name as
an existing platform.

    holos create platform --name k3d --display-name "Try Holos Locally"

    8:00AM ERR could not execute version=0.87.2 code=failed_precondition
    err="failed_precondition: platform.go:55: ent: constraint failed:
    ERROR: duplicate key value violates unique constraint
    \"platform_org_id_name\" (SQLSTATE 23505)" loc=client.go:138

This patch makes the CreatePlatform rpc idempotent using the upsert API.
The already_exists bool field is added to CreatePlatformResponse
response to indicate to the client if the platform already exists or
not.

Result:

    holos create platform --display-name "Holos Local" --name k3d10

    11:53AM INF create.go:56 created platform k3d10 version=0.87.2
    name=k3d10 id=0190c731-1808-7e7d-9ccb-3d17434d0055
    org=0190c6d6-4974-7733-9f7b-5d759a3e60e7 exists=false

    holos create platform --display-name "Holos Local" --name k3d10

    11:53AM INF create.go:56 updated platform k3d10 version=0.87.2
    name=k3d10 id=0190c731-1808-7e7d-9ccb-3d17434d0055
    org=0190c6d6-4974-7733-9f7b-5d759a3e60e7 exists=true
2024-07-18 11:53:51 -07:00
Jeff McCune
dceb37b7ab tilt: run holos server locally in k3d (#205)
Previously I developed holos server in the dev-holos namespace of a
remote cluster.  This patch updates the Tilt configs to develop locally
against k3d quickly and easily.

The database is a CNPG database which replaces PGO.  This is simpler and
ligher weight, one container in one pod.  CNPG has no repo host like PGO
has.
2024-07-18 10:24:45 -07:00
Jeff McCune
f6340ea4fe runbooks: recover zitadel with cnpg
Replaces the previous PGO runbook, we no longer use PGO and use CNPG
instead.
2024-07-18 07:58:58 -07:00
Jeff McCune
3845174738 server: add holos server init subcommand for migration (#204)
When starting holos server from the production Deployment, pgbouncer
blocks the automatic migration on startup.

```json
{
  "time": "2024-07-16T16:35:52.54507682-07:00",
  "level": "ERROR",
  "msg": "could not execute",
  "version": "0.87.2",
  "code": "unknown",
  "err": "sql/schema: create \"users\" table: ERROR: permission denied for schema public (SQLSTATE 42501)",
  "loc": "cli.go:82"
}
```

This patch separates automatic migration into a `holos server init`
subcommand intended for use in a Job.

Closes: #204
2024-07-16 17:55:40 -07:00
Jeff McCune
f0bc21a606 tilt: local development using k3d (#200)
Previously, the Tiltfile was hard-wired to Jeff's development
environment on the k2 cluster on-prem.  This doesn't work for other
contributors.

This patch fixes the problem by re-using the [Try Holos Locally][1]
documentation to create a local development enironment.  This has a
number of benefits.  The evaluation documentation will be kept up to
date because it doubles as our development environment.  Developing
locally is preferrable to developing in a remote cluster.  Hostnames and
URL's can be constant, e.g. https://app.holos.localhost/ for local dev
and https://app.holos.run/ for production.  We don't need to push to a
remote container registry, k3d has a local registry built in that works
with Tilt.

The only difference presently between evaluation and development when
following the local/k3d doc is the addition of a local registry.

With this patch holos starts up and is accessible at
https://app.holos.localhost/

[1]: https://holos.run/docs/tutorial/local/k3d/
2024-07-15 17:08:33 -07:00
Jeff McCune
6d0e48fccb github/workflows: disable test workflow
until we allocate time to fix it
2024-07-15 12:20:13 -07:00
Nate McCurdy
f5035ce699 docs/website: Touch up the k3d tutorial
This applies various grammar, formatting, and flow improvements to the
local k3d tutorial steps based on running through it from start to
finish.

This also removes the Go code responsible for embedding the website into
`holos`, which isn't needed since the site is hosted on Cloudflare
Pages.
2024-07-15 11:37:23 -07:00
Jeff McCune
3c694d2a92 doc/website: final first pass at local k3d (#199)
Link it off the nav, footer, and sidebar.  Follow up with another task
to reorganize and slim it down.

Closes: #199
2024-07-14 19:45:56 -07:00
Jeff McCune
b8592b0b72 doc/website: add holos social card (#199)
Made it in preview using a background png from https://social.cards/ and
converting our logo.

    mogrify -background none -resize 1200x -format png logo.svg
2024-07-14 14:38:17 -07:00
Jeff McCune
cf2289ef19 doc/website: make try holos next after intro (#199)
Previously the intro page linked next to the glossary.  This patch makes
the try holos locally page immediately follow the introduction page.
2024-07-14 14:06:55 -07:00
Jeff McCune
5e5b9c97d4 doc/website: fix link and mermaid colors (#199)
This patch fixes up the link colors and mermaid diagrams to look better
in both light and dark mode.  This may not be the final result but it
moves in the right direction.

Links are now blue with a visible line on hover.
2024-07-14 13:34:02 -07:00
Jeff McCune
a19e0ff3f3 doc/website: fix spelling errors (#199)
This patch adds cspell over doc/md to the make lint task and fixes
existing spelling errors in the documentation.
2024-07-14 12:48:31 -07:00
Jeff McCune
ac632cb407 doc/website: sync ArgoCD Applications automatically (#199)
Previously the guide did not cover reconciling holos platform components
with GitOps.  This patch adds instructions on how to apply the
application resources, review the diff, sync manually, and finally
enable automatic sync using CUE's struct merge feature.
2024-07-14 10:02:22 -07:00
Jeff McCune
154bbabf01 doc/website: add argocd to k3d platform (#199)
Previously there is no web app except httpbin in the k3d platform.  This
commit adds ArgoCD with an httproute and authorization policy at the
mesh layer.  The application layer authenticates against a separate
oidc client id in the same issuer the mesh uses to demonstrate zero
trust and compatibility between the application and platform layers.

With this patch the user can authenticate and log in, but applications
are not configured.  The user has no roles in ArgoCD either, rbac needs
to be configured properly for the getting started guide.
2024-07-14 06:56:15 -07:00
Jeff McCune
95e45d59cb doc/website: clarify why we use httpbin (#199)
Useful to inspect request headers from the perspective of the backend.
2024-07-13 19:50:26 -07:00
Jeff McCune
a45abedd32 doc/website: touch up process after a run through (#199)
Clean up, touch up.
2024-07-13 19:36:08 -07:00
Jeff McCune
a644b1181b doc/website: move rendering section to k3d (#199)
Previously the intro was spread out.  This patch focuses the tutorial
solely onto the k3d process.
2024-07-13 14:24:44 -07:00
Jeff McCune
861b552b0b doc/website: add k3d authproxy and authpolicy (#199)
This patch adds the authproxy and authpolicy holos components to the k3d
platform for local evaluation.  This combination implements a basic Zero
Trust security model.  The httpbin backend service is protected with
authenication and authorization at the platform level without any
changes to the backend service.

The client id and project are static because they're defined centrally
in https://login.holos.run to avoid needing to setup a full identity
provider locally in k3d.

With this patch authentication and authorization work from both the web
browser and from the command line with curl using the token provided by
the holos cli.
2024-07-13 14:09:41 -07:00
Jeff McCune
5d0212e832 doc/website: local k3d with httpbin working (#199)
Previously the local k3d tutorial doesn't expose any services to verify
the local certificate and the local dns changes work as expected.

This patch adds instructions and modifies the k3d platform to work with
a local mkcert certificate.  A ClusterIssuer is configured to issue
Certificate resources using the ca private key created my mkcert.

With this patch, following the instructions results in a working and
trusted httpbin resource at https://httpbin.holos.localhost  This works
both in Chrome and curl on the command line.
2024-07-13 07:35:44 -07:00
Jeff McCune
9f434928d6 doc/website: add istio gateway and local ca (#199)
This patch adds a script to install a local CA and configure cert
manager to issue certs similar to how it issues certs using LetsEncrypt
in a real cluster.
2024-07-12 10:19:30 -07:00
Jeff McCune
5b1fa4b046 doc/website: add helm chart cue example (#199)
This patch adds an example of how Holos uses unmodified upstream helm
charts to integrate software projects into a platform.
2024-07-11 21:27:29 -07:00
Jeff McCune
ae4614c35b internal/generate: add k3d platform and tutorial (#199)
Previously there is no way to evaluate Holos on local host.  This is a
problem because it's a high barrier to entry to setup a full blown GKE
and EKS cluster to evaluate the reference platform.

This patch adds a minimal, but useful, k3d platform which deploys to a
single local k3d cluster.  The purpose is to provide a shorter on ramp
to see the value of ArgoCD integrated with Istio to provide a zero trust
auth proxy.

The intentional trade off is to provide a less-holistic k3d platform
with a faster on-ramp to learn about the value the more-holistic holos
platform.

With this patch the documentation is correct and the platform renders
fully.  The user doesn't need to provide any Platform Model values, the
default suffice.

For the ArgoCD client ID, we'll use https://login.holos.run as the
issuer instead of building a new OIDC issuer inside of k3d, which would
create significant friction.
2024-07-11 21:07:05 -07:00
Jeff McCune
e99a00f0a1 doc/website: fix API reference docs links in header and footer
Previously the API nav link went to the CLI docs which was weird.
Should go to the current API reference docs.
2024-07-11 11:36:30 -07:00
Jeff McCune
e89dcb9783 doc/website: tagline: The Platform Operating System
Gary and I chatted about this yesterday.  Best tagline we've come up
with so far driving at the analogy with a debian distribution.
2024-07-11 10:44:13 -07:00
Jeff McCune
05806cb439 doc/website: add rendering pipeline diagram
This patch adds a diagram that gives an overview of the holos rendering
pipeline.  This is an importantn concept to understand when working with
holos components.

Note this probably should not go in the Overview, which is intended only
to give a sense of what getting started looks like.  Move it to the
render page when we add it.
2024-07-07 14:16:46 -07:00
Jeff McCune
bfb8458bcb doc/website: draft architecture
This patch fills out some of the architecture page.  Not totally happy
with it yet but it's a start.
2024-07-07 13:28:15 -07:00
Jeff McCune
55d4033116 doc/website: add mermaid architecture diagram
Previously there are no diagrams in the documentation.  This patch wires
up mermaid for use in code blocks in the markdown files.  A minimal
diagram is added to verify mermaid works but it's not the final diagram.
2024-07-07 08:54:22 -07:00
Jeff McCune
276dc95029 doc/website: tweak observability feature
Madison says it sounds weird.
2024-07-06 16:57:16 -07:00
Jeff McCune
c473321817 doc/website: add holos features on landing page
Previously the Docusaurus features examples were still in place on the
home page.  This patch replaces the homepage features with Holos
specific features and illustrations from undraw.

Refer to https://undraw.co/search
2024-07-06 16:11:07 -07:00
198 changed files with 28700 additions and 2152 deletions

76
.cspell.json Normal file
View File

@@ -0,0 +1,76 @@
{
"version": "0.2",
"language": "en",
"enableFiletypes": [
"mdx"
],
"words": [
"applicationset",
"argoproj",
"authpolicy",
"authproxy",
"authroutes",
"buildplan",
"cainjector",
"clusterissuer",
"cookiesecret",
"coredns",
"crds",
"crossplane",
"cuecontext",
"cuelang",
"dnsmasq",
"dscacheutil",
"entgo",
"errgroup",
"fieldmaskpb",
"flushcache",
"gitops",
"grpcreflect",
"holos",
"httpbin",
"Infima",
"isatty",
"istiod",
"jetstack",
"killall",
"kubeadm",
"kubeconfig",
"Kustomization",
"kustomize",
"ldflags",
"libnss",
"loadbalancer",
"mattn",
"mxcl",
"myhostname",
"nameserver",
"organizationconnect",
"orgid",
"otelconnect",
"Parentspanid",
"platformconnect",
"promhttp",
"protojson",
"putenv",
"quickstart",
"retryable",
"spanid",
"spiffe",
"startupapicheck",
"structpb",
"systemconnect",
"tablewriter",
"Tiltfile",
"timestamppb",
"Traceid",
"traefik",
"uibutton",
"Upsert",
"urandom",
"userconnect",
"userdata",
"zerolog",
"zitadel"
]
}

6
.gitignore vendored
View File

@@ -7,3 +7,9 @@ coverage.out
/deploy/
.vscode/
tmp/
.DS_*
# In case we run through the tutorial in this directory.
/holos-k3d/
/holos-infra/
node_modules/

12
.ko.yaml Normal file
View File

@@ -0,0 +1,12 @@
# Refer to https://ko.build/configuration/#overriding-go-build-settings
builds:
- id: holos
dir: .
main: ./cmd/holos
env:
- GOPRIVATE=github.com/holos-run/\*
ldflags:
- -s
- -w
- -X
- github.com/holos-run/holos/version.GitDescribe={{.Env.GIT_DETAIL}}{{.Env.GIT_SUFFIX}}

View File

@@ -48,6 +48,10 @@ bumpmajor: ## Bump the major version.
show-version: ## Print the full version.
@echo $(VERSION)
.PHONY: tag
tag: ## Tag a release
git tag v$(VERSION)
.PHONY: tidy
tidy: ## Tidy go module.
go mod tidy
@@ -72,6 +76,11 @@ build: ## Build holos executable.
@echo "GOPATH=${GOPATH}"
go build -trimpath -o bin/$(BIN_NAME) -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/$(BIN_NAME)
linux: ## Build holos executable for tilt.
@echo "building ${BIN_NAME}.linux ${VERSION}"
@echo "GOPATH=${GOPATH}"
GOOS=linux go build -trimpath -o bin/$(BIN_NAME).linux -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/$(BIN_NAME)
.PHONY: install
install: build ## Install holos to GOPATH/bin
install bin/$(BIN_NAME) $(shell go env GOPATH)/bin/$(BIN_NAME)
@@ -89,6 +98,7 @@ lint: ## Run linters.
buf lint
cd internal/frontend/holos && ng lint
golangci-lint run
./hack/cspell
.PHONY: coverage
coverage: test ## Test coverage profile.
@@ -111,6 +121,7 @@ go-deps: ## tool versions pinned in tools.go
go install honnef.co/go/tools/cmd/staticcheck
go install golang.org/x/tools/cmd/godoc
go install github.com/princjef/gomarkdoc/cmd/gomarkdoc
go install github.com/google/ko
# curl https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash
.PHONY: frontend-deps
@@ -126,10 +137,13 @@ frontend-deps: ## Install Angular deps for go generate
website-deps: ## Install Docusaurus deps for go generate
cd doc/website && npm install
.PHONY: image
image: build ## Docker image build
docker build . -t ${DOCKER_REPO}:v$(shell ./bin/holos --version)
docker push ${DOCKER_REPO}:v$(shell ./bin/holos --version)
.PHONY: image # refer to .ko.yaml as well
image: ## Container image build
KO_DOCKER_REPO=$(DOCKER_REPO) GIT_DETAIL=$(GIT_DETAIL) GIT_SUFFIX=$(GIT_SUFFIX) ko build --platform=all --bare ./cmd/holos --tags $(GIT_DETAIL)$(GIT_SUFFIX)
.PHONY: deploy
deploy: image ## DEPLOY TO PROD
GIT_DETAIL=$(GIT_DETAIL) GIT_SUFFIX=$(GIT_SUFFIX) bash ./hack/deploy
.PHONY: website
website: ## Build website

237
Tiltfile
View File

@@ -1,5 +1,5 @@
# -*- mode: Python -*-
# This Tiltfile manages a Go project with live leload in Kubernetes
# This Tiltfile manages a Go project with live reload in Kubernetes
listen_port = 3000
metrics_port = 9090
@@ -8,56 +8,21 @@ metrics_port = 9090
if os.getenv('TILT_WRAPPER') != '1':
fail("could not run, ./hack/tilt/bin/tilt was not used to start tilt")
# AWS Account to work in
aws_account = '271053619184'
aws_region = 'us-east-2'
# Resource ids
holos_backend = 'Holos Backend'
pg_admin = 'pgAdmin'
pg_cluster = 'PostgresCluster'
pg_svc = 'Database Pod'
holos_backend = 'Holos Server'
compile_id = 'Go Build'
auth_id = 'Auth Policy'
lint_id = 'Run Linters'
tests_id = 'Run Tests'
# PostgresCluster resource name in k8s
pg_cluster_name = 'holos'
# Database name inside the PostgresCluster
pg_database_name = 'holos'
# PGAdmin name
pg_admin_name = 'pgadmin'
# Default Registry.
# See: https://github.com/tilt-dev/tilt.build/blob/master/docs/choosing_clusters.md#manual-configuration
# Note, Tilt will append the image name to the registry uri path
default_registry('{account}.dkr.ecr.{region}.amazonaws.com/holos-run/holos-server'.format(account=aws_account, region=aws_region))
# default_registry('{account}.dkr.ecr.{region}.amazonaws.com/holos-run/holos'.format(account=aws_account, region=aws_region))
# Set a name prefix specific to the user. Multiple developers share the tilt-holos namespace.
developer = os.getenv('USER')
holos_server = 'holos'
# See ./hack/tilt/bin/tilt
namespace = os.getenv('NAMESPACE')
# We always develop against the k1 cluster.
# We always develop against the k3d-workload cluster
os.putenv('KUBECONFIG', os.path.abspath('./hack/tilt/kubeconfig'))
# The context defined in ./hack/tilt/kubeconfig
allow_k8s_contexts('sso@k1')
allow_k8s_contexts('sso@k2')
allow_k8s_contexts('sso@k3')
allow_k8s_contexts('sso@k4')
allow_k8s_contexts('sso@k5')
# PG db connection for localhost -> k8s port-forward
os.putenv('PGHOST', 'localhost')
os.putenv('PGPORT', '15432')
# We always develop in the dev aws account.
os.putenv('AWS_CONFIG_FILE', os.path.abspath('./hack/tilt/aws.config'))
os.putenv('AWS_ACCOUNT', aws_account)
os.putenv('AWS_DEFAULT_REGION', aws_region)
os.putenv('AWS_PROFILE', 'dev-holos')
os.putenv('AWS_SDK_LOAD_CONFIG', '1')
# Authenticate to AWS ECR when tilt up is run by the developer
local_resource('AWS Credentials', './hack/tilt/aws-login.sh', auto_init=True)
# Extensions are open-source, pre-packaged functions that extend Tilt
#
@@ -81,8 +46,8 @@ developer_paths = [
'./service/holos',
]
# Builds the holos-server executable
local_resource(compile_id, 'make build', deps=developer_paths)
# Builds the holos executable GOOS=linux
local_resource(compile_id, 'make linux', deps=developer_paths)
# Build Docker image
# Tilt will automatically associate image builds with the resource(s)
@@ -91,84 +56,33 @@ local_resource(compile_id, 'make build', deps=developer_paths)
# More info: https://docs.tilt.dev/api.html#api.docker_build
#
docker_build_with_restart(
'holos',
'k3d-registry.holos.localhost:5100/holos',
context='.',
entrypoint=[
'/app/bin/holos',
'/app/bin/holos.linux',
'server',
'--listen-port={}'.format(listen_port),
'--oidc-issuer=https://login.ois.run',
'--oidc-audience=262096764402729854@holos_platform',
'--log-level=debug',
'--metrics-port={}'.format(metrics_port),
'--log-format=text',
'--oidc-issuer=https://login.holos.run',
'--oidc-audience=275804490387516853@holos_quickstart', # auth proxy
'--oidc-audience=270319630705329162@holos_platform', # holos cli
],
dockerfile='./hack/tilt/Dockerfile',
dockerfile='./Dockerfile',
only=['./bin'],
# (Recommended) Updating a running container in-place
# https://docs.tilt.dev/live_update_reference.html
live_update=[
# Sync files from host to container
sync('./bin', '/app/bin'),
# Wait for aws-login https://github.com/tilt-dev/tilt/issues/3048
sync('./tilt/aws-login.last', '/dev/null'),
# Execute commands in the container when paths change
# run('/app/hack/codegen.sh', trigger=['./app/api'])
sync('./bin/', '/app/bin/'),
],
)
# Run local commands
# Local commands can be helpful for one-time tasks like installing
# project prerequisites. They can also manage long-lived processes
# for non-containerized services or dependencies.
#
# More info: https://docs.tilt.dev/local_resource.html
#
# local_resource('install-helm',
# cmd='which helm > /dev/null || brew install helm',
# # `cmd_bat`, when present, is used instead of `cmd` on Windows.
# cmd_bat=[
# 'powershell.exe',
# '-Noninteractive',
# '-Command',
# '& {if (!(Get-Command helm -ErrorAction SilentlyContinue)) {scoop install helm}}'
# ]
# )
# Teach tilt about our custom resources (Note, this may be intended for workloads)
# k8s_kind('authorizationpolicy')
# k8s_kind('requestauthentication')
# k8s_kind('virtualservice')
k8s_kind('pgadmin')
# Troubleshooting
def resource_name(id):
print('resource: {}'.format(id))
return id.name
workload_to_resource_function(resource_name)
# Apply Kubernetes manifests
# Tilt will build & push any necessary images, re-deploying your
# resources as they change.
#
# More info: https://docs.tilt.dev/api.html#api.k8s_yaml
#
def holos_yaml():
"""Return a k8s Deployment personalized for the developer."""
k8s_yaml_template = str(read_file('./hack/tilt/k8s.yaml'))
return k8s_yaml_template.format(
name=holos_server,
developer=developer,
namespace=namespace,
listen_port=listen_port,
metrics_port=metrics_port,
tz=os.getenv('TZ'),
)
# Customize a Kubernetes resource
# By default, Kubernetes resource names are automatically assigned
# based on objects in the YAML manifests, e.g. Deployment name.
@@ -179,133 +93,18 @@ def holos_yaml():
#
# More info: https://docs.tilt.dev/api.html#api.k8s_resource
#
k8s_yaml(blob(holos_yaml()))
k8s_yaml(blob(str(read_file('./hack/tilt/k8s/dev-holos-app/deployment.yaml'))))
# Backend server process
k8s_resource(
workload=holos_server,
new_name=holos_backend,
objects=[
'{}:serviceaccount'.format(holos_server),
'{}:servicemonitor'.format(holos_server),
],
objects=[],
resource_deps=[compile_id],
links=[
link('https://{}.app.dev.k2.holos.run/ui/'.format(developer), "Holos Web UI")
],
)
# AuthorizationPolicy - Beyond Corp functionality
k8s_resource(
new_name=auth_id,
objects=[
'{}:virtualservice'.format(holos_server),
link('https://app.holos.localhost/ui/'.format(developer), "Holos Web UI")
],
)
# Database
# Note: Tilt confuses the backup pods with the database server pods, so this code is careful to tease the pods
# apart so logs are streamed correctly.
# See: https://github.com/tilt-dev/tilt.specs/blob/master/resource_assembly.md
# pgAdmin Web UI
k8s_resource(
workload=pg_admin_name,
new_name=pg_admin,
port_forwards=[
port_forward(15050, 5050, pg_admin),
],
)
# Disabled because these don't group resources nicely
# k8s_kind('postgrescluster')
# Postgres database in-cluster
k8s_resource(
new_name=pg_cluster,
objects=['holos:postgrescluster'],
)
# Needed to select the database by label
# https://docs.tilt.dev/api.html#api.k8s_custom_deploy
k8s_custom_deploy(
pg_svc,
apply_cmd=['./hack/tilt/k8s-get-db-sts', pg_cluster_name],
delete_cmd=['echo', 'Skipping delete. Object managed by custom resource.'],
deps=[],
)
k8s_resource(
pg_svc,
port_forwards=[
port_forward(15432, 5432, 'psql'),
],
resource_deps=[pg_cluster]
)
# Run tests
local_resource(
tests_id,
'make test',
allow_parallel=True,
auto_init=False,
deps=developer_paths,
)
# Run linter
local_resource(
lint_id,
'make lint',
allow_parallel=True,
auto_init=False,
deps=developer_paths,
)
# UI Buttons for helpful things.
# Icons: https://fonts.google.com/icons
os.putenv("GH_FORCE_TTY", "80%")
cmd_button(
'{}:go-test-failfast'.format(tests_id),
argv=['./hack/tilt/go-test-failfast'],
resource=tests_id,
icon_name='quiz',
text='Fail Fast',
)
cmd_button(
'{}:issues'.format(holos_server),
argv=['./hack/tilt/gh-issues'],
resource=holos_backend,
icon_name='folder_data',
text='Issues',
)
cmd_button(
'{}:gh-issue-view'.format(holos_server),
argv=['./hack/tilt/gh-issue-view'],
resource=holos_backend,
icon_name='task',
text='View Issue',
)
cmd_button(
'{}:get-pgdb-creds'.format(holos_server),
argv=['./hack/tilt/get-pgdb-creds', pg_cluster_name, pg_database_name],
resource=pg_svc,
icon_name='lock_open_right',
text='DB Creds',
)
cmd_button(
'{}:get-pgdb-creds'.format(pg_admin_name),
argv=['./hack/tilt/get-pgdb-creds', pg_cluster_name, pg_database_name],
resource=pg_admin,
icon_name='lock_open_right',
text='DB Creds',
)
cmd_button(
'{}:get-pgadmin-creds'.format(pg_admin_name),
argv=['./hack/tilt/get-pgadmin-creds', pg_admin_name],
resource=pg_admin,
icon_name='lock_open_right',
text='pgAdmin Login',
)
print("✨ Tiltfile evaluated")

View File

@@ -1 +0,0 @@
module: "github.com/holos-run/holos"

View File

@@ -1,403 +0,0 @@
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
# v1alpha2
```go
import "github.com/holos-run/holos/api/core/v1alpha2"
```
Package v1alpha2 contains the core API contract between the holos cli and CUE configuration code. Platform designers, operators, and software developers use this API to write configuration in CUE which \`holos\` loads. The overall shape of the API defines imperative actions \`holos\` should carry out to render the complete yaml that represents a Platform.
[Platform](<#Platform>) defines the complete configuration of a platform. With the holos reference platform this takes the shape of one management cluster and at least two workload cluster. Each cluster has multiple [HolosComponent](<#HolosComponent>) resources applied to it.
Each holos component path, e.g. \`components/namespaces\` produces exactly one [BuildPlan](<#BuildPlan>) which in turn contains a set of [HolosComponent](<#HolosComponent>) kinds.
The primary kinds of [HolosComponent](<#HolosComponent>) are:
1. [HelmChart](<#HelmChart>) to render config from a helm chart.
2. [KustomizeBuild](<#KustomizeBuild>) to render config from [Kustomize](<#Kustomize>)
3. [KubernetesObjects](<#KubernetesObjects>) to render [APIObjects](<#APIObjects>) defined directly in CUE configuration.
Note that Holos operates as a data pipeline, so the output of a [HelmChart](<#HelmChart>) may be provided to [Kustomize](<#Kustomize>) for post\-processing.
## Index
- [Constants](<#constants>)
- [type APIObject](<#APIObject>)
- [type APIObjectMap](<#APIObjectMap>)
- [type APIObjects](<#APIObjects>)
- [type BuildPlan](<#BuildPlan>)
- [type BuildPlanComponents](<#BuildPlanComponents>)
- [type BuildPlanSpec](<#BuildPlanSpec>)
- [type Chart](<#Chart>)
- [type FileContent](<#FileContent>)
- [type FileContentMap](<#FileContentMap>)
- [type FilePath](<#FilePath>)
- [type HelmChart](<#HelmChart>)
- [type HolosComponent](<#HolosComponent>)
- [type Kind](<#Kind>)
- [type KubernetesObjects](<#KubernetesObjects>)
- [type Kustomize](<#Kustomize>)
- [type KustomizeBuild](<#KustomizeBuild>)
- [type Label](<#Label>)
- [type Metadata](<#Metadata>)
- [type Platform](<#Platform>)
- [type PlatformMetadata](<#PlatformMetadata>)
- [type PlatformSpec](<#PlatformSpec>)
- [type PlatformSpecComponent](<#PlatformSpecComponent>)
- [type Repository](<#Repository>)
## Constants
<a name="APIVersion"></a>
```go
const (
APIVersion = "v1alpha2"
BuildPlanKind = "BuildPlan"
HelmChartKind = "HelmChart"
// ChartDir is the directory name created in the holos component directory to cache a chart.
ChartDir = "vendor"
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
ResourcesFile = "resources.yaml"
)
```
<a name="KubernetesObjectsKind"></a>
```go
const KubernetesObjectsKind = "KubernetesObjects"
```
<a name="APIObject"></a>
## APIObject
APIObject represents the most basic generic form of a single kubernetes api object. Represented as a JSON object internally for compatibility between tools, for example loading from CUE.
```go
type APIObject structpb.Struct
```
<a name="APIObjectMap"></a>
## APIObjectMap
APIObjectMap represents the marshalled yaml representation of kubernetes api objects. Do not produce an APIObjectMap directly, instead use [APIObjects](<#APIObjects>) to produce the marshalled yaml representation from CUE data, then provide the result to [HolosComponent](<#HolosComponent>).
```go
type APIObjectMap map[Kind]map[Label]string
```
<a name="APIObjects"></a>
## APIObjects
APIObjects represents Kubernetes API objects defined directly from CUE code. Useful to mix in resources to any kind of [HolosComponent](<#HolosComponent>), for example adding an ExternalSecret resource to a [HelmChart](<#HelmChart>).
[Kind](<#Kind>) must be the resource kind, e.g. Deployment or Service.
[Label](<#Label>) is an arbitrary internal identifier to uniquely identify the resource within the context of a \`holos\` command. Holos will never write the intermediate label to rendered output.
Refer to [HolosComponent](<#HolosComponent>) which accepts an [APIObjectMap](<#APIObjectMap>) field provided by [APIObjects](<#APIObjects>).
```go
type APIObjects struct {
APIObjects map[Kind]map[Label]APIObject `json:"apiObjects"`
APIObjectMap APIObjectMap `json:"apiObjectMap"`
}
```
<a name="BuildPlan"></a>
## BuildPlan
BuildPlan represents a build plan for the holos cli to execute. The purpose of a BuildPlan is to define one or more [HolosComponent](<#HolosComponent>) kinds. For example a [HelmChart](<#HelmChart>), [KustomizeBuild](<#KustomizeBuild>), or [KubernetesObjects](<#KubernetesObjects>).
A BuildPlan usually has an additional empty [KubernetesObjects](<#KubernetesObjects>) for the purpose of using the [HolosComponent](<#HolosComponent>) DeployFiles field to deploy an ArgoCD or Flux gitops resource for the holos component.
```go
type BuildPlan struct {
Kind string `json:"kind" cue:"\"BuildPlan\""`
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha2\""`
Spec BuildPlanSpec `json:"spec"`
}
```
<a name="BuildPlanComponents"></a>
## BuildPlanComponents
```go
type BuildPlanComponents struct {
Resources map[Label]KubernetesObjects `json:"resources,omitempty"`
KubernetesObjectsList []KubernetesObjects `json:"kubernetesObjectsList,omitempty"`
HelmChartList []HelmChart `json:"helmChartList,omitempty"`
KustomizeBuildList []KustomizeBuild `json:"kustomizeBuildList,omitempty"`
}
```
<a name="BuildPlanSpec"></a>
## BuildPlanSpec
BuildPlanSpec represents the specification of the build plan.
```go
type BuildPlanSpec struct {
// Disabled causes the holos cli to take no action over the [BuildPlan].
Disabled bool `json:"disabled,omitempty"`
// Components represents multiple [HolosComponent] kinds to manage.
Components BuildPlanComponents `json:"components,omitempty"`
}
```
<a name="Chart"></a>
## Chart
Chart represents a helm chart.
```go
type Chart struct {
// Name represents the chart name.
Name string `json:"name"`
// Version represents the chart version.
Version string `json:"version"`
// Release represents the chart release when executing helm template.
Release string `json:"release"`
// Repository represents the repository to fetch the chart from.
Repository Repository `json:"repository,omitempty"`
}
```
<a name="FileContent"></a>
## FileContent
FileContent represents file contents.
```go
type FileContent string
```
<a name="FileContentMap"></a>
## FileContentMap
FileContentMap represents a mapping of file paths to file contents. Paths are relative to the \`holos\` output "deploy" directory, and may contain sub\-directories.
```go
type FileContentMap map[FilePath]FileContent
```
<a name="FilePath"></a>
## FilePath
FilePath represents a file path.
```go
type FilePath string
```
<a name="HelmChart"></a>
## HelmChart
HelmChart represents a holos component which wraps around an upstream helm chart. Holos orchestrates helm by providing values obtained from CUE, renders the output using \`helm template\`, then post\-processes the helm output yaml using the general functionality provided by [HolosComponent](<#HolosComponent>), for example [Kustomize](<#Kustomize>) post\-rendering and mixing in additional kubernetes api objects.
```go
type HelmChart struct {
HolosComponent `json:",inline"`
Kind string `json:"kind" cue:"\"HelmChart\""`
// Chart represents a helm chart to manage.
Chart Chart `json:"chart"`
// ValuesContent represents the values.yaml file holos passes to the `helm
// template` command.
ValuesContent string `json:"valuesContent"`
// EnableHooks enables helm hooks when executing the `helm template` command.
EnableHooks bool `json:"enableHooks" cue:"bool | *false"`
}
```
<a name="HolosComponent"></a>
## HolosComponent
HolosComponent defines the fields common to all holos component kinds. Every holos component kind should embed HolosComponent.
```go
type HolosComponent struct {
// Kind is a string value representing the resource this object represents.
Kind string `json:"kind"`
// APIVersion represents the versioned schema of this representation of an object.
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha2\""`
// Metadata represents data about the holos component such as the Name.
Metadata Metadata `json:"metadata"`
// APIObjectMap holds the marshalled representation of api objects. Useful to
// mix in resources to each HolosComponent type, for example adding an
// ExternalSecret to a HelmChart HolosComponent. Refer to [APIObjects].
APIObjectMap APIObjectMap `json:"apiObjectMap,omitempty"`
// DeployFiles represents file paths relative to the cluster deploy directory
// with the value representing the file content. Intended for defining the
// ArgoCD Application resource or Flux Kustomization resource from within CUE,
// but may be used to render any file related to the build plan from CUE.
DeployFiles FileContentMap `json:"deployFiles,omitempty"`
// Kustomize represents a kubectl kustomize build post-processing step.
Kustomize `json:"kustomize,omitempty"`
// Skip causes holos to take no action regarding this component.
Skip bool `json:"skip" cue:"bool | *false"`
}
```
<a name="Kind"></a>
## Kind
Kind is a kubernetes api object kind. Defined as a type for clarity and type checking.
```go
type Kind string
```
<a name="KubernetesObjects"></a>
## KubernetesObjects
KubernetesObjects represents a [HolosComponent](<#HolosComponent>) composed of Kubernetes API objects provided directly from CUE using [APIObjects](<#APIObjects>).
```go
type KubernetesObjects struct {
HolosComponent `json:",inline"`
Kind string `json:"kind" cue:"\"KubernetesObjects\""`
}
```
<a name="Kustomize"></a>
## Kustomize
Kustomize represents resources necessary to execute a kustomize build. Intended for at least two use cases:
1. Process a [KustomizeBuild](<#KustomizeBuild>) [HolosComponent](<#HolosComponent>) which represents raw yaml file resources in a holos component directory.
2. Post process a [HelmChart](<#HelmChart>) [HolosComponent](<#HolosComponent>) to inject istio, patch jobs, add custom labels, etc...
```go
type Kustomize struct {
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
KustomizeFiles FileContentMap `json:"kustomizeFiles,omitempty"`
// ResourcesFile is the file name used for api objects in kustomization.yaml
ResourcesFile string `json:"resourcesFile,omitempty"`
}
```
<a name="KustomizeBuild"></a>
## KustomizeBuild
KustomizeBuild represents a [HolosComponent](<#HolosComponent>) that renders plain yaml files in the holos component directory using \`kubectl kustomize build\`.
```go
type KustomizeBuild struct {
HolosComponent `json:",inline"`
Kind string `json:"kind" cue:"\"KustomizeBuild\""`
}
```
<a name="Label"></a>
## Label
Label is an arbitrary unique identifier internal to holos itself. The holos cli is expected to never write a Label value to rendered output files, therefore use a [Label](<#Label>) then the identifier must be unique and internal. Defined as a type for clarity and type checking.
A Label is useful to convert a CUE struct to a list, for example producing a list of [APIObject](<#APIObject>) resources from an [APIObjectMap](<#APIObjectMap>). A CUE struct using Label keys is guaranteed to not lose data when rendering output because a Label is expected to never be written to the final output.
```go
type Label string
```
<a name="Metadata"></a>
## Metadata
Metadata represents data about the holos component such as the Name.
```go
type Metadata struct {
// Name represents the name of the holos component.
Name string `json:"name"`
// Namespace is the primary namespace of the holos component. A holos
// component may manage resources in multiple namespaces, in this case
// consider setting the component namespace to default.
//
// This field is optional because not all resources require a namespace,
// particularly CRD's and DeployFiles functionality.
// +optional
Namespace string `json:"namespace,omitempty"`
}
```
<a name="Platform"></a>
## Platform
Platform represents a platform to manage. A Platform resource informs holos which components to build. The platform resource also acts as a container for the platform model form values provided by the PlatformService. The primary use case is to collect the cluster names, cluster types, platform model, and holos components to build into one resource.
```go
type Platform struct {
// Kind is a string value representing the resource this object represents.
Kind string `json:"kind" cue:"\"Platform\""`
// APIVersion represents the versioned schema of this representation of an object.
APIVersion string `json:"apiVersion" cue:"string | *\"v1alpha2\""`
// Metadata represents data about the object such as the Name.
Metadata PlatformMetadata `json:"metadata"`
// Spec represents the specification.
Spec PlatformSpec `json:"spec"`
}
```
<a name="PlatformMetadata"></a>
## PlatformMetadata
```go
type PlatformMetadata struct {
// Name represents the Platform name.
Name string `json:"name"`
}
```
<a name="PlatformSpec"></a>
## PlatformSpec
PlatformSpec represents the specification of a Platform. Think of a platform specification as a list of platform components to apply to a list of kubernetes clusters combined with the user\-specified Platform Model.
```go
type PlatformSpec struct {
// Model represents the platform model holos gets from from the
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
Model structpb.Struct `json:"model"`
// Components represents a list of holos components to manage.
Components []PlatformSpecComponent `json:"components"`
}
```
<a name="PlatformSpecComponent"></a>
## PlatformSpecComponent
PlatformSpecComponent represents a holos component to build or render.
```go
type PlatformSpecComponent struct {
// Path is the path of the component relative to the platform root.
Path string `json:"path"`
// Cluster is the cluster name to provide when rendering the component.
Cluster string `json:"cluster"`
}
```
<a name="Repository"></a>
## Repository
Repository represents a helm chart repository.
```go
type Repository struct {
Name string `json:"name"`
URL string `json:"url"`
}
```
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)

17
doc/md/glossary.md Normal file
View File

@@ -0,0 +1,17 @@
# Glossary
This page describes the terms used within the context of Holos.
## Management Cluster
## Workload Cluster
## Platform Form
## Platform Model
## Secret Store
## Service Mesh
## Zero Trust

View File

@@ -0,0 +1,28 @@
# Local Development
This document captures notes on locally developing Holos.
Follow the steps in [Try Holos Locally](/docs/tutorial/local/k3d), but take
care to select `Develop` tabs when creating the k3d cluster so you have a local
registry to push to.
## Apply Resources
Work will be done in the `dev-holos` namespace.
Apply the infrastructure, which should persist when tilt is started / stopped.
```bash
kubectl apply --server-side=true -f ./hack/tilt/k8s/dev-holos-infra
```
This creates the PostgresCluster, service account, etc...
## Start tilt
Tilt will build the go executable, build the container, then push it to the
local repository associated with k3d.
```bash
./hack/tilt/bin/tilt up
```

View File

@@ -0,0 +1,81 @@
# Architecture
This page describes the architecture of the Holos reference platform.
## Overview
The reference platform manages three kubernetes clusters by default. One management cluster and two workload clusters.
```mermaid
graph TB
subgraph "Management"
secrets(Secrets)
c1(Controllers)
end
subgraph "Primary"
s1p(Service 1)
s2p(Service 2)
end
subgraph "Standby"
s1s(Service 1)
s2s(Service 2)
end
classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000;
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff;
classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5;
class c1,s1p,s2p,s1s,s2s,secrets k8s;
class Management,Primary,Standby cluster;
```
The services in each cluster type are:
:::tip
The management cluster is designed to operate reliably on spot instances. A highly available management cluster typically costs less than a cup of coffee per month to operate.
:::
1. Management Cluster
- **SecretStore** to provide namespace scoped secrets to workload clusters.
- **CertManager** to provision TLS certificates and make them available to workload clusters.
- **ClusterAPI** to provision and manage workload clusters via GitOps. For example, EKS or GKE clusters.
- **Crossplane** to provision and manage cloud resources via GitOps. For example, buckets, managed databases, any other cloud resource.
- **CronJobs** to refresh short lived credentials. For example image pull credentials.
- **ArgoCD** to manage resources within the management cluster via GitOps.
2. Primary Workload Cluster
- **ArgoCD** to continuously deploy your applications and services via GitOps.
- **External Secrets Operator** to synchronize namespace scoped secrets.
- **Istio** to provide a Gateway to expose services.
- **ZITADEL** to provide SSO login for all other services (e.g. ArgoCD, Grafana, Backstage, etc...)
- **PostgreSQL** for in-cluster databases.
- **Backstage** to provide your developer portal into the whole platform.
- **Observability** implemented by Prometheus, Grafana, and Loki to provide monitoring and logging.
- **AuthorizationPolicy** to provide role based access control to all services in the cluster.
3. Standby Workload Cluster
- Identical configuration to the primary cluster.
- May be scaled down to zero to reduce expenses.
- Intended to take the primary cluster role quickly, within minutes, for disaster recovery or regular maintenance purposes.
## Security
### Namespaces
Namespaces are security boundaries in the reference platform. A given namespace is treated as the same security context across multiple clusters following the [SIG Multi-cluster Position](https://github.com/kubernetes/community/blob/dd4c8b704ef1c9c3bfd928c6fa9234276d61ad18/sig-multicluster/namespace-sameness-position-statement.md).
The namespace sameness principle makes role based access control straightforward to manage and comprehend. For example, granting a developer the ability to create secrets in namespace `example` means the developer has the ability to do so in the secret store in the management cluster and also synchronize the secret to the services they own in the workload clusters.
## Data Platform
Holos is designed to work with two distinct types of databases by default:
1. In-cluster PostgresSQL databases for lower cost and rapid development and testing.
2. Out-of-cluster SQL databases for production services, e.g. RDS, CloudSQL, Aurora, Redshift, etc...
:::tip
To simplify maintenance the holos reference platform provisions databases from the most recent backup by default.
:::
In-cluster databases in the holos reference platform automatically save backups to an S3 or GCS bucket. For regular maintenance and disaster recovery, the standby cluster automatically restores databases from the most recent backup in the bucket. This capability makes maintenance much simpler, most maintenance tasks are carried out on the standby cluster which is then promoted to the primary. Software upgrades in particular are intended to be carried out against the standby, verified, then promoted to primary. Once live traffic shifts to the upgraded services in the new primary the previous cluster can be spun down to save cost or upgraded safely in place.

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -0,0 +1,835 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Try Holos Locally
Learn how to configure and deploy the Holos reference platform to your local
host with k3d.
---
This guide assumes commands are run from your local host. Capitalized terms
have specific definitions described in the [Glossary](/docs/glossary).
## Requirements
You'll need the following tools installed on your local host to complete this guide.
1. [k3d](https://k3d.io/#installation) - to provide an api server.
2. [Docker](https://docs.docker.com/get-docker/) - to use k3d.
3. [holos](/docs/tutorial/install) - to build the platform.
4. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the Kubernetes cluster.
5. [helm](https://helm.sh/docs/intro/install/) - to render Holos components that integrate vendor provided Helm charts.
6. [mkcert](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation) - for local trusted certificates.
7. [jq](https://jqlang.github.io/jq/download/) - to manipulate json output.
## Outcome
At the end of this guide you'll have built a development platform that provides
Zero Trust security by holistically integrating off-the-shelf components.
1. ArgoCD to review and apply platform configuration changes.
2. Istio service mesh with mTLS encryption.
3. ZITADEL to provide single sign-on identity tokens with multi factor authentication.
The platform running on your local host will configure Istio to authenticate and
authorize requests using an oidc id token issued by ZITADEL _before_ the request
ever reaches ArgoCD.
:::tip
With Holos, developers don't need to write authentication or authorization logic
for many use cases.
:::
Single sign-on and role based access control are provided by the platform itself
for all service running in the platform using standardized policies.
The `k3d` platform is derived from the larger holos reference platform to
provide a smooth on-ramp to evaluate the value Holos offers.
1. Holos wraps unmodified Helm charts provided by software vendors.
2. Holos eliminates the need to template yaml.
3. Holos is composable, scaling down to local host and up to multi-cloud and multi-cluster.
4. The Zero Trust security model implemented by the reference platform.
5. Configuration unification with CUE.
## Register with Holos
Register an account with the Holos web service. This registration is required
to save platform configuration values via a simple web form and to explore how
Holos implements Zero Trust.
```bash
holos register user
```
## Create the Platform
Create the platform, which stores the Platform Form and its values in the Holos
web service. The Platform Form represents the Platform Model.
```bash
holos create platform --name k3d --display-name "Try Holos Locally"
```
## Generate the Platform
Holos builds the platform by building each component of the platform into fully
rendered Kubernetes configuration resources. Generate the source code for the
platform in a blank local directory. This directory is named `holos-infra` by
convention because it represents the Holos managed platform infrastructure.
Create a new Git repository to store the platform code:
```bash
mkdir holos-k3d
cd holos-k3d
git init .
```
Generate the platform code in the current directory:
```bash
holos generate platform k3d
```
Commit the generated platform config to the repository:
```bash
git add .
git commit -m "holos generate platform k3d - $(holos --version)"
```
## Push the Platform Form
Push the Platform Form to the web service to provide top-level configuration
values from which the platform components derive their final configuration.
```bash
holos push platform form .
```
Visit the printed URL to view the Platform Form.
:::tip
You have complete control over the form fields and validation rules.
:::
## Submit the Platform Model
Fill out the form and submit the Platform Model.
For the Role Based Access Control section, provide the value of the `sub`
subject claim of your identity to ensure only you have administrative access to
ArgoCD.
```bash
holos login --print-claims | jq -r .sub
```
For the ArgoCD Git repository URL, enter the url of a public repository where
you will push your local `holos-k3d` repository.
```bash
git remote add origin https://github.com/example/holos-k3d
git push origin HEAD:main
```
## Pull the Platform Model
The Platform Model is the JSON representation of the Platform Form values.
Holos provides the Platform Model to CUE to render the platform configuration to
plain YAML. Configuration that varies is derived from the Platform Model using
CUE.
Pull the Platform Model to your local host to render the platform.
```bash
holos pull platform model .
```
The `platform.config.json` file is intended to be committed to version control.
```bash
git add platform.config.json
git commit -m "Add platform model"
```
:::danger
Do not store secrets in the Platform Model.
:::
Holos uses ExternalSecret resources to securely sync with a SecretStore and
ensure Secrets are never stored in version control.
## Render the Platform
Rendering the platform iterates over each platform component and renders the
component into the final Kubernetes resources that will be sent to the API Server.
```bash
holos render platform ./platform
```
This command writes fully rendered Kubernetes resource yaml to the `deploy/` directory.
:::warning
Do not edit the files in the `deploy` as they will be written over.
:::
Commit the rendered platform configuration for `git diff` later.
```bash
git add deploy
git commit -m "holos render platform ./platform"
```
### Rendering
Holos uses the Kubernetes resource model to manage configuration. The `holos`
command line interface (cli) is the primary method you'll use to manage your
platform. Holos uses CUE to provide a unified configuration model of the
platform which is built from components packaged with Helm, Kustomize, CUE, or
any tool that can produce Kubernetes resources as output. This process can be
thought of as a yaml **rendering pipeline**.
Each component in a platform defines a rendering pipeline shown in Figure 2 to
produce Kubernetes api resources
```mermaid
---
title: Figure 2 - Render Pipeline
---
graph LR
PS[<a href="/docs/api/core/v1alpha2#PlatformSpec">PlatformSpec</a>]
BP[<a href="/docs/api/core/v1alpha2#BuildPlan">BuildPlan</a>]
HC[<a href="/docs/api/core/v1alpha2#HolosComponent">HolosComponent</a>]
H[<a href="/docs/api/core/v1alpha2#HelmChart">HelmChart</a>]
K[<a href="/docs/api/core/v1alpha2#KustomizeBuild">KustomizeBuild</a>]
O[<a href="/docs/api/core/v1alpha2#KubernetesObjects">KubernetesObjects</a>]
P[<a href="/docs/api/core/v1alpha2#Kustomize">Kustomize</a>]
Y[Kubernetes <br>Resources]
G[GitOps <br>Resource]
C[Kube API Server]
PS --> BP --> HC
HC --> H --> P
HC --> K --> P
HC --> O --> P
P --> Y --> C
P --> G --> C
```
The `holos` cli can be thought of as executing a data pipeline. The Platform
Model is the top level input to the pipeline and specifies the ways your
platform varies from other organizations. The `holos` cli takes the Platform
Model as input and executes a series of steps to produce the platform
configuration. The platform configuration output of `holos` are full
Kubernetes API resources, suitable for application to a cluster with `kubectl
apply -f`, or GitOps tools such as ArgoCD or Flux.
## Review the Platform Config
:::tip
This section is optional, included to provide insight into how Holos uses CUE
and Helm to unify and render the platform configuration.
:::
Take a moment to review the platform config `holos` rendered.
### ArgoCD Application
Note the Git URL you entered into the Platform Form is used to derive the ArgoCD
`Application` resource from the Platform Model.
```yaml
# deploy/clusters/workload/gitops/namespaces.application.gen.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: namespaces
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
# highlight-next-line
path: /deploy/clusters/workload/components/namespaces
# highlight-next-line
repoURL: https://github.com/holos-run/holos-k3d
# highlight-next-line
targetRevision: HEAD
```
One ArgoCD `Application` resource is produced for each Holos component by
default. Note the `cert-manger` component renders the output using Helm.
Holos unifies the Application resource using CUE. The CUE definition which
produces the rendered output is defined in `buildplan.cue` around line 222.
:::tip
Note how CUE does not use error-prone text templates, the language is well
specified and typed which reduces errors when unifying the configuration with
the Platform Model in the following `#Argo` definition.
:::
```cue
// buildplan.cue
// #Argo represents an argocd Application resource for each component, written
// using the #HolosComponent.deployFiles field.
#Argo: {
ComponentName: string
Application: app.#Application & {
metadata: name: ComponentName
metadata: namespace: "argocd"
spec: {
destination: server: "https://kubernetes.default.svc"
project: "default"
source: {
// highlight-next-line
path: "\(_Platform.Model.argocd.deployRoot)/deploy/clusters/\(_ClusterName)/components/\(ComponentName)"
// highlight-next-line
repoURL: _Platform.Model.argocd.repoURL
// highlight-next-line
targetRevision: _Platform.Model.argocd.targetRevision
}
}
}
// deployFiles represents the output files to write along side the component.
deployFiles: "clusters/\(_ClusterName)/gitops/\(ComponentName).application.gen.yaml": yaml.Marshal(Application)
}
```
### Helm Chart
Holos uses CUE to safely integrate the unmodified upstream `cert-manager` Helm
chart.
:::tip
Holos fully supports your existing Helm charts. Consider leveraging `holos` as
an safer alternative to umbrella charts.
:::
```cue
// components/cert-manager/cert-manager.cue
package holos
// Produce a helm chart build plan.
(#Helm & Chart).Output
let Chart = {
Name: "cert-manager"
Version: "1.14.5"
Namespace: "cert-manager"
Repo: name: "jetstack"
Repo: url: "https://charts.jetstack.io"
// highlight-next-line
Values: {
installCRDs: true
startupapicheck: enabled: false
// Must not use kube-system on gke autopilot. GKE Warden blocks access.
// highlight-next-line
global: leaderElection: namespace: Namespace
// https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-resource-requests#min-max-requests
resources: requests: {
cpu: "250m"
memory: "512Mi"
"ephemeral-storage": "100Mi"
}
// highlight-next-line
webhook: resources: Values.resources
// highlight-next-line
cainjector: resources: Values.resources
// highlight-next-line
startupapicheck: resource: Values.resources
// https://cloud.google.com/kubernetes-engine/docs/how-to/autopilot-spot-pods
nodeSelector: {
"kubernetes.io/os": "linux"
if _ClusterName == "management" {
"cloud.google.com/gke-spot": "true"
}
}
webhook: nodeSelector: Values.nodeSelector
cainjector: nodeSelector: Values.nodeSelector
startupapicheck: nodeSelector: Values.nodeSelector
}
}
```
## Create the Workload Cluster
The Workload Cluster is where your applications and services will be deployed.
In production this is usually an EKS, GKE, or AKS cluster.
:::tip
Holos supports any compliant Kubernetes cluster and was developed and tested on
GKE, EKS, Talos, and Kubeadm clusters.
:::
<Tabs>
<TabItem value="evaluate" label="Evaluate" default>
Use this command when evaluating Holos.
```bash
k3d cluster create workload \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
</TabItem>
<TabItem value="develop" label="Develop" default>
Use this command when developing Holos.
```bash
k3d registry create registry.holos.localhost --port 5100
```
```bash
k3d cluster create workload \
--registry-use k3d-registry.holos.localhost:5100 \
--port "443:443@loadbalancer" \
--k3s-arg "--disable=traefik@server:0"
```
</TabItem>
</Tabs>
Traefik is disabled because Istio provides the same functionality.
## Local CA
Create and apply the `local-ca` Secret containing the CA private key. This
Secret is necessary to issue certificates trusted by your browser when using the
local k3d platform.
```bash
bash ./scripts/local-ca
```
:::note
Admin access is necessary for `mkcert` to install the newly generated CA cert
into your local host's trust store.
:::
## DNS Setup
Configure your localhost to resolve `*.holos.localhost` to your loopback
interface. This is necessary for your browser requests to reach the k3d
workload cluster.
<Tabs>
<TabItem value="macos" label="macOS" default>
```bash
brew install dnsmasq
```
```bash
cat <<EOF >"$(brew --prefix)/etc/dnsmasq.d/holos.localhost.conf"
# Refer to https://holos.run/docs/tutorial/local/k3d/
address=/holos.localhost/127.0.0.1
EOF
```
```bash
if [[ -r /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist ]]; then
echo "dnsmasq already configured"
else
sudo cp "$(brew list dnsmasq | grep 'dnsmasq.plist$')" \
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
dscacheutil -flushcache
echo "dnsmasq configured"
fi
```
```bash
sudo mkdir -p /etc/resolver
sudo tee /etc/resolver/holos.localhost <<EOF
domain holos.localhost
nameserver 127.0.0.1
EOF
sudo killall -HUP mDNSResponder
```
</TabItem>
<TabItem value="linux" label="Linux">
[NSS-myhostname](http://man7.org/linux/man-pages/man8/nss-myhostname.8.html)
ships with many Linux distributions and should resolve *.localhost
automatically to 127.0.0.1.
Otherwise it is installable with:
```bash
sudo apt install libnss-myhostname
```
</TabItem>
<TabItem value="windows" label="Windows">
Ensure the loopback interface has at least the following names in `C:\windows\system32\drivers\etc\hosts`
```
127.0.0.1 httpbin.holos.localhost argocd.holos.localhost app.holos.localhost
```
</TabItem>
</Tabs>
## Apply the Platform Components
Use `kubectl` to apply each platform component. In production, it's common to
fully automate this process with ArgoCD, but we use `kubectl` in development
and exploration contexts to the same effect.
### Namespaces
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/namespaces
```
### Custom Resource Definitions
Services are exposed with standard `HTTPRoute` resources from the Gateway API.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/gateway-api
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istio-base
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/argo-crds
```
### Cert Manager
Apply the ClusterIssuer which issues Certificate resources using the local ca.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/cert-manager
kubectl apply --server-side=true -f deploy/clusters/workload/components/local-ca
kubectl apply --server-side=true -f deploy/clusters/workload/components/certificates
```
### Istio
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istio-cni
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/istiod
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/gateway
```
Verify the Gateway is programmed and the listeners have been accepted:
```bash
kubectl get -n istio-gateways gateway default -o json \
| jq -r '.status.conditions[].message'
```
```txt
Resource accepted
Resource programmed, assigned to service(s) default-istio.istio-gateways.svc.cluster.local:443
```
### httpbin
httpbin is a simple backend service useful for end-to-end testing.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/httpbin-backend
kubectl apply --server-side=true -f deploy/clusters/workload/components/httpbin-routes
```
:::important
Browse to [https://httpbin.holos.localhost/](https://httpbin.holos.localhost/)
to verify end to end connectivity.
:::
### Cookie Secret
Generate a random cookie encryption Secret and apply.
```bash
LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom \
| head -c 32 \
| kubectl create secret generic "authproxy" \
--from-file=cookiesecret=/dev/stdin \
--dry-run=client -o yaml \
| kubectl apply -n istio-gateways -f-
```
:::tip
The Holos reference platform uses an ExternalSecret to automatically sync this
Secret from your SecretStore.
:::
### Auth Proxy
The auth proxy is responsible for authenticating web browser requests. The auth
proxy provides a standard oidc id token to all services integrated with the
mesh.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/authproxy
kubectl apply --server-side=true -f deploy/clusters/workload/components/authroutes
```
:::important
Verify authentication is working by visiting
[https://httpbin.holos.localhost/holos/authproxy](https://httpbin.holos.localhost/holos/authproxy).
Expect a simple `Authenticated` response.
:::
:::note
Istio will respond with `no healthy upstream` until the pod becomes ready.
:::
Once authenticated, visit
[https://httpbin.holos.localhost/holos/authproxy/userinfo](https://httpbin.holos.localhost/holos/authproxy/userinfo)
which returns a subset of claims from your id token:
```json
{
"user": "275552236589843464",
"email": "demo@holos.run",
"preferredUsername": "demo"
}
```
### Auth Policy
Configure authorization policies using the claims provided in the authenticated
id token.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/components/authpolicy
```
:::important
Requests to `https://httpbin.holos.localhost` are protected by
AuthorizationPolicy platform resources after applying this component.
:::
### Zero Trust
A basic Zero Trust security model is now in place. Verify authentication is
working by browsing to
[https://httpbin.holos.localhost/dump/request](https://httpbin.holos.localhost/dump/request).
:::note
Istio make take a few seconds to program the Gateway with the
AuthorizationPolicy resources.
:::
:::tip
Note the `x-oidc-id-token` header is not sent by your browser but is received
by the backend service. This design reduces the risk of exposing id tokens.
Requests over the internet are also smaller and more reliable because large id
tokens with may claims are confined to the cluster.
:::
Verify unauthenticated requests are blocked:
```bash
curl https://httpbin.holos.localhost/dump/request
```
Expect a response that redirects to the identity provider.
Verify authenticated requests are allowed:
```bash
curl -H x-oidc-id-token:$(holos token) https://httpbin.holos.localhost/dump/request
```
Expect a response from the backend httpbin service with the id token header the
platform authenticated and authorized.
:::tip
Note how the platform secures both web browser and command line api access to
the backend httpbin service. httpbin itself has no authentication or
authorization functionality.
:::
### ArgoCD
ArgoCD automatically applies resources defined in Git similar to how this guide
uses `kubectl apply`.
Apply controller deployments and supporting resources.
```bash
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/argo-cd
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/argo-authpolicy
kubectl apply --server-side=true -f ./deploy/clusters/workload/components/argo-routes
```
Verify all Pods are running and all containers are ready.
```bash
kubectl get pods -n argocd
```
```txt
NAME READY STATUS RESTARTS AGE
argocd-application-controller-0 1/1 Running 0 10s
argocd-applicationset-controller-578db65fcd-lnn76 1/1 Running 0 10s
argocd-notifications-controller-67c856dbb7-12stk 1/1 Running 0 10s
argocd-redis-698f57d9b9-v4kqs 1/1 Running 0 10s
argocd-redis-secret-init-z5zg8 0/1 Completed 0 10s
argocd-repo-server-69f78dfb8-f6pb7 1/1 Running 0 10s
argocd-server-58f7f4466d-db5fv 2/2 Running 0 10s
```
Browse to [https://argocd.holos.localhost/](https://argocd.holos.localhost/) and
verify you get the ArgoCD login page.
![ArgoCD Login Page](./argocd-login.png)
:::note
Both the platform layer and the ArgoCD application layer performs authentication
and authorization using the same identity provider. Note how the Zero Trust
model provides an additional layer of security without friction.
:::
Login using the SSO button and verify you get to the Applications page.
![ArgoCD Applications](./argocd-apps.png)
### ArgoCD Applications
Apply the Application resources for all of the Holos components that compose the
platform. The Application resources provide drift detection and optional
automatic reconciliation of platform components.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/gitops
```
Browse to or refresh [https://argocd.holos.localhost/applications](https://argocd.holos.localhost/applications).
![ArgoCD Holos Components](./argocd-apps-2.png)
:::important
If you do not see any applications after refreshing the page ensure the `sub`
value in the Platform Model (`platform.config.json`) is correct and matches
`holos login --print-claims`.
:::
### Sync Applications
Navigate to the [namespaces Application](https://argocd.holos.localhost/applications/argocd/namespaces).
![ArgoCD Out of Sync](./argocd-out-of-sync.png)
Review the differences between the live platform and the git configuration.
![ArgoCD Diff](./argocd-diff.png)
Sync the application to reconcile the differences.
![ArgoCD Sync](./argocd-sync.png)
The Holos components should report Sync OK.
![ArgoCD Sync OK](./argocd-sync-ok.png)
:::tip
Automatic reconciliation is turned off by default.
:::
Optionally enable automatic reconciliation by adding `spec.syncPolicy.automated:
{}` to the `#Argo` definition.
Add the following to `buildplan.site.cue` to avoid `holos generate platform k3d`
writing over the customization.
:::tip
CUE merges definitions located in multiple files. This feature is used to
customize the platform.
:::
```bash
cat <<EOF > buildplan.site.cue
package holos
// Enable automated sync of platform components.
#Argo: Application: spec: syncPolicy: automated: {}
EOF
```
Re-render the platform.
```bash
holos render platform ./platform
```
Add and commit the changes.
```bash
git add .
git commit -m 'enable argocd automatic sync'
git push origin HEAD
```
Apply the new changes.
```bash
kubectl apply --server-side=true -f deploy/clusters/workload/gitops
```
Automatic reconciliation is enabled for all platform components.
![ArgoCD Automatic Sync OK](./argocd-auto-sync-ok.png)
## Summary
TODO
1. Configured the Service Mesh with mTLS.
2. Configured authentication and authorization.
3. Protected a backend service without backend code changes.
4. ArgoCD

View File

@@ -0,0 +1,17 @@
# Overview
<!-- https://kubernetes.io/docs/contribute/style/diagram-guide/ -->
This tutorial covers the following process of getting started with Holos.
```mermaid
graph LR
A[1. Install <br>holos] -->
B[2. Register <br>account] -->
C[3. Generate <br>platform] -->
D[4. Render <br>platform] -->
E[5. Apply <br>config]
classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000;
class A,B,C,D,E box
```

View File

@@ -1,16 +1,4 @@
facebook:
label: Facebook
permalink: /facebook
description: Facebook tag description
hello:
label: Hello
permalink: /hello
description: Hello tag description
docusaurus:
label: Docusaurus
permalink: /docusaurus
description: Docusaurus tag description
hola:
label: Hola
permalink: /hola
description: Hola tag description
holos:
label: Holos
permalink: /holos
description: Holos Platform

View File

@@ -4,7 +4,7 @@ import type * as Preset from '@docusaurus/preset-classic';
const config: Config = {
title: 'Holos',
tagline: 'The Cloud Native Platform Distribution',
tagline: 'The Platform Operating System',
favicon: 'img/favicon.ico',
// Set the production url of your site here
@@ -12,6 +12,7 @@ const config: Config = {
// Set the /<baseUrl>/ pathname under which your site is served
// For GitHub pages deployment, it is often '/<projectName>/'
baseUrl: '/',
trailingSlash: true,
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
@@ -29,6 +30,12 @@ const config: Config = {
locales: ['en'],
},
// https://docusaurus.io/docs/markdown-features/diagrams
markdown: {
mermaid: true
},
themes: ['@docusaurus/theme-mermaid'],
presets: [
[
'classic',
@@ -60,7 +67,12 @@ const config: Config = {
themeConfig: {
// Replace with your project's social card
image: 'img/docusaurus-social-card.jpg',
image: 'img/holos-social-card.png',
docs: {
sidebar: {
autoCollapseCategories: false,
}
},
navbar: {
title: '',
logo: {
@@ -68,6 +80,12 @@ const config: Config = {
srcDark: 'img/logo-dark.svg',
},
items: [
{
type: 'doc',
docId: 'tutorial/local/k3d',
position: 'left',
label: 'Try Holos',
},
{
type: 'doc',
docId: 'intro',
@@ -101,9 +119,17 @@ const config: Config = {
title: 'Docs',
items: [
{
label: 'Tutorial',
label: 'Try Holos Locally',
to: '/docs/tutorial/local/k3d',
},
{
label: 'Documentation',
to: '/docs/intro',
},
{
label: 'API Reference',
to: '/docs/api/core/v1alpha2',
},
],
},
{
@@ -154,6 +180,10 @@ const config: Config = {
},
],
},
mermaid: {
// Refer to https://mermaid.js.org/config/theming.html
theme: { light: 'neutral', dark: 'dark' },
},
} satisfies Preset.ThemeConfig,
};

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@
"dependencies": {
"@docusaurus/core": "3.4.0",
"@docusaurus/preset-classic": "3.4.0",
"@docusaurus/theme-mermaid": "^3.4.0",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
@@ -28,6 +29,7 @@
"@docusaurus/tsconfig": "^3.4.0",
"@docusaurus/types": "^3.4.0",
"@wcj/html-to-markdown-cli": "^2.1.1",
"cspell": "^8.10.4",
"html-to-markdown": "^1.0.0",
"typescript": "~5.2.2"
},

View File

@@ -16,15 +16,24 @@ const sidebars: SidebarsConfig = {
{
type: 'category',
label: 'Tutorial',
collapsed: false,
items: [
'tutorial/start',
'tutorial/register',
'tutorial/local/k3d',
],
},
{
type: 'category',
label: 'Reference Platform',
collapsed: false,
items: [
'reference-platform/architecture',
],
},
'glossary',
],
api: [
'api/core/v1alpha2',
'cli',
'api/core/v1alpha2'
],
};

View File

@@ -10,38 +10,40 @@ type FeatureItem = {
const FeatureList: FeatureItem[] = [
{
title: 'Easy to Use',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
title: 'Zero Trust Security',
Svg: require('@site/static/img/base00/undraw_security_on_re_e491.svg').default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
used to get your website up and running quickly.
Spend more time on your business features and less time rebuilding
authentication and authorization. Holos provides zero trust security
with no code needed to protect your services.
</>
),
},
{
title: 'Focus on What Matters',
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
title: 'Multi-Cloud',
Svg: require('@site/static/img/base00/undraw_cloud_hosting_7xb1.svg').default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
ahead and move your docs into the <code>docs</code> directory.
Avoid vendor lock in, downtime, and price hikes. Holos is designed to
easily deploy workloads into multiple clouds and multiple regions.
</>
),
},
{
title: 'Powered by React',
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
title: 'Developer Portal',
Svg: require('@site/static/img/base00/undraw_data_trends_re_2cdy.svg').default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
be extended while reusing the same header and footer.
Ship high quality code quickly, provide a great developer experience,
and maintain control over your infrastructure with the integrated
Backstage developer portal.
</>
),
},
];
function Feature({title, Svg, description}: FeatureItem) {
function Feature({ title, Svg, description }: FeatureItem) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">

View File

@@ -6,29 +6,34 @@
/* You can override the default Infima variables here. */
:root {
--ifm-link-color: #268bd2;
--docusaurus-highlighted-code-line-bg: #eee8d5;
/* Solarized Base03 */
--ifm-color-primary: #002b36;
/* Solarized Base3 */
--ifm-color-primary-light-background: #fdf6e3;
/* Solarized Base02 */
--ifm-color-primary-dark: #073642;
/* Solarized Base00 */
--ifm-color-primary-dark: #657b83;
/* Solarized Base01 */
--ifm-color-primary-darker: #586e75;
/* Solarized Base00 */
--ifm-color-primary-darkest: #657b83;
/* Solarized Base2 */
--ifm-color-primary-light: #eee8d5;
/* Solarized Base02 */
--ifm-color-primary-darkest: #073642;
/* Solarized Base0 */
--ifm-color-primary-light: #839496;
/* Solarized Base1 */
--ifm-color-primary-lighter: #93a1a1;
/* Solarized Base0 */
--ifm-color-primary-lightest: #839496;
/* Solarized Base2 */
--ifm-color-primary-lightest: #eee8d5;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-link-color: #268bd2;
--docusaurus-highlighted-code-line-bg: #073642;
/* Solarized Base3 */
--ifm-color-primary: #fdf6e3;
/* Solarized Base03 */
@@ -47,5 +52,4 @@
/* Solarized Base0 */
--ifm-color-primary-lightest: #839496;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}

View File

@@ -16,6 +16,11 @@ function HomepageHeader() {
{siteConfig.title}
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<p className="projectDesc">
Holos is a holistic software development platform built from the most
popular open source projects.<br /> Build your developer platform in
no time.
</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 34 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,29 +0,0 @@
// Package website embeds the docs website for the server subcommand. Docs are
// served at /docs similar to how the ui is served at /ui.
package website
// DISABLED go:generate rm -rf build
// DISABLED go:generate mkdir build
// DISABLED go:generate npm run build
// DISABLED go:generate touch $GOFILE
import (
"embed"
"io/fs"
)
// Output must be the relative path to where the build tool places the static
// site index.html file.
const OutputPath = "build"
//go:embed all:build
var Dist embed.FS
// Root returns the static site root directory.
func Root() fs.FS {
sub, err := fs.Sub(Dist, OutputPath)
if err != nil {
panic(err)
}
return sub
}

View File

@@ -1,97 +1,10 @@
# PostgresCluster Backups
# ZITADEL Backups
This document describes how the S3 bucket for `PostgresCluster` backups is configured. These buckets are configured both for ZITADEL and for Holos
Server and are applicable to any service in Holos that stores data in a pgo `PostgresCluster` resource.
Refer to [Schedule backups](https://cloudnative-pg.io/documentation/1.23/backup/#scheduled-backups)
## Create the Bucket
Name: `holos-zitadel-backups` for `zitadel`
Name: `holos-server-backups` for `holos server`
> [!NOTE]
> The settings below match the default settings recommended by AWS.
By default ZITADEL is backed up daily to S3. When restoring into a new cluster
of the same name, increment the revision variable to create a new blank folder
for the new cluster WAL. The cluster will not initialize unless the WAL
directory is empty.
Object Ownership: `ACLs disabled` (recommended) Checked.
Block Public Access settings for this bucket: **`Block all public access`** Checked.
Bucket Versioning: `Disable`
Default encryption: `Server-side encryption with Amazon S3 managed keys (SSE-S3)`
Bucket Key: `Enable`
Object Lock: `Disable`
## Create an IAM Policy
Create one IAM Policy for each bucket to grant full access to the bucket. Replace the resource with each bucket name.
Name: `holos-zitadel-backups` for `zitadel`
Name: `holos-server-backups` for `holos server`
Description: `Read and write access to a specific bucket for pgrest operating within a pgo PostgresCluster.`
Policy JSON:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::holos-zitadel-backups",
"arn:aws:s3:::holos-zitadel-backups/*"
]
}
]
}
```
## Create an IAM Group
Create an IAM Group to attach the policy granting access to the bucket.
Name: `holos-zitadel-backups` for `zitadel`
Attach permission policies: `holos-zitadel-backups`
Name: `holos-server-backups` for `holos server`
Attach permission policies: `holos-server-backups`
## Create the IAM User
Create an IAM User entity for each PostgresCluster. Do not provide user access to the AWS Management Console.
Name: `holos-zitadel-backups` for `zitadel`
Group: `holos-zitadel-backups`
Name: `holos-server-backups` for `holos server`
Group: `holos-server-backups`
## Create an Access Key
Create an access key for `pgbackrest` associated with the `PostgresCluster`.
Description:
> Used by pgbackrest associated with the PostgresCluster resource. Refer to the PostgresCluster resource pgbackrest.cofiguration.secret.name for the stored location of the access key. Synced from the Management Cluster using an ExternalSecret.
## Create the Secret
Create a `Secret` in the holos management cluster usable by pgbackrest. This is a secret with a single key, `s3.conf` with the following format:
```
[global]
repo2-cipher-pass=
repo2-s3-key=
repo2-s3-key-secret=
repo3-cipher-pass=
repo3-s3-key=
repo3-s3-key-secret=
```
> [!NOTE]
> Use the same values for repo2 and repo3. The purpose is to make space for migrating if need be in the future.
Generate the cipher pass using. This password is used to encrypt all backups using client side before the backup is written to the bucket.
```
tr -dc A-Za-z0-9 </dev/urandom | head -c 64
```
Store the secret into the management cluster:
```
holos create secret --namespace zitadel holos-zitadel-backups \
--append-hash=false --from-file .
```
```
holos create secret --namespace holos holos-server-backups \
--append-hash=false --from-file .
```
The cluster will recovery from the previous rev.

View File

@@ -1,150 +1,3 @@
# Postgres Full Backup
Suppose you delete all objects in the S3 bucket hosting all postgres backups. You want to take a full backup ASAP of an existing PostgreSQL database.
The normal method of annotating the `postgrescluster` resource will not work because the job will error:
```
kubectl annotate postgrescluster zitadel postgres-operator.crunchydata.com/pgbackrest-backup="$(date)" --overwrite
postgrescluster.postgres-operator.crunchydata.com/zitadel annotated
```
Backup fails:
```
k get pods
NAME READY STATUS RESTARTS AGE
zitadel-backup-hk7w-76bfk 0/1 Error 0 65s
zitadel-backup-hk7w-d55v6 0/1 Error 0 44s
zitadel-backup-hk7w-l9dwm 0/1 Error 0 76s
zitadel-backup-hk7w-zcg69 0/1 Error 0 3s
zitadel-pgbouncer-d9f8cffc-nx8lq 2/2 Running 0 49m
zitadel-pgbouncer-d9f8cffc-s7g7x 2/2 Running 0 49m
zitadel-pgha1-2xv2-0 5/5 Running 0 48m
zitadel-pgha1-78f4-0 5/5 Running 0 49m
zitadel-repo-host-0 2/2 Running 0 49m
```
Error is: `FileMissingError: unable to open missing file '/pgbackrest/prod-iam/zitadel/repo2/backup/db/backup.info.copy' for read`
```
time="2024-04-08T00:02:11Z" level=info msg="crunchy-pgbackrest starts"
time="2024-04-08T00:02:11Z" level=info msg="debug flag set to false"
time="2024-04-08T00:02:12Z" level=info msg="backrest backup command requested"
time="2024-04-08T00:02:12Z" level=info msg="command to execute is [pgbackrest backup --stanza=db --repo=2 --type=full]"
time="2024-04-08T00:02:12Z" level=info msg="output=[]"
time="2024-04-08T00:02:12Z" level=info msg="stderr=[ERROR: [055]: unable to load info file '/pgbackrest/prod-iam/zitadel/repo2/backup/db/backup.info' or '/pgbackrest/prod-iam/zitadel/repo2/backup/db/backup.info.copy':\n FileMissingError: unable to open missing file '/pgbackrest/prod-iam/zitadel/repo2/backup/db/backup.info' for read\n FileMissingError: unable to open missing file '/pgbackrest/prod-iam/zitadel/repo2/backup/db/backup.info.copy' for read\n HINT: backup.info cannot be opened and is required to perform a backup.\n HINT: has a stanza-create been performed?\n]"
time="2024-04-08T00:02:12Z" level=fatal msg="command terminated with exit code 55"
```
## Fix Process
We need to edit the postgrescluster. We're going to have the controller re-initialize the backup repository from scratch by removing it and re-adding it.
First, suspend flux:
```
flux suspend ks prod-iam-zitadel prod-iam-postgres
```
Save the config to two files:
```
kubectl get postgresclusters.postgres-operator.crunchydata.com zitadel -o yaml > orig.yaml
cp orig.yaml new.yaml
```
Remove the follow fields and re-apply the cluster. This will leave the cluster running and available while the controller reconciles the repo configuration:
```diff
--- orig.yaml 2024-04-07 17:08:26.834715820 -0700
+++ new.yaml 2024-04-07 17:08:57.418546067 -0700
@@ -4,6 +4,4 @@
annotations:
holos.run/description: ""
- postgres-operator.crunchydata.com/pgbackrest-backup: Sun 07 Apr 2024 05:01:35
- PM PDT
creationTimestamp: "2024-04-07T23:10:44Z"
finalizers:
@@ -26,12 +24,5 @@
repo1-retention-full: "1"
repo2-cipher-type: aes-256-cbc
- repo2-path: /pgbackrest/prod-iam/zitadel/repo2
- repo2-retention-full: "14"
- repo2-retention-full-type: time
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.49-0
- manual:
- options:
- - --type=full
- repoName: repo2
repos:
- name: repo1
@@ -43,12 +34,4 @@
requests:
storage: 4Gi
- - name: repo2
- s3:
- bucket: ois-zitadel-backups
- endpoint: s3.dualstack.us-east-2.amazonaws.com
- region: us-east-2
- schedules:
- differential: 0 1 * * 1-6
- full: 0 1 * * 0
restore:
enabled: true
```
Apply the config and wait for the controller to reconcile:
```
k apply --server-side=true -f new.yaml --force-conflicts
```
Check for reconciliation:
```
kubectl -n postgres-operator logs -l app.kubernetes.io/name=pgo | tail -1
```
```
time="2024-04-08T00:10:03Z" level=debug msg="reconciled cluster" controller=postgrescluster controllerGroup=postgres-operator.crunchydata.com controllerKind=PostgresCluster name=zitadel namespace=prod-iam postgresCluster=prod-iam/zitadel reconcileID=cc8c8eb7-9787-4504-8ecd-a04ec84fbc0b version=5.5.1-0-amd64
```
Re-add the repo host configuration
```
grep -v 'resourceVersion:' orig.yaml | k apply --server-side=true --force-conflicts -f-
```
```
postgrescluster.postgres-operator.crunchydata.com/zitadel serverside-applied
```
The full backup should be running and writing to S3 now:
```
kubectl logs -l postgres-operator.crunchydata.com/pgbackrest-backup=manual
```
```
time="2024-04-08T00:12:54Z" level=info msg="crunchy-pgbackrest starts"
time="2024-04-08T00:12:54Z" level=info msg="debug flag set to false"
time="2024-04-08T00:12:54Z" level=info msg="backrest backup command requested"
time="2024-04-08T00:12:54Z" level=info msg="command to execute is [pgbackrest backup --stanza=db --repo=2 --type=full]"
time="2024-04-08T00:16:02Z" level=info msg="output=[]"
time="2024-04-08T00:16:02Z" level=info msg="stderr=[]"
time="2024-04-08T00:16:02Z" level=info msg="crunchy-pgbackrest ends"
```
Finally, resume flux:
```
flux resume ks prod-iam-postgres prod-iam-zitadel
```
```
► resuming kustomization prod-iam-postgres in flux-system namespace
✔ kustomization resumed
► resuming kustomization prod-iam-zitadel in flux-system namespace
✔ kustomization resumed
```
Refer to [On-demand backups](https://cloudnative-pg.io/documentation/1.23/backup/#on-demand-backups)

71
go.mod
View File

@@ -16,6 +16,7 @@ require (
github.com/fullstorydev/grpcurl v1.9.1
github.com/go-jose/go-jose/v3 v3.0.3
github.com/gofrs/uuid v4.4.0+incompatible
github.com/google/ko v0.15.4
github.com/int128/kubelogin v1.28.0
github.com/jackc/pgx/v5 v5.5.5
github.com/lmittmann/tint v1.0.4
@@ -37,7 +38,7 @@ require (
google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002
honnef.co/go/tools v0.4.7
k8s.io/api v0.29.2
k8s.io/apimachinery v0.29.2
k8s.io/apimachinery v0.29.4
k8s.io/client-go v0.29.2
k8s.io/kubectl v0.29.2
modernc.org/sqlite v1.29.6
@@ -49,7 +50,16 @@ require (
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 // indirect
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
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/Masterminds/goutils v1.1.1 // indirect
@@ -62,8 +72,26 @@ require (
github.com/achanda/go-sysctl v0.0.0-20160222034550-6be7678c45d2 // indirect
github.com/agext/levenshtein v1.2.1 // indirect
github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/alessio/shellescape v1.4.1 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.27.13 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.13 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.28.0 // indirect
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.20.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.28.7 // indirect
github.com/aws/smithy-go v1.20.2 // indirect
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20240514230400-03fa26f5508f // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/bufbuild/protocompile v0.10.0 // indirect
@@ -79,6 +107,7 @@ require (
github.com/choria-io/go-updater v0.1.0 // indirect
github.com/choria-io/stream-replicator v0.8.3-0.20230503130504-86152f798aec // indirect
github.com/choria-io/tokens v0.0.4-0.20240316144214-a929d9325d48 // indirect
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/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect
@@ -86,20 +115,23 @@ require (
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.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
github.com/docker/cli v26.0.0+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v26.0.2+incompatible // indirect
github.com/docker/docker v26.1.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.1 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/emicklei/proto v1.10.0 // indirect
github.com/emicklei/proto v1.12.1 // indirect
github.com/emirpasic/gods v1.12.0 // 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 v5.6.0 // 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
@@ -115,10 +147,17 @@ require (
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/analysis v0.22.0 // indirect
github.com/go-openapi/errors v0.21.0 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/loads v0.21.5 // indirect
github.com/go-openapi/runtime v0.27.1 // indirect
github.com/go-openapi/spec v0.20.13 // indirect
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/gobwas/glob v0.2.3 // indirect
github.com/gofrs/uuid/v5 v5.0.0 // indirect
@@ -127,11 +166,12 @@ require (
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/cel-go v0.20.1 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-containerregistry v0.19.1 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20240416155748-26353dc0451f // indirect
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/google/wire v0.5.0 // indirect
@@ -144,7 +184,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
github.com/guptarohit/asciigraph v0.7.1 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // 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
@@ -159,12 +199,14 @@ require (
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
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/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.1.0 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/logrusorgru/aurora/v4 v4.0.0 // indirect
github.com/looplab/fsm v1.0.1 // indirect
@@ -196,6 +238,7 @@ require (
github.com/nats-io/nuid v1.0.1 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
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
@@ -203,6 +246,7 @@ require (
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/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
@@ -214,7 +258,7 @@ require (
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-20230328191034-3462fbc510c0 // indirect
github.com/protocolbuffers/txtpbfmt v0.0.0-20231025115547-084445ff1adf // 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
@@ -225,11 +269,15 @@ require (
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/samber/lo v1.39.0 // indirect
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
github.com/shirou/gopsutil/v3 v3.24.3 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sigstore/cosign/v2 v2.2.3 // indirect
github.com/sigstore/rekor v1.3.4 // indirect
github.com/sigstore/sigstore v1.8.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
@@ -243,6 +291,7 @@ require (
github.com/tidwall/gjson v1.17.1 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/vbatts/tar-split v0.11.5 // indirect
@@ -255,6 +304,7 @@ require (
github.com/yuin/goldmark v1.4.13 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zclconf/go-cty v1.8.0 // indirect
go.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
@@ -262,6 +312,7 @@ require (
go.opentelemetry.io/otel/sdk v1.25.0 // indirect
go.opentelemetry.io/otel/trace v1.25.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.24.0 // indirect
@@ -276,6 +327,7 @@ require (
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa // indirect
google.golang.org/grpc v1.62.1 // indirect
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
@@ -292,5 +344,6 @@ require (
modernc.org/token v1.1.0 // indirect
mvdan.cc/xurls/v2 v2.2.0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kind v0.23.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)

217
go.sum
View File

@@ -53,8 +53,33 @@ entgo.io/ent v0.13.1 h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE=
entgo.io/ent v0.13.1/go.mod h1:qCEmo+biw3ccBn9OyL4ZK5dfpwg++l1Gxwac5B1206A=
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=
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc=
github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw=
github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs=
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=
github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8=
github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0=
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
@@ -91,6 +116,8 @@ github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRB
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
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-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
@@ -102,6 +129,40 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA=
github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
github.com/aws/aws-sdk-go-v2/config v1.27.13 h1:WbKW8hOzrWoOA/+35S5okqO/2Ap8hkkFUzoW8Hzq24A=
github.com/aws/aws-sdk-go-v2/config v1.27.13/go.mod h1:XLiyiTMnguytjRER7u5RIkhIqS8Nyz41SwAWb4xEjxs=
github.com/aws/aws-sdk-go-v2/credentials v1.17.13 h1:XDCJDzk/u5cN7Aple7D/MiAhx1Rjo/0nueJ0La8mRuE=
github.com/aws/aws-sdk-go-v2/credentials v1.17.13/go.mod h1:FMNcjQrmuBYvOTZDtOLCIu0esmxjF7RuA/89iSXWzQI=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 h1:FVJ0r5XTHSmIHJV6KuDmdYhEpvlHpiSd38RQWhut5J4=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1/go.mod h1:zusuAeqezXzAB24LGuzuekqMAEgWkVYukBec3kr3jUg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/service/ecr v1.28.0 h1:rdPrcOZmqT2F+yzmKEImrx5XUs7Hpf4V9Rp6E8mhsxQ=
github.com/aws/aws-sdk-go-v2/service/ecr v1.28.0/go.mod h1:if7ybzzjOmDB8pat9FE35AHTY6ZxlYSy3YviSmFZv8c=
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.5 h1:452e/nFuqPvwPg+1OD2CG/v29R9MH8egJSJKh2Qduv8=
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.5/go.mod h1:8pvvNAklmq+hKmqyvFoMRg0bwg9sdGOvdwximmKiKP0=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.6 h1:o5cTaeunSpfXiLTIBx5xo2enQmiChtu1IBbzXnfU9Hs=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.6/go.mod h1:qGzynb/msuZIE8I75DVRCUXw3o3ZyBmUvMwQ2t/BrGM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0 h1:Qe0r0lVURDDeBQJ4yP+BOrJkvkiCo/3FH/t+wY11dmw=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0/go.mod h1:mUYPBhaF2lGiukDEjJX2BLRRKTmoUSitGDUgM4tRxak=
github.com/aws/aws-sdk-go-v2/service/sts v1.28.7 h1:et3Ta53gotFR4ERLXXHIHl/Uuk1qYpP5uU7cvNql8ns=
github.com/aws/aws-sdk-go-v2/service/sts v1.28.7/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw=
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 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=
@@ -146,6 +207,8 @@ github.com/choria-io/stream-replicator v0.8.3-0.20230503130504-86152f798aec h1:j
github.com/choria-io/stream-replicator v0.8.3-0.20230503130504-86152f798aec/go.mod h1:QVvT5tjYSYmvqx585herBk0aK13DS1j/wJVDDWuLFww=
github.com/choria-io/tokens v0.0.4-0.20240316144214-a929d9325d48 h1:KyL4w+dxAOfqi4Wds6Fh0632sxBw0YvRqL9fqMziGBI=
github.com/choria-io/tokens v0.0.4-0.20240316144214-a929d9325d48/go.mod h1:dEyJo/309e8n141nzx1u82QuXVt6mt42V1Jn9CkJJPs=
github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4=
github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589/go.mod h1:OuDyvmLnMCwa2ep4Jkm6nyA0ocJuZlGyk2gGseVzERM=
github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
@@ -194,26 +257,30 @@ github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkz
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/dgryski/trifles v0.0.0-20220729183022-231ecf6ed548 h1:acdRTG6Vp8kMaN3lVkI49O/BuHjg+GH5i/MJjYZV+BM=
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/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.0.0+incompatible h1:90BKrx1a1HKYpSnnBFR6AgDq/FqkHxwlUyzJVPxD30I=
github.com/docker/cli v26.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v26.0.2+incompatible h1:yGVmKUFGgcxA6PXWAokO0sQL22BrQ67cgVjko8tGdXE=
github.com/docker/docker v26.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo=
github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
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/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=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/proto v1.10.0 h1:pDGyFRVV5RvV+nkBK9iy3q67FBy9Xa7vwrOTE+g5aGw=
github.com/emicklei/proto v1.10.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emicklei/proto v1.12.1 h1:6n/Z2pZAnBwuhU66Gs8160B8rrrYKo7h2F2sCOnNceE=
github.com/emicklei/proto v1.12.1/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -228,6 +295,8 @@ github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU
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 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
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=
@@ -247,6 +316,8 @@ github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7Dlme
github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
@@ -286,22 +357,35 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-openapi/analysis v0.22.0 h1:wQ/d07nf78HNj4u+KiSY0sT234IAyePPbMgpUjUJQR0=
github.com/go-openapi/analysis v0.22.0/go.mod h1:acDnkkCI2QxIo8sSIPgmp1wUlRohV7vfGtAIVae73b0=
github.com/go-openapi/errors v0.21.0 h1:FhChC/duCnfoLj1gZ0BgaBmzhJC2SL/sJr8a2vAobSY=
github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho=
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU=
github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4=
github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRzT0=
github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8=
github.com/go-openapi/runtime v0.27.1 h1:ae53yaOoh+fx/X5Eaq8cRmavHgDma65XPZuvBqvJYto=
github.com/go-openapi/runtime v0.27.1/go.mod h1:fijeJEiEclyS8BRurYE1DE5TLb9/KZl6eAdbzjsrlLU=
github.com/go-openapi/spec v0.20.13 h1:XJDIN+dLH6vqXgafnl5SUIMnzaChQ6QTo0/UPMbkIaE=
github.com/go-openapi/spec v0.20.13/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw=
github.com/go-openapi/strfmt v0.22.0 h1:Ew9PnEYc246TwrEspvBdDHS4BVKXy/AOVsfqGDgAcaI=
github.com/go-openapi/strfmt v0.22.0/go.mod h1:HzJ9kokGIju3/K6ap8jL+OlGAbjpSv27135Yr9OivU4=
github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE=
github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE=
github.com/go-openapi/validate v0.22.4 h1:5v3jmMyIPKTR8Lv9syBAIRxG6lY0RqeBPB1LKEijzk8=
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-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-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
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=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
@@ -315,10 +399,12 @@ github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
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=
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
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=
@@ -354,6 +440,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -362,8 +449,8 @@ 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=
github.com/google/flatbuffers v23.3.3+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU=
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -371,6 +458,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -381,6 +469,8 @@ github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDIt
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/ko v0.15.4 h1:0blRbIdPmSy6v4LvedGxbI/8krdJYQgbSih3v6Y8V1c=
github.com/google/ko v0.15.4/go.mod h1:ZkcmfV91Xt6ZzOBHc/cXXGYnqWdNWDVy/gHoUU9sjag=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -390,11 +480,14 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/pprof v0.0.0-20240416155748-26353dc0451f h1:WpZiq8iqvGjJ3m3wzAVKL6+0vz7VkE79iSy9GII00II=
github.com/google/pprof v0.0.0-20240416155748-26353dc0451f/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 h1:SJ+NtwL6QaZ21U+IrK7d0gGgpjGGvd2kz+FzTHVzdqI=
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2/go.mod h1:Tv1PlzqC9t8wNnpPdctvtSUOPUUg4SHeE6vR1Ir2hmg=
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=
@@ -427,8 +520,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
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.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM=
github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
@@ -436,10 +529,12 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
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/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=
@@ -468,9 +563,16 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jdx/go-netrc v1.0.0 h1:QbLMLyCZGj0NA8glAhxUpf1zDg6cxnWgMBbjq40W0gQ=
github.com/jdx/go-netrc v1.0.0/go.mod h1:Gh9eFQJnoTNIRHXl2j5bJXA1u84hQWJWgGh569zF3v8=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg=
github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
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/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.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -484,6 +586,7 @@ github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+
github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
@@ -500,6 +603,8 @@ 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/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/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc=
@@ -571,6 +676,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
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/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=
@@ -590,16 +696,27 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM=
github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
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/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/open-policy-agent/opa v0.63.0 h1:ztNNste1v8kH0/vJMJNquE45lRvqwrM5mY9Ctr9xIXw=
@@ -611,6 +728,8 @@ github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2sz
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
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/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
@@ -627,6 +746,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/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=
github.com/princjef/gomarkdoc v1.1.0/go.mod h1:HI3w0Zv8H03ecak/IqVAcPFTuPt7sn7Top6xbgCs1Qk=
github.com/princjef/mageutil v1.0.0 h1:1OfZcJUMsooPqieOz2ooLjI+uHUo618pdaJsbCXcFjQ=
@@ -642,8 +763,8 @@ github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZA
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-20230328191034-3462fbc510c0 h1:sadMIsgmHpEOGbUs6VtHBXRR1OHevnj7hLx9ZcdNGW4=
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
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/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=
@@ -671,6 +792,8 @@ github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA=
github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU=
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
@@ -687,6 +810,12 @@ github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnj
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=
github.com/sigstore/cosign/v2 v2.2.3/go.mod h1:WpMn4MBt0cI23GdHsePwO4NxhX1FOz1ITGB3ALUjFaI=
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.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@@ -720,6 +849,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@@ -736,6 +866,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
@@ -752,6 +884,9 @@ github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJ
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
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-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=
@@ -760,6 +895,7 @@ github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5 h1:gmD7q6cCJfBbcu
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5/go.mod h1:fVwOndYN3s5IaGlMucfgxwMhqwcaJtlGejBU6zX6Yxw=
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=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -771,6 +907,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
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=
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -801,6 +939,8 @@ go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxi
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@@ -815,7 +955,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
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.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
@@ -860,6 +1004,7 @@ golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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=
@@ -880,6 +1025,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
@@ -888,6 +1034,9 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
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=
@@ -918,6 +1067,7 @@ golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.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-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=
@@ -928,10 +1078,13 @@ 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-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=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -952,16 +1105,19 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -992,7 +1148,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
@@ -1046,6 +1204,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
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=
@@ -1159,6 +1318,9 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
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/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=
gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
@@ -1177,6 +1339,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -1193,8 +1356,8 @@ 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.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8=
k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU=
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=
@@ -1228,6 +1391,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
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/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=

7
hack/cspell Executable file
View File

@@ -0,0 +1,7 @@
#! /bin/bash
#
set -euo pipefail
TOPLEVEL="$(cd $(dirname "$0") && git rev-parse --show-toplevel)"
cd "${TOPLEVEL}" && npx cspell ./doc/md/**/*.{md,mdx,markdown}

25
hack/deploy Executable file
View File

@@ -0,0 +1,25 @@
#! /bin/bash
#
tmpdir="$(mktemp -d)"
finish() {
rm -rf "$tmpdir"
}
trap finish EXIT
set -euo pipefail
: ${GIT_DETAIL:=$(git describe --tags HEAD)}
: ${GIT_SUFFIX:=$(test -n "`git status --porcelain`" && echo "-dirty" || echo "")}
cd "$tmpdir"
git clone --depth 1 git@github.com:holos-run/holos-infra.git
cd holos-infra/saas
echo '{"HolosVersion":"'${GIT_DETAIL}${GIT_SUFFIX}'"}' > userdata/holos.json
holos render platform ./platform
git add .
git commit -m "${GIT_DETAIL}${GIT_SUFFIX} [auto]"
git --no-pager show --stat
git push origin HEAD
echo
echo "https://argocd.admin.aws2.holos.run/applications/prod-holos-app"

View File

@@ -1,8 +0,0 @@
FROM 271053619184.dkr.ecr.us-east-2.amazonaws.com/holos-run/container-images/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

View File

@@ -1,21 +0,0 @@
#! /bin/bash
set -euo pipefail
PARENT="$(cd $(dirname "$0") && pwd)"
# If necessary
if [[ -s "${PARENT}/aws-login.last" ]]; then
last="$(<"${PARENT}/aws-login.last")"
now="$(date +%s)"
if [[ $(( now - last )) -lt 28800 ]]; then
echo "creds are still valid" >&2
exit 0
fi
fi
aws sso logout
aws sso login
aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin "${AWS_ACCOUNT}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
# Touch a file so tilt docker_build can watch it as a dep
date +%s > "${PARENT}/aws-login.last"

View File

@@ -1,7 +0,0 @@
[profile dev-holos]
sso_account_id = 271053619184
sso_role_name = AdministratorAccess
sso_start_url = https://openinfrastructure.awsapps.com/start
sso_region = us-east-2
region = us-east-2
output = json

View File

@@ -3,7 +3,9 @@
set -euo pipefail
TOPLEVEL="$(cd $(dirname "$0")/.. && pwd)"
export NAMESPACE="${USER}-holos"
echo "Local development assumes a k3d-workload local cluster exists." >&2
echo "Refer to https://holos.run/docs/tutorial/local/k3d" >&2
kubectl config view --minify --context=k3d-workload --flatten > "${TOPLEVEL}/kubeconfig"
export KUBECONFIG="${TOPLEVEL}/kubeconfig"
envsubst < "${KUBECONFIG}.template" > "${KUBECONFIG}"
export TILT_WRAPPER=1
exec tilt "$@"

View File

@@ -1,153 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: container-registry
app.kubernetes.io/instance: holos-system-ecr
app.kubernetes.io/name: holos-system-ecr
app.kubernetes.io/part-of: holos
name: holos-system-ecr
namespace: holos-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/component: container-registry
app.kubernetes.io/instance: holos-system-ecr
app.kubernetes.io/name: holos-system-ecr
app.kubernetes.io/part-of: holos
name: holos-system-ecr
rules:
- apiGroups:
- ""
resources:
- secrets
- namespaces
verbs:
- list
- apiGroups:
- ""
resourceNames:
- holos-system-ecr-image-pull-creds
resources:
- secrets
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/component: container-registry
app.kubernetes.io/instance: holos-system-ecr
app.kubernetes.io/name: holos-system-ecr
app.kubernetes.io/part-of: holos
name: holos-system-ecr
namespace: holos-system
roleRef:
kind: ClusterRole
name: holos-system-ecr
subjects:
- kind: ServiceAccount
name: holos-system-ecr
namespace: holos-system
---
apiVersion: v1
data:
refresh.sh: |-
#! /bin/bash
tmpdir="$(mktemp -d)"
finish() {
rm -rf "${tmpdir}"
}
trap finish EXIT
set -euo pipefail
aws sts assume-role-with-web-identity \
--role-arn ${AWS_ROLE_ARN} \
--role-session-name CronJob \
--web-identity-token file:///run/secrets/irsa/serviceaccount/token \
> "${tmpdir}/creds.json"
export AWS_ACCESS_KEY_ID=$(jq -r .Credentials.AccessKeyId "${tmpdir}/creds.json")
export AWS_SECRET_ACCESS_KEY=$(jq -r .Credentials.SecretAccessKey "${tmpdir}/creds.json")
export AWS_SESSION_TOKEN=$(jq -r .Credentials.SessionToken "${tmpdir}/creds.json")
set -x
aws ecr get-login-password --region ${AWS_REGION} \
| docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com
kubectl create secret docker-registry 'holos-system-ecr-image-pull-creds' \
--from-file=.dockerconfigjson=${HOME}/.docker/config.json \
--dry-run=client -o yaml \
> "${tmpdir}/secret.yaml"
# Get namespaces one per line
kubectl -o=jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' get namespaces > ${tmpdir}/namespaces.txt
# Copy the secret to all namespaces
for ns in $(grep -vE '^gke-|^kube-|^gmp-' ${tmpdir}/namespaces.txt); do
echo "---" >> "${tmpdir}/secretlist.yaml"
kubectl --dry-run=client -o yaml -n $ns apply -f "${tmpdir}/secret.yaml" >> "${tmpdir}/secretlist.yaml"
done
kubectl apply --server-side=true -f "${tmpdir}/secretlist.yaml"
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/component: image-pull-secret
app.kubernetes.io/instance: holos-system-ecr
app.kubernetes.io/name: refresher
app.kubernetes.io/part-of: holos
name: holos-system-ecr
namespace: holos-system
---
apiVersion: batch/v1
kind: CronJob
metadata:
labels:
app.kubernetes.io/component: container-registry
app.kubernetes.io/instance: holos-system-ecr
app.kubernetes.io/name: holos-system-ecr
app.kubernetes.io/part-of: holos
name: holos-system-ecr
namespace: holos-system
spec:
schedule: 0 */4 * * *
jobTemplate:
spec:
template:
spec:
containers:
- command:
- bash
- /app/scripts/refresh.sh
env:
- name: AWS_ACCOUNT
value: "271053619184"
- name: AWS_REGION
value: us-east-2
- name: AWS_ROLE_ARN
value: arn:aws:iam::271053619184:role/ImagePull
image: quay.io/holos/toolkit:latest
imagePullPolicy: Always
name: toolkit
resources:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 50m
memory: 64Mi
volumeMounts:
- mountPath: /app/scripts
name: scripts
- mountPath: /run/secrets/irsa/serviceaccount
name: irsa
restartPolicy: OnFailure
serviceAccountName: holos-system-ecr
volumes:
- configMap:
name: holos-system-ecr
name: scripts
- name: irsa
projected:
sources:
- serviceAccountToken:
path: "token"
audience: "irsa"
expirationSeconds: 3600

View File

@@ -1,5 +0,0 @@
#! /bin/bash
#
set -euo pipefail
cp "${KUBECONFIG}.template" "${KUBECONFIG}"
kubectl config set-context --current --namespace "${NAMESPACE}"

View File

@@ -1,226 +0,0 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: '{name}'
namespace: '{namespace}'
labels:
app: '{name}'
holos.run/developer: '{developer}'
spec:
selector:
matchLabels:
app: '{name}'
template:
metadata:
labels:
app: '{name}'
holos.run/developer: '{developer}'
sidecar.istio.io/inject: 'true'
spec:
serviceAccountName: holos
containers:
- name: holos
image: holos # Tilt appends a tilt-* tag for the built docker image
# args are configured in the Tiltfile
env:
- name: GOMAXPROCS
value: '1'
- name: TZ
value: '{tz}'
- name: SHUTDOWN_DELAY
value: '0'
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: holos-pguser-holos
key: uri
ports:
- name: http
containerPort: {listen_port}
protocol: TCP
resources:
requests:
cpu: 250m
memory: 100Mi
limits:
cpu: 1000m
memory: 200Mi
---
apiVersion: v1
kind: Service
metadata:
name: '{name}'
namespace: '{namespace}'
labels:
app: '{name}'
holos.run/developer: '{developer}'
spec:
type: ClusterIP
selector:
app: '{name}'
ports:
- name: http
port: {listen_port}
appProtocol: http2
protocol: TCP
targetPort: {listen_port}
- name: metrics
port: {metrics_port}
appProtocol: http
protocol: TCP
targetPort: {metrics_port}
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: '{name}'
namespace: '{namespace}'
labels:
app: '{name}'
holos.run/developer: '{developer}'
spec:
endpoints:
- port: metrics
path: /metrics
interval: 15s
selector:
matchLabels:
app: '{name}'
holos.run/developer: '{developer}'
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: '{name}'
namespace: '{namespace}'
labels:
app: '{name}'
holos.run/developer: '{developer}'
spec:
gateways:
- istio-ingress/default
hosts:
- '{developer}.app.dev.k2.holos.run'
http:
- name: "coffee-ui"
match:
- uri:
prefix: "/ui"
route:
- destination:
host: coffee
port:
number: 4200
- name: "holos-api"
route:
- destination:
host: '{name}'
port:
number: {listen_port}
---
apiVersion: v1
kind: Service
metadata:
name: coffee
spec:
ports:
- protocol: TCP
port: 4200
---
apiVersion: v1
kind: Endpoints
metadata:
name: coffee
subsets:
- addresses:
- ip: 192.168.2.21
ports:
- port: 4200
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: holos
namespace: '{namespace}'
labels:
app: '{name}'
holos.run/developer: '{developer}'
imagePullSecrets:
- name: kube-system-ecr-image-pull-creds
---
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PGAdmin
metadata:
name: 'pgadmin'
namespace: '{namespace}'
labels:
holos.run/developer: '{developer}'
spec:
serverGroups:
- name: holos
postgresClusterSelector:
matchLabels:
holos.run/developer: '{developer}'
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
---
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: 'holos'
namespace: '{namespace}'
labels:
holos.run/developer: '{developer}'
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.1-0
postgresVersion: 16
users:
- name: holos
databases:
- holos
options: 'SUPERUSER'
- name: '{developer}'
databases:
- holos
- '{developer}'
options: 'SUPERUSER'
# https://access.crunchydata.com/documentation/postgres-operator/latest/architecture/user-management
instances:
- name: db
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
postgres-operator.crunchydata.com/cluster: '{name}'
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.47-2
# https://github.com/CrunchyData/postgres-operator/issues/2531#issuecomment-1713676019
global:
archive-async: "y"
archive-push-queue-max: "100MiB"
spool-path: "/pgdata/backups"
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,2 @@
resources:
- https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.23/releases/cnpg-1.23.2.yaml

View File

@@ -0,0 +1,74 @@
---
# Source: CUE apiObjects.Deployment.holos
metadata:
name: holos
namespace: dev-holos
labels:
app.holos.run/environment: dev
app.holos.run/name: holos
app.holos.run/component: app
app.kubernetes.io/component: server
render.holos.run/component: dev-holos-app
spec:
selector:
matchLabels:
app.kubernetes.io/component: server
template:
metadata:
labels:
app.holos.run/environment: dev
app.holos.run/name: holos
app.holos.run/component: app
app.kubernetes.io/component: server
sidecar.istio.io/inject: "true"
render.holos.run/component: dev-holos-app
spec:
serviceAccountName: holos
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: holos
image: k3d-registry.holos.localhost:5100/holos:latest
imagePullPolicy: IfNotPresent
command:
- /app/bin/holos
- server
- --log-format=json
- --oidc-issuer=https://login.holos.run
- --oidc-audience=275571128859132936
env:
- name: TZ
value: '{tz}'
- name: GOMAXPROCS
value: '1'
- name: SHUTDOWN_DELAY
value: '0'
- name: DATABASE_URL
valueFrom:
secretKeyRef:
key: uri
name: holos-app
ports:
- containerPort: 3000
name: http
protocol: TCP
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
resources:
limits:
cpu: "0.5"
memory: 512Mi
requests:
cpu: "0.5"
memory: 512Mi
strategy:
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
kind: Deployment
apiVersion: apps/v1

View File

@@ -0,0 +1,27 @@
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
labels:
app.kubernetes.io/name: authpolicy-allow-app
app.kubernetes.io/part-of: default-gateway
name: authpolicy-allow-app
namespace: istio-gateways
spec:
action: ALLOW
rules:
- to:
- operation:
hosts:
- app.holos.localhost
- app.holos.localhost:*
when:
- key: request.auth.principal
values:
- https://login.holos.run/*
- key: request.auth.audiences
values:
- 270319630705329162@holos_platform
- "275571128859132936"
selector:
matchLabels:
istio.io/gateway-name: default

View File

@@ -0,0 +1,15 @@
---
# Source: CUE apiObjects.Cluster.holos
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: holos
namespace: dev-holos
labels:
app.holos.run/environment: dev
app.holos.run/name: holos
app.holos.run/component: database
spec:
instances: 1
storage:
size: 1Gi

View File

@@ -0,0 +1,28 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
labels:
app: holos
name: holos
namespace: istio-gateways
spec:
hostnames:
- app.holos.localhost
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: default
namespace: istio-gateways
rules:
- backendRefs:
- group: ""
kind: Service
name: holos
namespace: dev-holos
port: 3000
weight: 1
matches:
- path:
type: PathPrefix
value: /

View File

@@ -0,0 +1,49 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: holos
namespace: dev-holos
labels:
app.holos.run/environment: dev
app.holos.run/name: holos
---
# Source: CUE apiObjects.Service.holos
apiVersion: v1
metadata:
name: holos
namespace: dev-holos
labels:
app.holos.run/environment: dev
app.holos.run/name: holos
annotations: {}
spec:
type: ClusterIP
selector:
app.kubernetes.io/component: server
ports:
- appProtocol: http2
name: http
port: 3000
protocol: TCP
targetPort: 3000
- appProtocol: http
name: metrics
port: 9090
protocol: TCP
targetPort: 9090
kind: Service
---
# Source: CUE apiObjects.ReferenceGrant.istio-gateways
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: istio-gateways
namespace: dev-holos
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: istio-gateways
to:
- group: ""
kind: Service

View File

@@ -0,0 +1,50 @@
---
# Source: CUE apiObjects.Job.holos
apiVersion: batch/v1
kind: Job
metadata:
name: holos-init
namespace: dev-holos
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation
helm.sh/hook-weight: "2"
spec:
activeDeadlineSeconds: 300
backoffLimit: 5
template:
spec:
containers:
- name: holos
image: quay.io/holos-run/holos:v0.87.2-26-g3845174
imagePullPolicy: IfNotPresent
command:
- /app/bin/holos
- server
- init
- --log-level=debug
- --log-format=json
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
key: uri
name: holos-app
securityContext:
capabilities:
drop:
- ALL
runAsNonRoot: true
allowPrivilegeEscalation: false
resources:
limits:
cpu: "0.5"
memory: 512Mi
requests:
cpu: "0.5"
memory: 512Mi
restartPolicy: OnFailure
serviceAccountName: holos
securityContext:
seccompProfile:
type: RuntimeDefault

View File

@@ -1,45 +0,0 @@
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpVENDQVRDZ0F3SUJBZ0lSQU9TenlHd2VMK3N4NjVvckVCTXV1c293Q2dZSUtvWkl6ajBFQXdJd0ZURVQKTUJFR0ExVUVDaE1LYTNWaVpYSnVaWFJsY3pBZUZ3MHlOREF5TVRNd05UQTRNRFJhRncwek5EQXlNVEF3TlRBNApNRFJhTUJVeEV6QVJCZ05WQkFvVENtdDFZbVZ5Ym1WMFpYTXdXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CCkJ3TkNBQVREWUluR09EN2ZpbFVIeXNpZG1ac2Vtd2liTk9hT1A5ZzVJT1VsTkllUHZ1Y01ZV01aNWNkZXpVQmIKMGh4Zm1WYXR0QWxpcnorMlFpVld5by9WZFNsOG8yRXdYekFPQmdOVkhROEJBZjhFQkFNQ0FvUXdIUVlEVlIwbApCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPCkJCWUVGTGVtcEhSM25lVXYvSUc1WWpwempDbWUydmIyTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUNZajRsNUgKL043OG5UcnJxQzMxWjlsY0lpODEwcno5N3JIdUJnWFZZUkxBQWlBNHVEc0YyNEI5aGV3WklUbWEwaHpCMjNOdQpwZnprTWV5VzZHV2U2RWh4NGc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://k2.core.ois.run:6443
name: k2
contexts:
- context:
cluster: k2
namespace: default
user: admin@k2
name: admin@k2
- context:
cluster: k2
namespace: ${NAMESPACE}
user: oidc
name: sso@k2
current-context: sso@k2
kind: Config
preferences: {}
users:
- name: admin@k2
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJoRENDQVNxZ0F3SUJBZ0lRVXZKTlEvV0Ewalg5RXF6ZElIMFA4ekFLQmdncWhrak9QUVFEQWpBVk1STXcKRVFZRFZRUUtFd3ByZFdKbGNtNWxkR1Z6TUI0WERUSTBNRE14TVRJek1UY3hPVm9YRFRJMU1ETXhNVEl6TVRjeQpPVm93S1RFWE1CVUdBMVVFQ2hNT2MzbHpkR1Z0T20xaGMzUmxjbk14RGpBTUJnTlZCQU1UQldGa2JXbHVNRmt3CkV3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFNjZrMStQb1l5OHlPWTZkRFR5MHJYRTUvRlZJVU0rbkcKNEVzSXZxOHBuZ2lVRWRkeTdYM3hvZ2E5d2NSZy8xeVZ4Q2FNbzBUVEZveXkxaVZMMWxGWDNLTklNRVl3RGdZRApWUjBQQVFIL0JBUURBZ1dnTUJNR0ExVWRKUVFNTUFvR0NDc0dBUVVGQndNQ01COEdBMVVkSXdRWU1CYUFGTGVtCnBIUjNuZVV2L0lHNVlqcHpqQ21lMnZiMk1Bb0dDQ3FHU000OUJBTUNBMGdBTUVVQ0lDaDVGTWlXV3hxVHYyc0wKQVdvQ2lxaWJ0OUNUMnpsNzRlSTllMEZPTzRKTkFpRUF5T0wwR3RxVnlTSHUzbUsvVDBxZFhYQ3dmdHdWQVE4cgo2ejJWaVZrMzg2dz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSURtdTh0UGVrRmhlNzRXWm5idXlwOFZ1VUIxTVYwcTN4QklOclVVbjBaRjVvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFNjZrMStQb1l5OHlPWTZkRFR5MHJYRTUvRlZJVU0rbkc0RXNJdnE4cG5naVVFZGR5N1gzeApvZ2E5d2NSZy8xeVZ4Q2FNbzBUVEZveXkxaVZMMWxGWDNBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- oidc-login
- get-token
- --oidc-issuer-url=https://login.ois.run
- --oidc-client-id=261774567918339420@holos_platform
- --oidc-extra-scope=openid
- --oidc-extra-scope=email
- --oidc-extra-scope=profile
- --oidc-extra-scope=groups
- --oidc-extra-scope=offline_access
- --oidc-extra-scope=urn:zitadel:iam:org:domain:primary:openinfrastructure.co
- --oidc-use-pkce
command: kubectl
env: null
interactiveMode: IfAvailable
provideClusterInfo: false

View File

@@ -1,33 +0,0 @@
#! /bin/bash
#
tmpdir="$(mktemp -d)"
finish() {
rm -rf "$tmpdir"
}
trap finish EXIT
set -euo pipefail
umask 077
kubectl -n "dev-${USER}" get secret "${USER}.holos-server-db.credentials.postgresql.acid.zalan.do" -o json > "${tmpdir}/creds.json"
if [[ -f ~/.pgpass ]]; then
(grep -v "^localhost:14126:holos:${USER}:" ~/.pgpass || true) > "${tmpdir}/pgpass"
fi
PGUSER="$(jq -r '.data | map_values(@base64d) | .username' ${tmpdir}/creds.json)"
PGPASSWORD="$(jq -r '.data | map_values(@base64d) | .password' ${tmpdir}/creds.json)"
echo "${PGHOST}:${PGPORT}:${PGDATABASE}:${PGUSER}:${PGPASSWORD}" >> "${tmpdir}/pgpass"
cp "${tmpdir}/pgpass" ~/.pgpass
echo "updated: ${HOME}/.pgpass" >&2
cat <<EOF >&2
## Connect from a localhost shell through the port forward to the cluster
export PGHOST=${PGHOST}
export PGPORT=${PGPORT}
export PGDATABASE=${PGDATABASE}
export PGUSER=${PGUSER}
psql -c '\conninfo'
EOF
psql --host=${PGHOST} --port=${PGPORT} ${PGDATABASE} -c '\conninfo'

View File

@@ -12,7 +12,7 @@ import (
"path/filepath"
"strings"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/load"
"github.com/holos-run/holos/api/core/v1alpha2"
@@ -47,6 +47,16 @@ type config struct {
type Builder struct {
cfg config
ctx *cue.Context
}
// BuildData represents the data necessary to produce a build plan. It is a
// convenience wrapper to store relevant fields to inform the user.
type BuildData struct {
Value cue.Value
ModuleRoot string
InstancePath holos.InstancePath
Dir string
}
type buildPlanWrapper struct {
@@ -92,7 +102,10 @@ func New(opts ...Option) *Builder {
for _, f := range opts {
f(&cfg)
}
b := &Builder{cfg: cfg}
b := &Builder{
cfg: cfg,
ctx: cuecontext.New(),
}
return b
}
@@ -111,97 +124,122 @@ func (b *Builder) Cluster() string {
return b.cfg.cluster
}
// Instances returns the cue build instances being built.
func (b *Builder) Instances(ctx context.Context, cfg *client.Config) ([]*build.Instance, error) {
log := logger.FromContext(ctx)
mod, err := b.findCueMod()
// Unify returns a cue.Value representing the kind of build holos is meant to
// execute. This function unifies a cue package entrypoint with
// platform.config.json and user data json files located recursively within the
// userdata directory at the cue module root.
func (b *Builder) Unify(ctx context.Context, cfg *client.Config) (bd BuildData, err error) {
cueModDir, err := b.findCueMod()
if err != nil {
return nil, errors.Wrap(err)
err = errors.Wrap(err)
return
}
dir := string(mod)
bd.ModuleRoot = string(cueModDir)
cueConfig := load.Config{Dir: dir}
// Get the platform model from the PlatformConfig
pc, err := client.LoadPlatformConfig(ctx, dir)
platformConfigData, err := os.ReadFile(filepath.Join(bd.ModuleRoot, client.PlatformConfigFile))
if err != nil {
return nil, errors.Wrap(err)
}
data, err := json.Marshal(pc)
if err != nil {
return nil, errors.Wrap(err)
return bd, errors.Wrap(fmt.Errorf("could not load platform model: %w", err))
}
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
cueConfig.Tags = append(cueConfig.Tags, "platform_config="+string(data))
if b.Cluster() != "" {
cueConfig.Tags = append(cueConfig.Tags, "cluster="+b.Cluster())
}
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cueConfig.Tags))
prefix := []string{"cue", "export", "--out", "yaml"}
for _, tag := range cueConfig.Tags {
prefix = append(prefix, "-t", fmt.Sprintf("'%s'", tag))
cueConfig := load.Config{
Dir: bd.ModuleRoot,
ModuleRoot: bd.ModuleRoot,
// TODO: Use instance.FillPath to fill the platform config.
// Refer to https://pkg.go.dev/cuelang.org/go/cue#Value.FillPath
Tags: []string{
"cluster=" + cfg.Holos().ClusterName(),
"platform_config=" + string(platformConfigData),
},
}
// Make args relative to the module directory
args := make([]string, len(b.cfg.args))
for idx, path := range b.cfg.args {
args := make([]string, 0, len(b.cfg.args)+2)
for _, path := range b.cfg.args {
target, err := filepath.Abs(path)
if err != nil {
return nil, errors.Wrap(fmt.Errorf("could not find absolute path: %w", err))
return bd, errors.Wrap(fmt.Errorf("could not find absolute path: %w", err))
}
relPath, err := filepath.Rel(dir, target)
relPath, err := filepath.Rel(bd.ModuleRoot, target)
if err != nil {
return nil, errors.Wrap(fmt.Errorf("invalid argument, must be relative to cue.mod: %w", err))
return bd, errors.Wrap(fmt.Errorf("invalid argument, must be relative to cue.mod: %w", err))
}
relPath = "./" + relPath
args[idx] = relPath
equiv := make([]string, len(prefix), 1+len(prefix))
copy(equiv, prefix)
equiv = append(equiv, relPath)
log.Debug(strings.Join(equiv, " "), "comment", "cue equivalent command")
// WATCH OUT: Assumes only one instance path is provided via args, which is
// true when I added this, but may be a poor assumption by the time you read
// this.
bd.InstancePath = holos.InstancePath(target)
bd.Dir = relPath
relPath = "./" + relPath
args = append(args, relPath)
}
return load.Instances(args, &cueConfig), nil
instances := load.Instances(args, &cueConfig)
values, err := b.ctx.BuildInstances(instances)
if err != nil {
err = errors.Wrap(err)
return
}
// Unify into a single Value
for _, v := range values {
bd.Value = bd.Value.Unify(v)
}
// Fill in #UserData
userData, err := loadUserData(b.ctx, bd.ModuleRoot)
if err != nil {
return
}
bd.Value = bd.Value.FillPath(cue.ParsePath("#UserData"), userData)
return
}
// loadUserData recursively unifies userdata/**/*.json files into cue.Value val.
func loadUserData(ctx *cue.Context, moduleRoot string) (val cue.Value, err error) {
err = filepath.Walk(filepath.Join(moduleRoot, "userdata"), func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && filepath.Ext(info.Name()) == ".json" {
userData, err := os.ReadFile(path)
if err != nil {
return errors.Wrap(err)
}
val = val.Unify(ctx.CompileBytes(userData, cue.Filename(path)))
}
return nil
})
return
}
// Run builds the cue entrypoint into zero or more Results. Exactly one CUE
// package entrypoint is expected in the args slice. The platform config is
// provided to the entrypoint through a json encoded string tag named
// platform_config. The resulting cue.Value is unified with all user data files
// at the path "#UserData".
func (b *Builder) Run(ctx context.Context, cfg *client.Config) (results []*render.Result, err error) {
log := logger.FromContext(ctx)
log.DebugContext(ctx, "cue: building instances")
instances, err := b.Instances(ctx, cfg)
bd, err := b.Unify(ctx, cfg)
if err != nil {
return nil, err
}
results = make([]*render.Result, 0, len(instances)*8)
// Each CUE instance provides a BuildPlan
for idx, instance := range instances {
log.DebugContext(ctx, "cue: building instance", "idx", idx, "dir", instance.Dir)
r, err := b.runInstance(ctx, instance)
if err != nil {
return nil, errors.Wrap(fmt.Errorf("could not run: %w", err))
}
results = append(results, r...)
}
return results, nil
return b.build(ctx, bd)
}
func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (results []*render.Result, err error) {
path := holos.InstancePath(instance.Dir)
log := logger.FromContext(ctx).With("dir", path)
func (b Builder) build(ctx context.Context, bd BuildData) (results []*render.Result, err error) {
log := logger.FromContext(ctx).With("dir", bd.InstancePath)
value := bd.Value
if err := instance.Err; err != nil {
return nil, errors.Wrap(fmt.Errorf("could not load: %w", err))
}
cueCtx := cuecontext.New()
value := cueCtx.BuildInstance(instance)
if err := value.Err(); err != nil {
return nil, errors.Wrap(fmt.Errorf("could not build %s: %w", instance.Dir, err))
return nil, errors.Wrap(fmt.Errorf("could not build %s: %w", bd.InstancePath, err))
}
log.DebugContext(ctx, "cue: validating instance")
if err := value.Validate(); err != nil {
return nil, errors.Wrap(fmt.Errorf("could not validate: %w", err))
@@ -210,14 +248,15 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
log.DebugContext(ctx, "cue: decoding holos build plan")
jsonBytes, err := value.MarshalJSON()
if err != nil {
return nil, errors.Wrap(fmt.Errorf("could not marshal cue instance %s: %w", instance.Dir, err))
return nil, errors.Wrap(fmt.Errorf("could not marshal cue instance %s: %w", bd.Dir, err))
}
decoder := json.NewDecoder(bytes.NewReader(jsonBytes))
// Discriminate the type of build plan.
tm := &v1alpha1.TypeMeta{}
err = decoder.Decode(tm)
if err != nil {
return nil, errors.Wrap(fmt.Errorf("invalid BuildPlan: %s: %w", instance.Dir, err))
return nil, errors.Wrap(fmt.Errorf("invalid BuildPlan: %s: %w", bd.Dir, err))
}
log.DebugContext(ctx, "cue: discriminated build kind: "+tm.Kind, "kind", tm.Kind, "apiVersion", tm.APIVersion)
@@ -234,10 +273,10 @@ func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (res
case "BuildPlan":
var bp v1alpha2.BuildPlan
if err = decoder.Decode(&bp); err != nil {
err = errors.Wrap(fmt.Errorf("could not decode BuildPlan %s: %w", instance.Dir, err))
err = errors.Wrap(fmt.Errorf("could not decode BuildPlan %s: %w", bd.Dir, err))
return
}
results, err = b.buildPlan(ctx, &bp, path)
results, err = b.buildPlan(ctx, &bp, bd.InstancePath)
if err != nil {
return results, err
}

View File

@@ -6,8 +6,6 @@ import (
"encoding/json"
"fmt"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/cuecontext"
"github.com/holos-run/holos"
core "github.com/holos-run/holos/api/core/v1alpha2"
meta "github.com/holos-run/holos/api/meta/v1alpha2"
@@ -20,37 +18,22 @@ import (
func (b *Builder) Platform(ctx context.Context, cfg *client.Config) (*core.Platform, error) {
log := logger.FromContext(ctx)
log.DebugContext(ctx, "cue: building platform instance")
instances, err := b.Instances(ctx, cfg)
bd, err := b.Unify(ctx, cfg)
if err != nil {
return nil, errors.Wrap(err)
}
if len(instances) != 1 {
return nil, errors.Wrap(errors.New(fmt.Sprintf("instances length %d must be exactly 1", len(instances))))
}
// We only process the first instance, assume the render platform subcommand enforces this.
instance := instances[0]
log.DebugContext(ctx, "cue: building instance", "dir", instance.Dir)
p, err := b.runPlatform(ctx, instance)
if err != nil {
return nil, errors.Wrap(fmt.Errorf("could not build platform: %w", err))
}
return p, nil
return b.runPlatform(ctx, bd)
}
func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*core.Platform, error) {
path := holos.InstancePath(instance.Dir)
func (b Builder) runPlatform(ctx context.Context, bd BuildData) (*core.Platform, error) {
path := holos.InstancePath(bd.Dir)
log := logger.FromContext(ctx).With("dir", path)
if err := instance.Err; err != nil {
value := bd.Value
if err := bd.Value.Err(); err != nil {
return nil, errors.Wrap(fmt.Errorf("could not load: %w", err))
}
cueCtx := cuecontext.New()
value := cueCtx.BuildInstance(instance)
if err := value.Err(); err != nil {
return nil, errors.Wrap(fmt.Errorf("could not build %s: %w", instance.Dir, err))
}
log.DebugContext(ctx, "cue: validating instance")
if err := value.Validate(); err != nil {
return nil, errors.Wrap(fmt.Errorf("could not validate: %w", err))
@@ -59,7 +42,7 @@ func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*co
log.DebugContext(ctx, "cue: decoding holos platform")
jsonBytes, err := value.MarshalJSON()
if err != nil {
return nil, errors.Wrap(fmt.Errorf("could not marshal cue instance %s: %w", instance.Dir, err))
return nil, errors.Wrap(fmt.Errorf("could not marshal cue instance %s: %w", bd.Dir, err))
}
decoder := json.NewDecoder(bytes.NewReader(jsonBytes))
@@ -67,7 +50,7 @@ func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*co
tm := &meta.TypeMeta{}
err = decoder.Decode(tm)
if err != nil {
return nil, errors.Wrap(fmt.Errorf("invalid platform: %s: %w", instance.Dir, err))
return nil, errors.Wrap(fmt.Errorf("invalid platform: %s: %w", bd.Dir, err))
}
log.DebugContext(ctx, "cue: discriminated build kind: "+tm.GetKind(), "kind", tm.GetKind(), "apiVersion", tm.GetAPIVersion())
@@ -80,7 +63,7 @@ func (b Builder) runPlatform(ctx context.Context, instance *build.Instance) (*co
switch tm.GetKind() {
case "Platform":
if err = decoder.Decode(&pf); err != nil {
err = errors.Wrap(fmt.Errorf("could not decode platform %s: %w", instance.Dir, err))
err = errors.Wrap(fmt.Errorf("could not decode platform %s: %w", bd.Dir, err))
return nil, err
}
return &pf, nil

View File

@@ -43,8 +43,8 @@ func makeBuildRunFunc(cfg *client.Config) command.RunFunc {
// New returns the build subcommand for the root command
func New(cfg *holos.Config) *cobra.Command {
cmd := command.New("build [directory...]")
cmd.Args = cobra.MinimumNArgs(1)
cmd := command.New("build [directory]")
cmd.Args = cobra.ExactArgs(1)
cmd.Short = "build kubernetes api objects from a directory"
cmd.Flags().AddGoFlagSet(cfg.ClusterFlagSet())

View File

@@ -12,6 +12,7 @@ type RunFunc func(c *cobra.Command, args []string) error
func New(name string) *cobra.Command {
cmd := &cobra.Command{
Use: name,
Short: name,
Version: version.Version,
Args: cobra.NoArgs,
CompletionOptions: cobra.CompletionOptions{

View File

@@ -1,6 +1,8 @@
package create
import (
"fmt"
"github.com/holos-run/holos/internal/cli/command"
"github.com/holos-run/holos/internal/cli/secret"
"github.com/holos-run/holos/internal/client"
@@ -41,12 +43,19 @@ func NewPlatform(cfg *client.Config) *cobra.Command {
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
client := client.New(cfg)
pf, err := client.CreatePlatform(ctx, pm)
resp, err := client.CreatePlatform(ctx, pm)
if err != nil {
return err
}
log := logger.FromContext(ctx)
log.InfoContext(ctx, "created platform", "name", pf.GetName(), "id", pf.GetId(), "org", pf.GetOwner().GetOrgId())
action := "created"
if resp.GetAlreadyExists() {
action = "already exists"
}
pf := resp.GetPlatform()
name := pf.GetName()
log.InfoContext(ctx, fmt.Sprintf("platform %s %s", name, action), "name", name, "id", pf.GetId(), "org", pf.GetOwner().GetOrgId(), "exists", resp.GetAlreadyExists())
return nil
}

View File

@@ -0,0 +1,54 @@
package destroy
import (
"fmt"
"github.com/holos-run/holos/internal/cli/command"
"github.com/holos-run/holos/internal/client"
"github.com/holos-run/holos/internal/errors"
"github.com/holos-run/holos/internal/holos"
"github.com/spf13/cobra"
)
// New returns the command for the cli
func New(cfg *holos.Config) *cobra.Command {
cmd := command.New("delete")
cmd.Aliases = []string{"destroy"}
cmd.Short = "delete resources"
cmd.Flags().SortFlags = false
cmd.RunE = func(c *cobra.Command, args []string) error {
return c.Usage()
}
// api client config
config := client.NewConfig(cfg)
// flags
cmd.PersistentFlags().SortFlags = false
// commands
cmd.AddCommand(NewPlatform(config))
return cmd
}
func NewPlatform(cfg *client.Config) *cobra.Command {
cmd := command.New("platform")
cmd.Args = cobra.MinimumNArgs(1)
cmd.Use = "platform [flags] PLATFORM_ID [PLATFORM_ID ...]"
cmd.Short = "Delete one or more platforms by ID"
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
rpc := client.New(cfg)
for _, platformID := range args {
msg, err := rpc.DeletePlatform(ctx, platformID)
if err != nil {
return errors.Wrap(err)
}
platform := msg.GetPlatform()
fmt.Fprintf(cmd.OutOrStdout(), "deleted platform %s (%s)\n", platform.GetName(), platform.GetId())
}
return nil
}
return cmd
}

View File

@@ -1,23 +1,79 @@
package get
import (
"errors"
"fmt"
"strings"
"text/tabwriter"
"time"
"github.com/holos-run/holos/internal/cli/command"
"github.com/holos-run/holos/internal/cli/secret"
"github.com/holos-run/holos/internal/client"
"github.com/holos-run/holos/internal/holos"
"github.com/spf13/cobra"
"k8s.io/kubectl/pkg/util/slice"
)
// New returns the get command for the cli.
func New(hc *holos.Config) *cobra.Command {
cmd := command.New("get")
cmd.Short = "get resources"
cmd.Aliases = []string{"list"}
cmd.Flags().SortFlags = false
cmd.RunE = func(c *cobra.Command, args []string) error {
return c.Usage()
}
// flags
cmd.PersistentFlags().SortFlags = false
// commands
cmd.AddCommand(secret.NewGetCmd(hc))
cmd.AddCommand(NewPlatform(hc))
return cmd
}
func NewPlatform(hc *holos.Config) *cobra.Command {
cmd := command.New("platform")
cmd.Aliases = []string{"platforms"}
cmd.Args = cobra.MinimumNArgs(0)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
clientContext := holos.NewClientContext(ctx)
rpc := client.New(client.NewConfig(hc))
msgs, err := rpc.Platforms(ctx, clientContext.OrgID)
if err != nil {
return err
}
now := time.Now()
rows := make([][]string, 0, len(msgs))
for _, msg := range msgs {
name := msg.GetName()
if len(args) > 0 && !slice.ContainsString(args, name, nil) {
continue
}
age := now.Sub(msg.GetDetail().GetCreatedAt().AsTime())
rows = append(rows, []string{
name,
msg.GetDisplayName(),
holos.RoundDuration(age),
msg.GetId(),
})
}
w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 0, 4, ' ', 0)
if len(rows) == 0 {
return errors.New("not found")
}
fmt.Fprintln(w, "NAME\tDESCRIPTION\tAGE\tID")
for _, row := range rows {
fmt.Fprintln(w, strings.Join(row, "\t"))
}
return w.Flush()
}
return cmd
}

View File

@@ -3,6 +3,8 @@
package pull
import (
"fmt"
"github.com/holos-run/holos/internal/cli/command"
"github.com/holos-run/holos/internal/client"
"github.com/holos-run/holos/internal/errors"
@@ -52,28 +54,25 @@ func NewPlatformConfig(cfg *client.Config) *cobra.Command {
rpc := client.New(cfg)
for _, name := range args {
// Get the platform metadata for the platform id.
pmd, err := client.LoadPlatform(ctx, name)
pmd, err := client.LoadPlatformMetadata(ctx, name)
if err != nil {
return errors.Wrap(err)
}
log := logger.FromContext(ctx).With("platform_id", pmd.GetId())
log := logger.FromContext(ctx).With("platform_name", pmd.GetName(), "platform_id", pmd.GetId())
// Get the platform model
model, err := rpc.PlatformModel(ctx, pmd.GetId())
if err != nil {
return errors.Wrap(err)
}
log.Info("pulled platform model")
log.DebugContext(ctx, "pulled platform "+pmd.GetName()+" model")
// Build the PlatformConfig
pc := &object.PlatformConfig{
PlatformId: pmd.GetId(),
PlatformModel: model,
}
pc := &object.PlatformConfig{PlatformModel: model}
// Save the PlatformConfig
path, err := client.SavePlatformConfig(ctx, name, pc)
if err != nil {
return errors.Wrap(err)
}
log.Info("saved platform config", "path", path)
log.DebugContext(ctx, fmt.Sprintf("wrote: %s for platform %s", path, pmd.GetName()), "path", path)
}
return nil
}

View File

@@ -54,7 +54,7 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
rpc := client.New(cfg)
for _, name := range args {
// Get the platform metadata for the platform id.
p, err := client.LoadPlatform(ctx, name)
p, err := client.LoadPlatformMetadata(ctx, name)
if err != nil {
return errors.Wrap(err)
}
@@ -67,7 +67,7 @@ func NewPlatformForm(cfg *client.Config) *cobra.Command {
if err := rpc.UpdateForm(ctx, p.GetId(), form); err != nil {
return errors.Wrap(err)
}
slog.Default().InfoContext(ctx, fmt.Sprintf("pushed: %s/ui/platform/%s", cfg.Client().Server(), p.GetId()))
slog.Default().InfoContext(ctx, fmt.Sprintf("browse to form url: %s/ui/platform/%s", cfg.Client().Server(), p.GetId()))
}
return nil
}
@@ -88,17 +88,23 @@ func NewPlatformModel(cfg *client.Config) *cobra.Command {
ctx = logger.NewContext(ctx, logger.FromContext(ctx).With("server", cfg.Client().Server()))
rpc := client.New(cfg)
for _, name := range args {
// Get the platform config for the platform id.
p, err := client.LoadPlatformConfig(ctx, name)
// Get the platform metadata for the platform id.
pl, err := client.LoadPlatformMetadata(ctx, name)
if err != nil {
return errors.Wrap(err)
}
// Get the platform model
pm, err := client.LoadPlatformConfig(ctx, name)
if err != nil {
return errors.Wrap(err)
}
// Make the rpc call to update the platform form.
if err := rpc.UpdatePlatformModel(ctx, p.PlatformId, p.PlatformModel); err != nil {
if err := rpc.UpdatePlatformModel(ctx, pl.GetId(), pm.GetPlatformModel()); err != nil {
return errors.Wrap(err)
}
slog.Default().InfoContext(ctx, fmt.Sprintf("pushed: %s/ui/platform/%s", cfg.Client().Server(), p.PlatformId))
slog.Default().InfoContext(ctx, fmt.Sprintf("pushed: %s/ui/platform/%s", cfg.Client().Server(), pl.GetId()))
}
return nil
}

View File

@@ -3,7 +3,6 @@ package render
import (
"context"
"flag"
"fmt"
"runtime"
"github.com/holos-run/holos/internal/builder"
@@ -37,26 +36,13 @@ func NewComponent(cfg *holos.Config) *cobra.Command {
cmd.PersistentFlags().AddGoFlagSet(config.ClientFlagSet())
cmd.PersistentFlags().AddGoFlagSet(config.TokenFlagSet())
var printInstances bool
flagSet := flag.NewFlagSet("", flag.ContinueOnError)
flagSet.BoolVar(&printInstances, "print-instances", false, "expand /... paths for xargs")
cmd.Flags().AddGoFlagSet(flagSet)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Root().Context()
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
if printInstances {
instances, err := build.Instances(ctx, config)
if err != nil {
return errors.Wrap(err)
}
for _, instance := range instances {
fmt.Fprintln(cmd.OutOrStdout(), instance.Dir)
}
return nil
}
results, err := build.Run(ctx, config)
if err != nil {
return errors.Wrap(err)

View File

@@ -17,6 +17,7 @@ import (
"github.com/holos-run/holos/internal/cli/command"
"github.com/holos-run/holos/internal/cli/controller"
"github.com/holos-run/holos/internal/cli/create"
"github.com/holos-run/holos/internal/cli/destroy"
"github.com/holos-run/holos/internal/cli/generate"
"github.com/holos-run/holos/internal/cli/get"
"github.com/holos-run/holos/internal/cli/kv"
@@ -72,6 +73,7 @@ func New(cfg *holos.Config) *cobra.Command {
rootCmd.AddCommand(render.New(cfg))
rootCmd.AddCommand(get.New(cfg))
rootCmd.AddCommand(create.New(cfg))
rootCmd.AddCommand(destroy.New(cfg))
rootCmd.AddCommand(preflight.New(cfg))
rootCmd.AddCommand(login.New(cfg))
rootCmd.AddCommand(logout.New(cfg))

View File

@@ -65,7 +65,7 @@ func (c *Client) Platforms(ctx context.Context, orgID string) ([]*platform.Platf
req := &platform.ListPlatformsRequest{
OrgId: orgID,
FieldMask: &fieldmaskpb.FieldMask{
Paths: []string{"id", "name", "displayName"},
Paths: []string{"id", "name", "displayName", "detail"},
},
}
resp, err := c.pltSvc.ListPlatforms(ctx, connect.NewRequest(req))
@@ -123,7 +123,7 @@ func (c *Client) PlatformModel(ctx context.Context, platformID string) (*structp
return pf.Msg.GetPlatform().GetSpec().GetModel(), nil
}
func (c *Client) CreatePlatform(ctx context.Context, pm PlatformMutation) (*platform.Platform, error) {
func (c *Client) CreatePlatform(ctx context.Context, pm PlatformMutation) (*platform.CreatePlatformResponse, error) {
log := logger.FromContext(ctx).With("platform", pm.Name)
start := time.Now()
req := &platform.CreatePlatformRequest{
@@ -139,5 +139,18 @@ func (c *Client) CreatePlatform(ctx context.Context, pm PlatformMutation) (*plat
}
log = log.With("platform_id", pf.Msg.GetPlatform().GetId())
log.DebugContext(ctx, "create platform", "duration", time.Since(start))
return pf.Msg.GetPlatform(), nil
return pf.Msg, nil
}
func (c *Client) DeletePlatform(ctx context.Context, platformID string) (*platform.DeletePlatformResponse, error) {
log := logger.FromContext(ctx).With("platform_id", platformID)
start := time.Now()
req := &platform.DeletePlatformRequest{PlatformId: platformID}
resp, err := c.pltSvc.DeletePlatform(ctx, connect.NewRequest(req))
if err != nil {
return nil, errors.Wrap(err)
}
name := resp.Msg.GetPlatform().GetName()
log.DebugContext(ctx, "deleted platform "+name, "name", name, "duration", time.Since(start))
return resp.Msg, nil
}

View File

@@ -12,18 +12,19 @@ import (
"google.golang.org/protobuf/encoding/protojson"
)
// PlatformMetadataFile is the platform metadata json file name located in the root
// of a platform directory.
// PlatformMetadataFile is the platform metadata json file name located in the
// root of a platform directory. This file is the authoritative source of truth
// for the PlatformID used in rpc calls to the PlatformService.
const PlatformMetadataFile = "platform.metadata.json"
// PlatformConfigFile is the marshaled json representation of the PlatformConfig
// DTO used to cache the data holos passes from the PlatformService to CUE when
// rendering platform components.
// PlatformConfigFile represents the marshaled json representation of the
// PlatformConfig DTO used to persist the inputs to the CUE platform code.
const PlatformConfigFile = "platform.config.json"
// LoadPlatform loads the platform.metadata.json file from a named path. Useful
// to obtain a platform id for PlatformService rpc methods.
func LoadPlatform(ctx context.Context, name string) (*platform.Platform, error) {
// LoadPlatformMetadata loads the platform.metadata.json file from a named path.
// Used as the authoritative source of truth to obtain a platform id for
// PlatformService rpc methods.
func LoadPlatformMetadata(ctx context.Context, name string) (*platform.Platform, error) {
data, err := os.ReadFile(filepath.Join(name, PlatformMetadataFile))
if err != nil {
return nil, fmt.Errorf("could not load platform metadata: %w", err)
@@ -32,6 +33,8 @@ func LoadPlatform(ctx context.Context, name string) (*platform.Platform, error)
if err := protojson.Unmarshal(data, p); err != nil {
return nil, fmt.Errorf("could not load platform metadata: %w", err)
}
log := logger.FromContext(ctx)
log.DebugContext(ctx, "loaded: "+p.GetName(), "path", PlatformMetadataFile, "name", p.GetName(), "display_name", p.GetDisplayName(), "id", p.GetId())
return p, nil
}
@@ -41,13 +44,13 @@ func LoadPlatform(ctx context.Context, name string) (*platform.Platform, error)
func LoadPlatformConfig(ctx context.Context, name string) (*object.PlatformConfig, error) {
data, err := os.ReadFile(filepath.Join(name, PlatformConfigFile))
if err != nil {
return nil, fmt.Errorf("could not load platform config: %w", err)
return nil, fmt.Errorf("could not load platform model: %w", err)
}
pc := &object.PlatformConfig{}
if err := protojson.Unmarshal(data, pc); err != nil {
return nil, fmt.Errorf("could not load platform config: %w", err)
p := &object.PlatformConfig{}
if err := protojson.Unmarshal(data, p); err != nil {
return nil, fmt.Errorf("could not load platform model: %w", err)
}
return pc, nil
return p, nil
}
// SavePlatformConfig writes pc to the platform root directory path identified by name.

View File

@@ -0,0 +1,49 @@
package console
import (
"context"
"fmt"
"io"
"log/slog"
"sync"
)
func NewHandler(out io.Writer, opts *Options) slog.Handler {
h := &ConsoleHandler{out: out, mu: &sync.Mutex{}}
if opts != nil {
h.opts = *opts
}
if h.opts.Level == nil {
h.opts.Level = slog.LevelInfo
}
return h
}
type Options struct {
Level slog.Leveler
}
type ConsoleHandler struct {
opts Options
mu *sync.Mutex
out io.Writer
}
func (h *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
return level >= h.opts.Level.Level()
}
func (h *ConsoleHandler) Handle(ctx context.Context, r slog.Record) error {
h.mu.Lock()
defer h.mu.Unlock()
_, err := fmt.Fprintln(h.out, r.Message)
return err
}
func (h *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
return h
}
func (h *ConsoleHandler) WithGroup(name string) slog.Handler {
return h
}

View File

@@ -12,5 +12,5 @@
</style><link rel="stylesheet" href="styles-IHLR3ZBD.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles-IHLR3ZBD.css"></noscript><link rel="modulepreload" href="chunk-EYHLAWIE.js"></head>
<body class="mat-typography">
<app-root></app-root>
<script src="polyfills-A7MJM4D4.js" type="module"></script><script src="main-E473TGC2.js" type="module"></script></body>
<script src="polyfills-A7MJM4D4.js" type="module"></script><script src="main-6TNXO3ZY.js" type="module"></script></body>
</html>

View File

@@ -332,8 +332,8 @@ export class ResourceOwner extends Message<ResourceOwner> {
*/
export class Form extends Message<Form> {
/**
* fields represents FormlyFieldConfig[] encoded as an array of JSON objects
* organized by section.
* field_configs represents FormlyFieldConfig[] encoded as an array of JSON
* objects organized by section.
*
* @generated from field: repeated google.protobuf.Struct field_configs = 1;
*/
@@ -369,22 +369,20 @@ export class Form extends Message<Form> {
/**
* PlatformConfig represents the data passed from the holos cli to CUE when
* rendering configuration.
* rendering configuration. At present it contains only the platform model from
* the PlatformService, but it is expected to carry additional fields from
* additional data sources. For this reason, there is a distinction in domain
* language between the "Platform Config" and the "Platform Model" The config
* is a data transfer object that carries at least the model. The model
* represents the form values from the PlatformService.
*
* @generated from message holos.object.v1alpha1.PlatformConfig
*/
export class PlatformConfig extends Message<PlatformConfig> {
/**
* Platform UUID.
* platform_model represents the form values from the PlatformService.
*
* @generated from field: string platform_id = 1;
*/
platformId = "";
/**
* Platform Model.
*
* @generated from field: google.protobuf.Struct platform_model = 2;
* @generated from field: google.protobuf.Struct platform_model = 1;
*/
platformModel?: Struct;
@@ -396,8 +394,7 @@ export class PlatformConfig extends Message<PlatformConfig> {
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.object.v1alpha1.PlatformConfig";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "platform_model", kind: "message", T: Struct },
{ no: 1, name: "platform_model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PlatformConfig {

View File

@@ -3,7 +3,7 @@
/* eslint-disable */
// @ts-nocheck
import { CreatePlatformRequest, CreatePlatformResponse, GetPlatformRequest, GetPlatformResponse, ListPlatformsRequest, ListPlatformsResponse, UpdatePlatformRequest, UpdatePlatformResponse } from "./platform_service_pb.js";
import { CreatePlatformRequest, CreatePlatformResponse, DeletePlatformRequest, DeletePlatformResponse, GetPlatformRequest, GetPlatformResponse, ListPlatformsRequest, ListPlatformsResponse, UpdatePlatformRequest, UpdatePlatformResponse } from "./platform_service_pb.js";
import { MethodKind } from "@bufbuild/protobuf";
/**
@@ -48,6 +48,15 @@ export const PlatformService = {
O: ListPlatformsResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.DeletePlatform
*/
deletePlatform: {
name: "DeletePlatform",
I: DeletePlatformRequest,
O: DeletePlatformResponse,
kind: MethodKind.Unary,
},
}
} as const;

View File

@@ -60,6 +60,11 @@ export class CreatePlatformResponse extends Message<CreatePlatformResponse> {
*/
platform?: Platform;
/**
* @generated from field: bool already_exists = 2;
*/
alreadyExists = false;
constructor(data?: PartialMessage<CreatePlatformResponse>) {
super();
proto3.util.initPartial(data, this);
@@ -69,6 +74,7 @@ export class CreatePlatformResponse extends Message<CreatePlatformResponse> {
static readonly typeName = "holos.platform.v1alpha1.CreatePlatformResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform", kind: "message", T: Platform },
{ no: 2, name: "already_exists", kind: "scalar", T: 8 /* ScalarType.BOOL */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreatePlatformResponse {
@@ -412,3 +418,77 @@ export class PlatformMutation extends Message<PlatformMutation> {
}
}
/**
* @generated from message holos.platform.v1alpha1.DeletePlatformRequest
*/
export class DeletePlatformRequest extends Message<DeletePlatformRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
constructor(data?: PartialMessage<DeletePlatformRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.DeletePlatformRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): DeletePlatformRequest {
return new DeletePlatformRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): DeletePlatformRequest {
return new DeletePlatformRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): DeletePlatformRequest {
return new DeletePlatformRequest().fromJsonString(jsonString, options);
}
static equals(a: DeletePlatformRequest | PlainMessage<DeletePlatformRequest> | undefined, b: DeletePlatformRequest | PlainMessage<DeletePlatformRequest> | undefined): boolean {
return proto3.util.equals(DeletePlatformRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.DeletePlatformResponse
*/
export class DeletePlatformResponse extends Message<DeletePlatformResponse> {
/**
* @generated from field: holos.platform.v1alpha1.Platform platform = 1;
*/
platform?: Platform;
constructor(data?: PartialMessage<DeletePlatformResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.DeletePlatformResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform", kind: "message", T: Platform },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): DeletePlatformResponse {
return new DeletePlatformResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): DeletePlatformResponse {
return new DeletePlatformResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): DeletePlatformResponse {
return new DeletePlatformResponse().fromJsonString(jsonString, options);
}
static equals(a: DeletePlatformResponse | PlainMessage<DeletePlatformResponse> | undefined, b: DeletePlatformResponse | PlainMessage<DeletePlatformResponse> | undefined): boolean {
return proto3.util.equals(DeletePlatformResponse, a, b);
}
}

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