mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-01-11 21:23:12 +01:00
Merge branch 'main' into renovate/docker-digest
Signed-off-by: Francesco Canovai <francesco.canovai@enterprisedb.com>
This commit is contained in:
commit
c3390ebf27
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@ -32,11 +32,6 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
# TODO: remove this when we daggerize the e2e
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23.x'
|
||||
- name: Install Task
|
||||
uses: arduino/setup-task@v2
|
||||
- name: Install Dagger
|
||||
|
||||
122
Taskfile.yml
122
Taskfile.yml
@ -1,7 +1,14 @@
|
||||
version: 3
|
||||
|
||||
# Environment variables that are shared across tasks.
|
||||
env:
|
||||
# We have multiple parallel tasks that run for a long time. Prefix their output with the task name so we can understand
|
||||
# what task is writing.
|
||||
output: prefixed
|
||||
|
||||
# Variables that are shared across tasks.
|
||||
vars:
|
||||
# renovate: datasource=docker depName=kindest/node versioning=semver
|
||||
E2E_KUBERNETES_VERSION: v1.32.0
|
||||
E2E_CLUSTER_NAME: barman-cloud-plugin-e2e-{{.E2E_KUBERNETES_VERSION}}
|
||||
REGISTRY_NETWORK: barman-cloud-plugin
|
||||
REGISTRY_NAME: registry.barman-cloud-plugin
|
||||
REGISTRY_PORT: 5000
|
||||
@ -89,8 +96,8 @@ tasks:
|
||||
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem \
|
||||
-subj "/O=CloudNativePG/OU=Barman Cloud Plugin Testing" &&
|
||||
openssl genrsa -out server-key.pem 4096 &&
|
||||
openssl req -subj "/CN=${REGISTRY_NAME}" -sha256 -new -key server-key.pem -out server.csr &&
|
||||
echo subjectAltName = DNS:${REGISTRY_NAME},IP:127.0.0.1 >> extfile.cnf &&
|
||||
openssl req -subj "/CN={{ .REGISTRY_NAME }}" -sha256 -new -key server-key.pem -out server.csr &&
|
||||
echo subjectAltName = DNS:{{ .REGISTRY_NAME }},IP:127.0.0.1 >> extfile.cnf &&
|
||||
echo extendedKeyUsage = serverAuth >> extfile.cnf &&
|
||||
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
|
||||
-CAcreateserial -out server-cert.pem -extfile extfile.cnf &&
|
||||
@ -106,9 +113,9 @@ tasks:
|
||||
desc: Create a docker network for image building used by the dagger engine and the registry
|
||||
run: once
|
||||
cmds:
|
||||
- docker network create ${REGISTRY_NETWORK}
|
||||
- docker network create {{ .REGISTRY_NETWORK}}
|
||||
status:
|
||||
- docker network inspect ${REGISTRY_NETWORK}
|
||||
- docker network inspect {{ .REGISTRY_NETWORK }}
|
||||
|
||||
start-registry:
|
||||
desc: Start a container registry
|
||||
@ -121,14 +128,14 @@ tasks:
|
||||
REGISTRY_VERSION: 2
|
||||
cmds:
|
||||
- >
|
||||
docker run -d --name ${REGISTRY_NAME}
|
||||
-p ${REGISTRY_PORT}:5000
|
||||
--network ${REGISTRY_NETWORK}
|
||||
docker run -d --name {{ .REGISTRY_NAME }}
|
||||
-p {{ .REGISTRY_PORT }}:5000
|
||||
--network {{ .REGISTRY_NETWORK }}
|
||||
-v $(pwd)/certs:/certs
|
||||
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server-cert.pem -e REGISTRY_HTTP_TLS_KEY=/certs/server-key.pem
|
||||
registry:${REGISTRY_VERSION}
|
||||
status:
|
||||
- \[ "$(docker inspect -f {{`'{{.State.Running}}'`}} "${REGISTRY_NAME}" 2> /dev/null )" == 'true' \]
|
||||
- \[ "$(docker inspect -f {{`'{{.State.Running}}'`}} "{{ .REGISTRY_NAME }}" 2> /dev/null )" == 'true' \]
|
||||
|
||||
|
||||
# Start a dagger engine that mounts the CA certificate for the local registry.
|
||||
@ -144,12 +151,12 @@ tasks:
|
||||
DAGGER_ENGINE_IMAGE: registry.dagger.io/engine:v{{ .DAGGER_VERSION }}
|
||||
cmds:
|
||||
- >
|
||||
docker run -d -v /var/lib/dagger --name "${DAGGER_ENGINE_CONTAINER_NAME}"
|
||||
--network=${REGISTRY_NETWORK}
|
||||
docker run -d -v /var/lib/dagger --name "{{ .DAGGER_ENGINE_CONTAINER_NAME }}"
|
||||
--network={{ .REGISTRY_NETWORK }}
|
||||
-v $(pwd)/certs/ca.pem:/usr/local/share/ca-certificates/ca.crt
|
||||
--privileged {{ .DAGGER_ENGINE_IMAGE }}
|
||||
status:
|
||||
- \[ "$(docker inspect -f {{`'{{.State.Running}}'`}} "${DAGGER_ENGINE_CONTAINER_NAME}" 2> /dev/null )" == 'true' \]
|
||||
- \[ "$(docker inspect -f {{`'{{.State.Running}}'`}} "{{ .DAGGER_ENGINE_CONTAINER_NAME }}" 2> /dev/null )" == 'true' \]
|
||||
|
||||
# We build an image and push it to a local registry.
|
||||
# The name is always `plugin-barman-cloud:testing`.
|
||||
@ -164,9 +171,9 @@ tasks:
|
||||
_EXPERIMENTAL_DAGGER_RUNNER_HOST: docker-container://{{ .DAGGER_ENGINE_CONTAINER_NAME }}
|
||||
cmds:
|
||||
- >
|
||||
GITHUB_REF= dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
||||
GITHUB_REF= dagger -s call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
||||
build --dir . --file containers/Dockerfile.plugin --platform linux/amd64
|
||||
publish --ref ${REGISTRY_NAME}:${REGISTRY_PORT}/plugin-barman-cloud --tags testing
|
||||
publish --ref {{ .REGISTRY_NAME }}:{{ .REGISTRY_PORT }}/plugin-barman-cloud --tags testing
|
||||
|
||||
# We build an image and push it to a local registry.
|
||||
# The name is always `sidecar-barman-cloud:testing`.
|
||||
@ -181,9 +188,9 @@ tasks:
|
||||
_EXPERIMENTAL_DAGGER_RUNNER_HOST: docker-container://{{ .DAGGER_ENGINE_CONTAINER_NAME }}
|
||||
cmds:
|
||||
- >
|
||||
GITHUB_REF= dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
||||
GITHUB_REF= dagger -s call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
||||
build --dir . --file containers/Dockerfile.sidecar --platform linux/amd64
|
||||
publish --ref ${REGISTRY_NAME}:${REGISTRY_PORT}/sidecar-barman-cloud --tags testing
|
||||
publish --ref {{ .REGISTRY_NAME }}:{{ .REGISTRY_PORT }}/sidecar-barman-cloud --tags testing
|
||||
|
||||
build-images:
|
||||
desc: Build the container images for the plugin
|
||||
@ -191,6 +198,39 @@ tasks:
|
||||
- build-plugin-image
|
||||
- build-sidecar-image
|
||||
|
||||
# Install kind if not at the expected version.
|
||||
install-kind:
|
||||
desc: Install kind
|
||||
run: once
|
||||
vars:
|
||||
# renovate: datasource=git-refs depName=kind lookupName=https://github.com/kubernetes-sigs/kind versioning=semver
|
||||
KIND_VERSION: v0.26.0
|
||||
cmds:
|
||||
- go install sigs.k8s.io/kind@{{.KIND_VERSION}}
|
||||
- kind version | grep -q {{.KIND_VERSION}}
|
||||
status:
|
||||
- kind version | grep -q {{.KIND_VERSION}}
|
||||
|
||||
start-kind-cluster:
|
||||
desc: Start a kind cluster
|
||||
deps:
|
||||
- install-kind
|
||||
- start-build-network
|
||||
run: once
|
||||
cmds:
|
||||
- >
|
||||
kind create cluster --name {{ .E2E_CLUSTER_NAME }}
|
||||
--image kindest/node:{{ .E2E_KUBERNETES_VERSION }}
|
||||
--config hack/kind-config.yaml
|
||||
--wait 5m
|
||||
- >
|
||||
for node in $(kind get nodes --name {{ .E2E_CLUSTER_NAME }} ); do
|
||||
docker network connect {{ .REGISTRY_NETWORK }} $node;
|
||||
docker exec $node sh -c "update-ca-certificates";
|
||||
done
|
||||
status:
|
||||
- kind get clusters | grep -q {{ .E2E_CLUSTER_NAME }}
|
||||
|
||||
# TODO: see if it is possible to daggerize this. It will have to manage docker to make kind work.
|
||||
# TODO: add a task to clean up the kind cluster for new test runs.
|
||||
# Run the e2e tests. This task will start a kind cluster, deploy the plugin, and run the tests.
|
||||
@ -199,22 +239,42 @@ tasks:
|
||||
# * The registry to be in the same network of the dagger-engine.
|
||||
# * The dagger-engine to mount the CA.
|
||||
# * The kind cluster to mount the CA.
|
||||
e2e:
|
||||
desc: Run e2e tests
|
||||
e2e-external-kind:
|
||||
desc: Run e2e tests in a local kind cluster
|
||||
deps:
|
||||
- build-images
|
||||
- start-kind-cluster
|
||||
vars:
|
||||
# renovate: datasource=docker depName=golang versioning=semver
|
||||
GOLANG_IMAGE_VERSION: 1.23.4
|
||||
KUBECONFIG_PATH:
|
||||
sh: mktemp -t kubeconfig-XXXXX
|
||||
env:
|
||||
_EXPERIMENTAL_DAGGER_RUNNER_HOST: docker-container://{{ .DAGGER_ENGINE_CONTAINER_NAME }}
|
||||
cmds:
|
||||
- kind get kubeconfig --internal --name {{ .E2E_CLUSTER_NAME }} > {{ .KUBECONFIG_PATH }}
|
||||
- >
|
||||
GITHUB_REF= dagger call -m dagger/e2e/ run
|
||||
--source .
|
||||
--kubeconfig {{.KUBECONFIG_PATH}}
|
||||
--go-version {{ .GOLANG_IMAGE_VERSION }}
|
||||
|
||||
e2e-ephemeral:
|
||||
desc: Run e2e tests in an ephemeral k3s cluster
|
||||
deps:
|
||||
- build-images
|
||||
vars:
|
||||
# renovate: datasource=docker depName=golang versioning=semver
|
||||
GOLANG_IMAGE_VERSION: 1.23.4
|
||||
env:
|
||||
_EXPERIMENTAL_DAGGER_RUNNER_HOST: docker-container://{{ .DAGGER_ENGINE_CONTAINER_NAME }}
|
||||
cmds:
|
||||
- >
|
||||
go run github.com/onsi/ginkgo/v2/ginkgo
|
||||
--procs=8
|
||||
--randomize-all
|
||||
--randomize-suites
|
||||
--fail-on-pending
|
||||
--fail-on-empty
|
||||
--keep-going
|
||||
--timeout=30m
|
||||
--github-output
|
||||
./test/e2e
|
||||
GITHUB_REF= dagger call -m dagger/e2e/ run-ephemeral
|
||||
--source .
|
||||
--ca certs/ca.pem
|
||||
--registry {{.REGISTRY_NAME}}:{{.REGISTRY_PORT}}
|
||||
--go-version {{ .GOLANG_IMAGE_VERSION }}
|
||||
|
||||
ci:
|
||||
desc: Run the CI pipeline
|
||||
@ -224,7 +284,7 @@ tasks:
|
||||
- uncommitted
|
||||
- lint
|
||||
- go-test
|
||||
- e2e
|
||||
- e2e-ephemeral
|
||||
|
||||
publish:
|
||||
desc: Build and publish a container image for the plugin
|
||||
@ -284,7 +344,7 @@ tasks:
|
||||
- controller-gen
|
||||
desc: Generate the manifest for the main branch
|
||||
vars:
|
||||
GITHUB_REPOSITORY: '{{ default "cloudnative-pg/plugin-barman-cloud" .GITHUB_REPOSITORY }}'
|
||||
GITHUB_REPOSITORY: cloudnative-pg/plugin-barman-cloud
|
||||
GITHUB_REF: main
|
||||
GITHUB_REF_NAME: main
|
||||
cmds:
|
||||
|
||||
4
dagger/e2e/.gitattributes
vendored
Normal file
4
dagger/e2e/.gitattributes
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/dagger.gen.go linguist-generated
|
||||
/internal/dagger/** linguist-generated
|
||||
/internal/querybuilder/** linguist-generated
|
||||
/internal/telemetry/** linguist-generated
|
||||
4
dagger/e2e/.gitignore
vendored
Normal file
4
dagger/e2e/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/dagger.gen.go
|
||||
/internal/dagger
|
||||
/internal/querybuilder
|
||||
/internal/telemetry
|
||||
18
dagger/e2e/dagger.json
Normal file
18
dagger/e2e/dagger.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "e2e",
|
||||
"engineVersion": "v0.15.1",
|
||||
"sdk": "go",
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "go",
|
||||
"source": "github.com/sagikazarmark/daggerverse/go@go/v0.9.0",
|
||||
"pin": "d9ba06776c4c1ccf6f329bd862b9b439c4582ab6"
|
||||
},
|
||||
{
|
||||
"name": "k3s",
|
||||
"source": "github.com/marcosnils/daggerverse/k3s@k3s/v0.1.7",
|
||||
"pin": "833ec36632b2457862f6e3bf1f7107ad65e3e515"
|
||||
}
|
||||
],
|
||||
"source": "."
|
||||
}
|
||||
51
dagger/e2e/go.mod
Normal file
51
dagger/e2e/go.mod
Normal file
@ -0,0 +1,51 @@
|
||||
module dagger/e-2-e
|
||||
|
||||
go 1.23.2
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.17.57
|
||||
github.com/Khan/genqlient v0.7.0
|
||||
github.com/vektah/gqlparser/v2 v2.5.19
|
||||
go.opentelemetry.io/otel v1.27.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0
|
||||
go.opentelemetry.io/otel/log v0.3.0
|
||||
go.opentelemetry.io/otel/metric v1.27.0
|
||||
go.opentelemetry.io/otel/sdk v1.27.0
|
||||
go.opentelemetry.io/otel/sdk/log v0.3.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.27.0
|
||||
go.opentelemetry.io/otel/trace v1.27.0
|
||||
go.opentelemetry.io/proto/otlp v1.3.1
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||
golang.org/x/sync v0.10.0
|
||||
google.golang.org/grpc v1.68.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
|
||||
github.com/sosodev/duration v1.3.1 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/protobuf v1.35.2 // indirect
|
||||
)
|
||||
|
||||
replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88
|
||||
|
||||
replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0
|
||||
|
||||
replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0
|
||||
|
||||
replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0
|
||||
85
dagger/e2e/go.sum
Normal file
85
dagger/e2e/go.sum
Normal file
@ -0,0 +1,85 @@
|
||||
github.com/99designs/gqlgen v0.17.57 h1:Ak4p60BRq6QibxY0lEc0JnQhDurfhxA67sp02lMjmPc=
|
||||
github.com/99designs/gqlgen v0.17.57/go.mod h1:Jx61hzOSTcR4VJy/HFIgXiQ5rJ0Ypw8DxWLjbYDAUw0=
|
||||
github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w=
|
||||
github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4=
|
||||
github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg=
|
||||
github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U=
|
||||
go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
|
||||
go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY=
|
||||
go.opentelemetry.io/otel/log v0.3.0 h1:kJRFkpUFYtny37NQzL386WbznUByZx186DpEMKhEGZs=
|
||||
go.opentelemetry.io/otel/log v0.3.0/go.mod h1:ziCwqZr9soYDwGNbIL+6kAvQC+ANvjgG367HVcyR/ys=
|
||||
go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik=
|
||||
go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak=
|
||||
go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI=
|
||||
go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A=
|
||||
go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U=
|
||||
go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw=
|
||||
go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
|
||||
go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
|
||||
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
|
||||
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
98
dagger/e2e/main.go
Normal file
98
dagger/e2e/main.go
Normal file
@ -0,0 +1,98 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"dagger/e-2-e/internal/dagger"
|
||||
)
|
||||
|
||||
type E2E struct{}
|
||||
|
||||
// Run runs the E2E tests on a Kubernetes cluster. It returns the output of the tests.
|
||||
// We expect a kubeconfig file that allows access to the cluster, and optionally
|
||||
// a service to bind to, if the cluster is not directly exposed to the dagger container running the tests.
|
||||
func (m *E2E) Run(
|
||||
ctx context.Context,
|
||||
// source is the directory containing the source code for the project
|
||||
source *dagger.Directory,
|
||||
// kubeconfig is the kubeconfig file to use for the tests
|
||||
kubeconfig *dagger.File,
|
||||
// svc is the Kubernetes service to bind to. It will be known as "kubernetes" in the container.
|
||||
// +optional
|
||||
svc *dagger.Service,
|
||||
// version of the golang image to use
|
||||
// +optional
|
||||
// +default="latest"
|
||||
goVersion string,
|
||||
) (string, error) {
|
||||
goDag := dag.Go(dagger.GoOpts{Version: goVersion}).WithCgoDisabled().WithSource(source)
|
||||
if svc != nil {
|
||||
goDag = goDag.WithServiceBinding("kubernetes", svc)
|
||||
}
|
||||
return goDag.Container().
|
||||
WithMountedFile("/kubeconfig", kubeconfig).
|
||||
WithEnvVariable("KUBECONFIG", "/kubeconfig").
|
||||
WithExec([]string{"go", "run", "github.com/onsi/ginkgo/v2/ginkgo",
|
||||
"--procs=8",
|
||||
"--randomize-all",
|
||||
"--randomize-suites",
|
||||
"--fail-on-pending",
|
||||
"--fail-on-empty",
|
||||
"--keep-going",
|
||||
"--timeout=30m",
|
||||
"--github-output",
|
||||
"./test/e2e"}).Stdout(ctx)
|
||||
}
|
||||
|
||||
// RunEphemeral creates a k3s cluster in dagger and then runs the E2E tests on it.
|
||||
// If a private registry is used, its url and the ca certificate for the registry should be provided.
|
||||
func (m *E2E) RunEphemeral(
|
||||
ctx context.Context,
|
||||
// source is the directory containing the source code for the project
|
||||
source *dagger.Directory,
|
||||
// registry is a private registry
|
||||
// +optional
|
||||
// +default="registry.barman-cloud-plugin:5000"
|
||||
registry string,
|
||||
// ca is the certificate authority for the registry
|
||||
// +optional
|
||||
ca *dagger.File,
|
||||
// name is the name of the ephemeral container
|
||||
// +optional
|
||||
// +default="e2e"
|
||||
name string,
|
||||
// version of the golang image to use
|
||||
// +optional
|
||||
// +default="latest"
|
||||
goVersion string,
|
||||
) (string, error) {
|
||||
k3s := dag.K3S(name)
|
||||
ctr := k3s.Container()
|
||||
if ca != nil {
|
||||
ctr = ctr.WithMountedFile("/usr/local/share/ca-certificates/ca.crt", ca)
|
||||
}
|
||||
if registry != "" {
|
||||
ctr = ctr.WithNewFile("/registries.yaml", fmt.Sprintf(`
|
||||
configs:
|
||||
"%s":
|
||||
tls:
|
||||
ca_file: "/usr/local/share/ca-certificates/ca.crt"
|
||||
`, registry)).
|
||||
WithExec([]string{"sh", "-c", "cat /registries.yaml > /etc/rancher/k3s/registries.yaml"})
|
||||
}
|
||||
|
||||
ctr, err := ctr.Sync(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
kServer := k3s.WithContainer(ctr).Server()
|
||||
|
||||
kServer, err = kServer.Start(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer kServer.Stop(ctx)
|
||||
|
||||
return m.Run(ctx, source, k3s.Config(), kServer, goVersion)
|
||||
}
|
||||
@ -6,6 +6,6 @@ apiVersion: kind.x-k8s.io/v1alpha4
|
||||
nodes:
|
||||
- role: control-plane
|
||||
extraMounts:
|
||||
- hostPath: ../../certs/ca.pem
|
||||
- hostPath: certs/ca.pem
|
||||
containerPath: /usr/local/share/ca-certificates/ca.crt
|
||||
readOnly: true
|
||||
@ -24,10 +24,10 @@ import (
|
||||
|
||||
apimachineryTypes "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
kustomizeTypes "sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||
|
||||
internalClient "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/client"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/deployment"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/e2etestenv"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/kustomize"
|
||||
@ -41,10 +41,12 @@ import (
|
||||
|
||||
// We don't want multiple ginkgo nodes to run the setup concurrently, we use a single cluster for all tests.
|
||||
var _ = SynchronizedBeforeSuite(func(ctx SpecContext) []byte {
|
||||
var cl client.Client
|
||||
var err error
|
||||
if cl, err = e2etestenv.Setup(ctx,
|
||||
e2etestenv.WithKindAdditionalNetworks([]string{"barman-cloud-plugin"})); err != nil {
|
||||
cl, _, err := internalClient.NewClient()
|
||||
if err != nil {
|
||||
Fail(fmt.Sprintf("failed to create Kubernetes client: %v", err))
|
||||
}
|
||||
|
||||
if err = e2etestenv.Setup(ctx, cl); err != nil {
|
||||
Fail(fmt.Sprintf("failed to setup environment: %v", err))
|
||||
}
|
||||
|
||||
|
||||
@ -19,26 +19,16 @@ package e2etestenv
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/kind/pkg/cluster"
|
||||
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/certmanager"
|
||||
internalClient "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/client"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/cloudnativepg"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/kind"
|
||||
)
|
||||
|
||||
// SetupOptions contains the options for setting up the test environment.
|
||||
type SetupOptions struct {
|
||||
K8sVersion string
|
||||
|
||||
KindVersion string
|
||||
KindClusterNamePrefix string
|
||||
KindAdditionalNetworks []string
|
||||
|
||||
CNPGKustomizationURL string
|
||||
CNPGKustomizationRef string
|
||||
CNPGKustomizationTimeout string
|
||||
@ -53,27 +43,6 @@ type SetupOptions struct {
|
||||
// SetupOption is a function that sets up an option for the test environment setup.
|
||||
type SetupOption func(*SetupOptions)
|
||||
|
||||
// WithK8sVersion sets the Kubernetes version for the test environment.
|
||||
func WithK8sVersion(version string) SetupOption {
|
||||
return func(opts *SetupOptions) {
|
||||
opts.K8sVersion = version
|
||||
}
|
||||
}
|
||||
|
||||
// WithKindVersion sets the Kind version for the test environment.
|
||||
func WithKindVersion(version string) SetupOption {
|
||||
return func(opts *SetupOptions) {
|
||||
opts.KindVersion = version
|
||||
}
|
||||
}
|
||||
|
||||
// WithKindAdditionalNetworks sets the additional networks for the Kind cluster for the test environment.
|
||||
func WithKindAdditionalNetworks(networks []string) SetupOption {
|
||||
return func(opts *SetupOptions) {
|
||||
opts.KindAdditionalNetworks = networks
|
||||
}
|
||||
}
|
||||
|
||||
// WithCNPGKustomizationURL sets the CloudNativePG kustomization URL for the test environment.
|
||||
func WithCNPGKustomizationURL(url string) SetupOption {
|
||||
return func(opts *SetupOptions) {
|
||||
@ -124,56 +93,31 @@ func WithIgnoreExistingResources(ignore bool) SetupOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithKindClusterNamePrefix sets the prefix for the Kind cluster name for the test environment.
|
||||
func withKindClusterNamePrefix(name string) SetupOption {
|
||||
return func(opts *SetupOptions) {
|
||||
opts.KindClusterNamePrefix = name
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
kindConfigFile = "config/kind-config.yaml"
|
||||
)
|
||||
|
||||
func defaultSetupOptions() SetupOptions {
|
||||
// TODO: renovate
|
||||
return SetupOptions{
|
||||
K8sVersion: "v1.31.1",
|
||||
KindVersion: "v0.24.0",
|
||||
CertManagerVersion: "v1.15.1",
|
||||
KindClusterNamePrefix: "e2e",
|
||||
KindAdditionalNetworks: []string{},
|
||||
}
|
||||
}
|
||||
|
||||
// Setup sets up the test environment for the e2e tests, starting kind and installing the necessary components.
|
||||
//
|
||||
//nolint:ireturn
|
||||
func Setup(ctx context.Context, opts ...SetupOption) (client.Client, error) {
|
||||
func Setup(ctx context.Context, cl client.Client, opts ...SetupOption) error {
|
||||
options := defaultSetupOptions()
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
if err := setupKind(ctx, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cl, _, err := internalClient.NewClient()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create Kubernetes client: %w", err)
|
||||
}
|
||||
|
||||
if err := installCertManager(ctx, cl, options); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
if err := installCNPG(ctx, cl, options); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// Return the Kubernetes client used for the tests
|
||||
return cl, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func installCNPG(ctx context.Context, cl client.Client, options SetupOptions) error {
|
||||
@ -227,32 +171,3 @@ func installCertManager(ctx context.Context, cl client.Client, options SetupOpti
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupKind(ctx context.Context, options SetupOptions) error {
|
||||
// This function sets up the environment for the e2e tests
|
||||
// by creating the cluster and installing the necessary
|
||||
// components.
|
||||
expectedClusterName := kindClusterName(options.KindClusterNamePrefix, options.K8sVersion)
|
||||
provider := cluster.NewProvider()
|
||||
clusterIsRunning, err := kind.IsClusterRunning(provider, expectedClusterName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check if Kind cluster is running: %w", err)
|
||||
}
|
||||
if !clusterIsRunning {
|
||||
kindOpts := []kind.CreateClusterOption{
|
||||
kind.WithK8sVersion(options.K8sVersion),
|
||||
kind.WithConfigFile(kindConfigFile),
|
||||
kind.WithNetworks(options.KindAdditionalNetworks),
|
||||
}
|
||||
if err := kind.CreateCluster(ctx, provider, expectedClusterName, kindOpts...); err != nil {
|
||||
return fmt.Errorf("failed to create Kind cluster: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func kindClusterName(prefix, k8sVersion string) string {
|
||||
k8sVersion = strings.ReplaceAll(k8sVersion, ".", "-")
|
||||
return fmt.Sprintf("%s-%s", prefix, k8sVersion)
|
||||
}
|
||||
|
||||
@ -1,164 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kind
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/client"
|
||||
"sigs.k8s.io/kind/pkg/cluster"
|
||||
"sigs.k8s.io/kind/pkg/cluster/nodes"
|
||||
)
|
||||
|
||||
// IsClusterRunning checks if a Kind cluster with the given name is running.
|
||||
func IsClusterRunning(provider *cluster.Provider, clusterName string) (bool, error) {
|
||||
clusters, err := provider.List()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to list Kind clusters: %w", err)
|
||||
}
|
||||
for _, c := range clusters {
|
||||
if c == clusterName {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// CreateClusterOptions are the options for creating a Kind cluster.
|
||||
type CreateClusterOptions struct {
|
||||
ConfigFile string
|
||||
K8sVersion string
|
||||
Networks []string
|
||||
}
|
||||
|
||||
// CreateClusterOption is the option for creating a Kind cluster.
|
||||
type CreateClusterOption func(*CreateClusterOptions)
|
||||
|
||||
// WithConfigFile sets the config file for creating a Kind cluster.
|
||||
func WithConfigFile(configFile string) CreateClusterOption {
|
||||
return func(opts *CreateClusterOptions) {
|
||||
opts.ConfigFile = configFile
|
||||
}
|
||||
}
|
||||
|
||||
// WithK8sVersion sets the Kubernetes version for creating a Kind cluster.
|
||||
func WithK8sVersion(k8sVersion string) CreateClusterOption {
|
||||
return func(opts *CreateClusterOptions) {
|
||||
opts.K8sVersion = k8sVersion
|
||||
}
|
||||
}
|
||||
|
||||
// WithNetworks sets the network for creating a Kind cluster.
|
||||
func WithNetworks(networks []string) CreateClusterOption {
|
||||
return func(opts *CreateClusterOptions) {
|
||||
opts.Networks = networks
|
||||
}
|
||||
}
|
||||
|
||||
// CreateCluster creates a Kind cluster with the given name.
|
||||
func CreateCluster(ctx context.Context, provider *cluster.Provider, name string, opts ...CreateClusterOption) error {
|
||||
options := &CreateClusterOptions{}
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
createOpts := []cluster.CreateOption{
|
||||
cluster.CreateWithRetain(true),
|
||||
cluster.CreateWithDisplayUsage(true),
|
||||
cluster.CreateWithDisplaySalutation(true),
|
||||
}
|
||||
if options.ConfigFile != "" {
|
||||
createOpts = append(createOpts, cluster.CreateWithConfigFile(options.ConfigFile))
|
||||
}
|
||||
if options.K8sVersion != "" {
|
||||
createOpts = append(createOpts, cluster.CreateWithNodeImage(fmt.Sprintf("kindest/node:%s", options.K8sVersion)))
|
||||
}
|
||||
err := provider.Create(name, createOpts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("kind cluster creation failed: %w", err)
|
||||
}
|
||||
|
||||
// Initialize Docker client
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Docker client: %w", err)
|
||||
}
|
||||
|
||||
// Since a cluster can mount additional certificates, we need to make sure they are
|
||||
// usable by the nodes in the cluster.
|
||||
nodeList, err := getNodes(provider, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := updateCACertificates(ctx, cli, nodeList); err != nil {
|
||||
return fmt.Errorf("failed to update CA certificates: %w", err)
|
||||
}
|
||||
|
||||
if err := connectNetworks(ctx, cli, nodeList, options.Networks); err != nil {
|
||||
return fmt.Errorf("failed to connect networks: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateCACertificates(ctx context.Context, cli *client.Client, nodes []nodes.Node) error {
|
||||
for _, node := range nodes {
|
||||
execConfig := container.ExecOptions{
|
||||
Cmd: strslice.StrSlice([]string{"update-ca-certificates"}),
|
||||
AttachStdout: true,
|
||||
AttachStderr: true,
|
||||
}
|
||||
execID, err := cli.ContainerExecCreate(ctx, node.String(), execConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create exec instance in node %s: %w", node.String(), err)
|
||||
}
|
||||
|
||||
err = cli.ContainerExecStart(ctx, execID.ID, container.ExecStartOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start exec instance in node %s: %w", node.String(), err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func connectNetworks(ctx context.Context, cli *client.Client, nodes []nodes.Node, networks []string) error {
|
||||
for _, netw := range networks {
|
||||
for _, node := range nodes {
|
||||
err := cli.NetworkConnect(ctx, netw, node.String(), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect node %s to network %s: %w", node.String(), netw, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getNodes(provider *cluster.Provider, clusterName string) ([]nodes.Node, error) {
|
||||
nodeList, err := provider.ListNodes(clusterName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get Kind nodes: %w", err)
|
||||
}
|
||||
|
||||
return nodeList, nil
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package kind provides utilities for ensuring the presence and correct version of the Kind binary,
|
||||
// as well as functions for installing and managing the Kind binary in a local project.
|
||||
package kind
|
||||
Loading…
Reference in New Issue
Block a user