From 2c808f5a581f48ceb21ade53471b404db4614fb6 Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Thu, 3 Jul 2025 18:13:56 +0200 Subject: [PATCH 1/8] Embed CAPI Operator reconciler in turtles Signed-off-by: Danil-Grigorev --- go.mod | 50 ++++- go.sum | 90 +++++++- internal/controllers/operator_reconciler.go | 201 ++++++++++++++++++ .../provider_health_check_reconciler.go | 63 ++++++ main.go | 18 +- 5 files changed, 418 insertions(+), 4 deletions(-) create mode 100644 internal/controllers/operator_reconciler.go create mode 100644 internal/controllers/provider_health_check_reconciler.go diff --git a/go.mod b/go.mod index 38049ac6a..31777e070 100644 --- a/go.mod +++ b/go.mod @@ -24,47 +24,90 @@ require ( ) require ( + cel.dev/expr v0.18.0 // indirect + dario.cat/mergo v1.0.1 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/sprig/v3 v3.3.0 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/adrg/xdg v0.5.3 // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/drone/envsubst/v2 v2.0.0-20210730161058-179042472c46 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/gobuffalo/flect v1.0.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect + github.com/google/cel-go v0.22.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/google/go-github/v52 v52.0.0 // indirect + github.com/google/go-github/v53 v53.2.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/huandu/xstrings v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.12.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/spf13/cobra v1.9.1 // indirect - github.com/stretchr/testify v1.10.0 // indirect + github.com/spf13/viper v1.20.0 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/valyala/fastjson v1.6.4 // indirect github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/net v0.38.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sync v0.14.0 // indirect @@ -73,6 +116,9 @@ require ( golang.org/x/time v0.8.0 // indirect golang.org/x/tools v0.31.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 // indirect + google.golang.org/grpc v1.67.3 // indirect google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -80,6 +126,8 @@ require ( k8s.io/apiserver v0.32.5 // indirect k8s.io/cluster-bootstrap v0.32.3 // indirect k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + oras.land/oras-go/v2 v2.6.0 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect ) diff --git a/go.sum b/go.sum index bae1e36f9..82f17f1e8 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,10 @@ github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+ github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= +github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -18,14 +22,23 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= 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/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= github.com/coredns/corefile-migration v1.0.26 h1:xiiEkVB1Dwolb24pkeDUDBfygV9/XsOSq79yFCrhptY= github.com/coredns/corefile-migration v1.0.26/go.mod h1:56DPqONc3njpVPsdilEnfijCwNGC3/kTJLl7i7SPavY= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -34,6 +47,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/drone/envsubst/v2 v2.0.0-20210730161058-179042472c46 h1:7QPwrLT79GlD5sizHf27aoY2RTvw62mO6x7mxkScNk0= +github.com/drone/envsubst/v2 v2.0.0-20210730161058-179042472c46/go.mod h1:esf2rsHFNlZlxsqsZDojNBcnNs5REqIvRrWRHqX0vEU= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= @@ -42,10 +57,13 @@ github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjT github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +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.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -62,6 +80,8 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4= github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -74,9 +94,17 @@ github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g= github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= 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.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-github/v52 v52.0.0 h1:uyGWOY+jMQ8GVGSX8dkSwCzlehU3WfdxQ7GweO/JP7M= +github.com/google/go-github/v52 v52.0.0/go.mod h1:WJV6VEEUPuMo5pXqqa2ZCZEdbQqua4zAk2MZTIo+m+4= +github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= +github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 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= @@ -84,7 +112,8 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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 v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= @@ -123,6 +152,10 @@ github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -141,14 +174,22 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.20.0 h1:zrxIyR3RQIOsarIrgL8+sAvALXul9jeEPa06Y0Ph6vY= +github.com/spf13/viper v1.20.0/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -160,10 +201,23 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 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/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= +github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.etcd.io/etcd/api/v3 v3.5.20 h1:aKfz3nPZECWoZJXMSH9y6h2adXjtOHaHTGEVCuCmaz0= +go.etcd.io/etcd/api/v3 v3.5.20/go.mod h1:QqKGViq4KTgOG43dr/uH0vmGWIaoJY3ggFi6ZH0TH/U= +go.etcd.io/etcd/client/pkg/v3 v3.5.20 h1:sZIAtra+xCo56gdf6BR62to/hiie5Bwl7hQIqMzVTEM= +go.etcd.io/etcd/client/pkg/v3 v3.5.20/go.mod h1:qaOi1k4ZA9lVLejXNvyPABrVEe7VymMF2433yyRQ7O0= +go.etcd.io/etcd/client/v3 v3.5.20 h1:jMT2MwQEhyvhQg49Cec+1ZHJzfUf6ZgcmV0GjPv0tIQ= +go.etcd.io/etcd/client/v3 v3.5.20/go.mod h1:J5lbzYRMUR20YolS5UjlqqMcu3/wdEvG5VNBhzyo3m0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= @@ -191,16 +245,26 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +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= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= @@ -208,17 +272,36 @@ golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKl golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20210615035016-665e8c7367d1/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +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.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= @@ -227,6 +310,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -235,7 +320,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 h1:TqExAhdPaB60Ux47Cn0oLV07rGnxZzIsaRhQaqS666A= @@ -274,6 +358,8 @@ k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJ k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc= +oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/cluster-api v1.10.2 h1:xfvtNu4Fy/41grL0ryH5xSKQjpJEWdO8HiV2lPCCozQ= diff --git a/internal/controllers/operator_reconciler.go b/internal/controllers/operator_reconciler.go new file mode 100644 index 000000000..d08c666f5 --- /dev/null +++ b/internal/controllers/operator_reconciler.go @@ -0,0 +1,201 @@ +/* +Copyright © 2023 - 2025 SUSE LLC + +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 controllers + +import ( + "context" + + "sigs.k8s.io/cluster-api-operator/controller" + ctrl "sigs.k8s.io/controller-runtime" + ctr "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2" +) + +// OperatorReconciler is a mapping wrapper for CAPIProvider -> operator provider resources +type OperatorReconciler struct{} + +// SetupWithManager is a mapping wrapper for CAPIProvider -> operator provider resources +func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options ctr.Options) error { + log := log.FromContext(ctx) + + if err := (&CAPIProviderReconcilerWrapper{ + GenericProviderReconciler: controller.GenericProviderReconciler{ + Provider: &operatorv1.CoreProvider{}, + ProviderList: &operatorv1.CoreProviderList{}, + Client: mgr.GetClient(), + Config: mgr.GetConfig(), + WatchConfigSecretChanges: true, + }}).SetupWithManager(ctx, mgr, options); err != nil { + log.Error(err, "unable to create controller", "controller", "CoreProvider") + return err + } + + if err := (&CAPIProviderReconcilerWrapper{ + GenericProviderReconciler: controller.GenericProviderReconciler{ + Provider: &operatorv1.InfrastructureProvider{}, + ProviderList: &operatorv1.InfrastructureProviderList{}, + Client: mgr.GetClient(), + Config: mgr.GetConfig(), + WatchConfigSecretChanges: true, + WatchCoreProviderChanges: true, + }}).SetupWithManager(ctx, mgr, options); err != nil { + log.Error(err, "unable to create controller", "controller", "InfrastructureProvider") + return err + } + + if err := (&CAPIProviderReconcilerWrapper{ + GenericProviderReconciler: controller.GenericProviderReconciler{ + Provider: &operatorv1.BootstrapProvider{}, + ProviderList: &operatorv1.BootstrapProviderList{}, + Client: mgr.GetClient(), + Config: mgr.GetConfig(), + WatchConfigSecretChanges: true, + WatchCoreProviderChanges: true, + }}).SetupWithManager(ctx, mgr, options); err != nil { + log.Error(err, "unable to create controller", "controller", "BootstrapProvider") + return err + } + + if err := (&CAPIProviderReconcilerWrapper{ + GenericProviderReconciler: controller.GenericProviderReconciler{ + Provider: &operatorv1.ControlPlaneProvider{}, + ProviderList: &operatorv1.ControlPlaneProviderList{}, + Client: mgr.GetClient(), + Config: mgr.GetConfig(), + WatchConfigSecretChanges: true, + WatchCoreProviderChanges: true, + }}).SetupWithManager(ctx, mgr, options); err != nil { + log.Error(err, "unable to create controller", "controller", "ControlPlaneProvider") + return err + } + + if err := (&CAPIProviderReconcilerWrapper{ + GenericProviderReconciler: controller.GenericProviderReconciler{ + Provider: &operatorv1.AddonProvider{}, + ProviderList: &operatorv1.AddonProviderList{}, + Client: mgr.GetClient(), + Config: mgr.GetConfig(), + WatchConfigSecretChanges: true, + WatchCoreProviderChanges: true, + }}).SetupWithManager(ctx, mgr, options); err != nil { + log.Error(err, "unable to create controller", "controller", "AddonProvider") + return err + } + + if err := (&CAPIProviderReconcilerWrapper{ + GenericProviderReconciler: controller.GenericProviderReconciler{ + Provider: &operatorv1.IPAMProvider{}, + ProviderList: &operatorv1.IPAMProviderList{}, + Client: mgr.GetClient(), + Config: mgr.GetConfig(), + WatchConfigSecretChanges: true, + WatchCoreProviderChanges: true, + }}).SetupWithManager(ctx, mgr, options); err != nil { + log.Error(err, "unable to create controller", "controller", "IPAMProvider") + return err + } + + if err := (&CAPIProviderReconcilerWrapper{ + GenericProviderReconciler: controller.GenericProviderReconciler{ + Provider: &operatorv1.RuntimeExtensionProvider{}, + ProviderList: &operatorv1.RuntimeExtensionProviderList{}, + Client: mgr.GetClient(), + Config: mgr.GetConfig(), + WatchConfigSecretChanges: true, + WatchCoreProviderChanges: true, + }}).SetupWithManager(ctx, mgr, options); err != nil { + log.Error(err, "unable to create controller", "controller", "RuntimeExtensionProvider") + return err + } + + return nil +} + +//+kubebuilder:rbac:groups=turtles-capi.cattle.io,resources=capiproviders,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=turtles-capi.cattle.io,resources=capiproviders/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=turtles-capi.cattle.io,resources=capiproviders/finalizers,verbs=update + +// CAPIProviderReconcilerWrapper wraps the upstream CAPIProviderReconciler +type CAPIProviderReconcilerWrapper struct { + controller.GenericProviderReconciler +} + +// BuildWithManager builds the CAPIProviderReconciler +func (r *CAPIProviderReconcilerWrapper) BuildWithManager(ctx context.Context, mgr ctrl.Manager) (*ctrl.Builder, error) { + builder, err := r.GenericProviderReconciler.BuildWithManager(ctx, mgr) + if err != nil { + return nil, err + } + + reconciler := controller.NewPhaseReconciler(r.GenericProviderReconciler, r.Provider, r.ProviderList) + + r.GenericProviderReconciler.ReconcilePhases = []controller.PhaseFn{ + r.setDefaultProviderSpec, + reconciler.ApplyFromCache, + reconciler.PreflightChecks, + reconciler.InitializePhaseReconciler, + reconciler.DownloadManifests, + reconciler.Load, + reconciler.Fetch, + reconciler.Store, + reconciler.Upgrade, + reconciler.Install, + reconciler.ReportStatus, + reconciler.Finalize, + } + + return builder, err +} + +// SetupWithManager sets up the controller with the Manager. +func (r *CAPIProviderReconcilerWrapper) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options ctr.Options) error { + builder, err := r.BuildWithManager(ctx, mgr) + if err != nil { + return err + } + + return builder.WithOptions(options).Complete(r) +} + +func (r *CAPIProviderReconcilerWrapper) Reconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, reterr error) { + return r.GenericProviderReconciler.Reconcile(ctx, req) +} + +func (r *CAPIProviderReconcilerWrapper) setDefaultProviderSpec(ctx context.Context) (*controller.Result, error) { + setDefaultProviderSpec(r.Provider) + + return &controller.Result{}, nil +} + +// setDefaultProviderSpec sets the default values for the provider spec. +func setDefaultProviderSpec(o operatorv1.GenericProvider) { + providerSpec := o.GetSpec() + providerNamespace := o.GetNamespace() + + if providerSpec.ConfigSecret != nil && providerSpec.ConfigSecret.Namespace == "" { + providerSpec.ConfigSecret.Namespace = providerNamespace + } + + if providerSpec.AdditionalManifestsRef != nil && providerSpec.AdditionalManifestsRef.Namespace == "" { + providerSpec.AdditionalManifestsRef.Namespace = providerNamespace + } + + o.SetSpec(providerSpec) +} diff --git a/internal/controllers/provider_health_check_reconciler.go b/internal/controllers/provider_health_check_reconciler.go new file mode 100644 index 000000000..3523a47c1 --- /dev/null +++ b/internal/controllers/provider_health_check_reconciler.go @@ -0,0 +1,63 @@ +/* +Copyright © 2023 - 2025 SUSE LLC + +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 controllers + +import ( + kerrors "k8s.io/apimachinery/pkg/util/errors" + "sigs.k8s.io/cluster-api-operator/controller" + ctrl "sigs.k8s.io/controller-runtime" + ctr "sigs.k8s.io/controller-runtime/pkg/controller" + + operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2" +) + +// ProviderHealthCheckReconciler is a health check wrapper for operator provider resources +type ProviderHealthCheckReconciler struct{} + +// SetupWithManager is setup manager wrapper for operator healthcheck +func (r *ProviderHealthCheckReconciler) SetupWithManager(mgr ctrl.Manager, options ctr.Options) error { + return kerrors.NewAggregate([]error{ + (&controller.GenericProviderHealthCheckReconciler{ + Client: mgr.GetClient(), + Provider: &operatorv1.CoreProvider{}, + }).SetupWithManager(mgr, options), + (&controller.GenericProviderHealthCheckReconciler{ + Client: mgr.GetClient(), + Provider: &operatorv1.InfrastructureProvider{}, + }).SetupWithManager(mgr, options), + (&controller.GenericProviderHealthCheckReconciler{ + Client: mgr.GetClient(), + Provider: &operatorv1.BootstrapProvider{}, + }).SetupWithManager(mgr, options), + (&controller.GenericProviderHealthCheckReconciler{ + Client: mgr.GetClient(), + Provider: &operatorv1.ControlPlaneProvider{}, + }).SetupWithManager(mgr, options), + (&controller.GenericProviderHealthCheckReconciler{ + Client: mgr.GetClient(), + Provider: &operatorv1.AddonProvider{}, + }).SetupWithManager(mgr, options), + (&controller.GenericProviderHealthCheckReconciler{ + Client: mgr.GetClient(), + Provider: &operatorv1.RuntimeExtensionProvider{}, + }).SetupWithManager(mgr, options), + (&controller.GenericProviderHealthCheckReconciler{ + Client: mgr.GetClient(), + Provider: &operatorv1.IPAMProvider{}, + }).SetupWithManager(mgr, options), + }) +} diff --git a/main.go b/main.go index 5b42f588e..cba9abae6 100644 --- a/main.go +++ b/main.go @@ -268,6 +268,22 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager) { setupLog.Info("enabling CAPI Operator synchronization controller") + if feature.Gates.Enabled(feature.EmbeddedOperator) { + if err := (&controllers.OperatorReconciler{}).SetupWithManager(ctx, mgr, controller.Options{ + MaxConcurrentReconciles: concurrencyNumber, + }); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Operator") + os.Exit(1) + } + + if err := (&controllers.ProviderHealthCheckReconciler{}).SetupWithManager(mgr, controller.Options{ + MaxConcurrentReconciles: concurrencyNumber, + }); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Healthcheck") + os.Exit(1) + } + } + if err := (&controllers.CAPIProviderReconciler{ Client: mgr.GetClient(), Scheme: scheme, @@ -275,7 +291,7 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager) { MaxConcurrentReconciles: concurrencyNumber, CacheSyncTimeout: maxDuration, }); err != nil { - setupLog.Error(err, "unable to create CAPI Provider controller") + setupLog.Error(err, "unable to create CAPI Provider sync controller") os.Exit(1) } From 4125c56d23a0637b16d9af24c9ea70b6f1f3d27a Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Fri, 4 Jul 2025 11:43:36 +0200 Subject: [PATCH 2/8] Lint fixes Signed-off-by: Danil-Grigorev --- internal/controllers/operator_reconciler.go | 36 +++++++++++-------- .../provider_health_check_reconciler.go | 6 ++-- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/internal/controllers/operator_reconciler.go b/internal/controllers/operator_reconciler.go index d08c666f5..6fc8a641e 100644 --- a/internal/controllers/operator_reconciler.go +++ b/internal/controllers/operator_reconciler.go @@ -19,19 +19,19 @@ package controllers import ( "context" - "sigs.k8s.io/cluster-api-operator/controller" ctrl "sigs.k8s.io/controller-runtime" ctr "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2" + "sigs.k8s.io/cluster-api-operator/controller" ) -// OperatorReconciler is a mapping wrapper for CAPIProvider -> operator provider resources +// OperatorReconciler is a mapping wrapper for CAPIProvider -> operator provider resources. type OperatorReconciler struct{} -// SetupWithManager is a mapping wrapper for CAPIProvider -> operator provider resources +// SetupWithManager is a mapping wrapper for CAPIProvider -> operator provider resources. func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options ctr.Options) error { log := log.FromContext(ctx) @@ -42,7 +42,8 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana Client: mgr.GetClient(), Config: mgr.GetConfig(), WatchConfigSecretChanges: true, - }}).SetupWithManager(ctx, mgr, options); err != nil { + }, + }).SetupWithManager(ctx, mgr, options); err != nil { log.Error(err, "unable to create controller", "controller", "CoreProvider") return err } @@ -55,7 +56,8 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana Config: mgr.GetConfig(), WatchConfigSecretChanges: true, WatchCoreProviderChanges: true, - }}).SetupWithManager(ctx, mgr, options); err != nil { + }, + }).SetupWithManager(ctx, mgr, options); err != nil { log.Error(err, "unable to create controller", "controller", "InfrastructureProvider") return err } @@ -68,7 +70,8 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana Config: mgr.GetConfig(), WatchConfigSecretChanges: true, WatchCoreProviderChanges: true, - }}).SetupWithManager(ctx, mgr, options); err != nil { + }, + }).SetupWithManager(ctx, mgr, options); err != nil { log.Error(err, "unable to create controller", "controller", "BootstrapProvider") return err } @@ -81,7 +84,8 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana Config: mgr.GetConfig(), WatchConfigSecretChanges: true, WatchCoreProviderChanges: true, - }}).SetupWithManager(ctx, mgr, options); err != nil { + }, + }).SetupWithManager(ctx, mgr, options); err != nil { log.Error(err, "unable to create controller", "controller", "ControlPlaneProvider") return err } @@ -94,7 +98,8 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana Config: mgr.GetConfig(), WatchConfigSecretChanges: true, WatchCoreProviderChanges: true, - }}).SetupWithManager(ctx, mgr, options); err != nil { + }, + }).SetupWithManager(ctx, mgr, options); err != nil { log.Error(err, "unable to create controller", "controller", "AddonProvider") return err } @@ -107,7 +112,8 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana Config: mgr.GetConfig(), WatchConfigSecretChanges: true, WatchCoreProviderChanges: true, - }}).SetupWithManager(ctx, mgr, options); err != nil { + }, + }).SetupWithManager(ctx, mgr, options); err != nil { log.Error(err, "unable to create controller", "controller", "IPAMProvider") return err } @@ -120,7 +126,8 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana Config: mgr.GetConfig(), WatchConfigSecretChanges: true, WatchCoreProviderChanges: true, - }}).SetupWithManager(ctx, mgr, options); err != nil { + }, + }).SetupWithManager(ctx, mgr, options); err != nil { log.Error(err, "unable to create controller", "controller", "RuntimeExtensionProvider") return err } @@ -132,12 +139,12 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana //+kubebuilder:rbac:groups=turtles-capi.cattle.io,resources=capiproviders/status,verbs=get;update;patch //+kubebuilder:rbac:groups=turtles-capi.cattle.io,resources=capiproviders/finalizers,verbs=update -// CAPIProviderReconcilerWrapper wraps the upstream CAPIProviderReconciler +// CAPIProviderReconcilerWrapper wraps the upstream CAPIProviderReconciler. type CAPIProviderReconcilerWrapper struct { controller.GenericProviderReconciler } -// BuildWithManager builds the CAPIProviderReconciler +// BuildWithManager builds the CAPIProviderReconciler. func (r *CAPIProviderReconcilerWrapper) BuildWithManager(ctx context.Context, mgr ctrl.Manager) (*ctrl.Builder, error) { builder, err := r.GenericProviderReconciler.BuildWithManager(ctx, mgr) if err != nil { @@ -146,7 +153,7 @@ func (r *CAPIProviderReconcilerWrapper) BuildWithManager(ctx context.Context, mg reconciler := controller.NewPhaseReconciler(r.GenericProviderReconciler, r.Provider, r.ProviderList) - r.GenericProviderReconciler.ReconcilePhases = []controller.PhaseFn{ + r.ReconcilePhases = []controller.PhaseFn{ r.setDefaultProviderSpec, reconciler.ApplyFromCache, reconciler.PreflightChecks, @@ -174,11 +181,12 @@ func (r *CAPIProviderReconcilerWrapper) SetupWithManager(ctx context.Context, mg return builder.WithOptions(options).Complete(r) } +// Reconcile wraps the upstream Reconcile method. func (r *CAPIProviderReconcilerWrapper) Reconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, reterr error) { return r.GenericProviderReconciler.Reconcile(ctx, req) } -func (r *CAPIProviderReconcilerWrapper) setDefaultProviderSpec(ctx context.Context) (*controller.Result, error) { +func (r *CAPIProviderReconcilerWrapper) setDefaultProviderSpec(_ context.Context) (*controller.Result, error) { setDefaultProviderSpec(r.Provider) return &controller.Result{}, nil diff --git a/internal/controllers/provider_health_check_reconciler.go b/internal/controllers/provider_health_check_reconciler.go index 3523a47c1..631e8f8ee 100644 --- a/internal/controllers/provider_health_check_reconciler.go +++ b/internal/controllers/provider_health_check_reconciler.go @@ -18,17 +18,17 @@ package controllers import ( kerrors "k8s.io/apimachinery/pkg/util/errors" - "sigs.k8s.io/cluster-api-operator/controller" ctrl "sigs.k8s.io/controller-runtime" ctr "sigs.k8s.io/controller-runtime/pkg/controller" operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2" + "sigs.k8s.io/cluster-api-operator/controller" ) -// ProviderHealthCheckReconciler is a health check wrapper for operator provider resources +// ProviderHealthCheckReconciler is a health check wrapper for operator provider resources. type ProviderHealthCheckReconciler struct{} -// SetupWithManager is setup manager wrapper for operator healthcheck +// SetupWithManager is setup manager wrapper for operator healthcheck. func (r *ProviderHealthCheckReconciler) SetupWithManager(mgr ctrl.Manager, options ctr.Options) error { return kerrors.NewAggregate([]error{ (&controller.GenericProviderHealthCheckReconciler{ From 7d1726354ffdd6f40e0621eef1e33483ab71a2b0 Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Fri, 4 Jul 2025 14:47:07 +0200 Subject: [PATCH 3/8] Add operator rbac to turtles Signed-off-by: Danil-Grigorev --- .../templates/clusterctl-config.yaml | 5 ++++- .../rancher-turtles/templates/operator-crds.yaml | 14 ++++++++++++++ config/operator/bases/operator_role.yaml | 13 +++++++++++++ config/operator/kustomization.yaml | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 config/operator/bases/operator_role.yaml diff --git a/charts/rancher-turtles/templates/clusterctl-config.yaml b/charts/rancher-turtles/templates/clusterctl-config.yaml index 60892df5c..fb88cd7e9 100644 --- a/charts/rancher-turtles/templates/clusterctl-config.yaml +++ b/charts/rancher-turtles/templates/clusterctl-config.yaml @@ -1,7 +1,10 @@ {{- if index .Values "rancherTurtles" "features" "embedded-operator" "enabled" }} -apiversion: v1 +apiVersion: v1 kind: ConfigMap metadata: name: clusterctl-config namespace: '{{ .Values.rancherTurtles.namespace }}' + annotations: + "helm.sh/hook": "pre-install, pre-upgrade" + "helm.sh/hook-weight": "-1" {{- end}} \ No newline at end of file diff --git a/charts/rancher-turtles/templates/operator-crds.yaml b/charts/rancher-turtles/templates/operator-crds.yaml index eb3c311a3..2ba51c824 100644 --- a/charts/rancher-turtles/templates/operator-crds.yaml +++ b/charts/rancher-turtles/templates/operator-crds.yaml @@ -21810,4 +21810,18 @@ spec: storage: true subresources: status: {} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + rancher-turtles/aggregate-to-manager: "true" + name: rancher-turtles-operator-admin +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' {{- end }} diff --git a/config/operator/bases/operator_role.yaml b/config/operator/bases/operator_role.yaml new file mode 100644 index 000000000..efe4f6dc3 --- /dev/null +++ b/config/operator/bases/operator_role.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + rancher-turtles/aggregate-to-manager: "true" + name: operator-admin +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' \ No newline at end of file diff --git a/config/operator/kustomization.yaml b/config/operator/kustomization.yaml index 4a5c423b9..d718bbee5 100644 --- a/config/operator/kustomization.yaml +++ b/config/operator/kustomization.yaml @@ -9,6 +9,7 @@ resources: - bases/operator.cluster.x-k8s.io_infrastructureproviders.yaml - bases/operator.cluster.x-k8s.io_ipamproviders.yaml - bases/operator.cluster.x-k8s.io_runtimeextensionproviders.yaml +- bases/operator_role.yaml #+kubebuilder:scaffold:crdkustomizeresource patches: From 9e60e2e8f8573a4d891e73e57a1568f1a006834a Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Sun, 6 Jul 2025 15:47:10 +0200 Subject: [PATCH 4/8] Add e2e test for embedded-operator Signed-off-by: Danil-Grigorev --- charts/rancher-turtles/templates/clusterctl-config.yaml | 3 --- charts/rancher-turtles/templates/deployment.yaml | 2 +- test/e2e/suites/chart-upgrade/chart_upgrade_test.go | 3 +++ test/e2e/suites/etcd-snapshot-restore/suite_test.go | 2 ++ test/e2e/suites/import-gitops-v3/suite_test.go | 4 ++++ test/e2e/suites/v2prov/suite_test.go | 4 ++++ 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/charts/rancher-turtles/templates/clusterctl-config.yaml b/charts/rancher-turtles/templates/clusterctl-config.yaml index fb88cd7e9..31df5bbb5 100644 --- a/charts/rancher-turtles/templates/clusterctl-config.yaml +++ b/charts/rancher-turtles/templates/clusterctl-config.yaml @@ -4,7 +4,4 @@ kind: ConfigMap metadata: name: clusterctl-config namespace: '{{ .Values.rancherTurtles.namespace }}' - annotations: - "helm.sh/hook": "pre-install, pre-upgrade" - "helm.sh/hook-weight": "-1" {{- end}} \ No newline at end of file diff --git a/charts/rancher-turtles/templates/deployment.yaml b/charts/rancher-turtles/templates/deployment.yaml index 190da4605..7c75e42b6 100644 --- a/charts/rancher-turtles/templates/deployment.yaml +++ b/charts/rancher-turtles/templates/deployment.yaml @@ -26,7 +26,7 @@ spec: containers: - args: - --leader-elect - - --feature-gates=agent-tls-mode={{ index .Values "rancherTurtles" "features" "agent-tls-mode" "enabled"}},ui-plugin={{ index .Values "turtlesUI" "enabled"}} + - --feature-gates=agent-tls-mode={{ index .Values "rancherTurtles" "features" "agent-tls-mode" "enabled"}},ui-plugin={{ index .Values "turtlesUI" "enabled"}},embedded-operator={{ index .Values "rancherTurtles" "features" "embedded-operator" "enabled"}} {{- range .Values.rancherTurtles.managerArguments }} - {{ . }} {{- end }} diff --git a/test/e2e/suites/chart-upgrade/chart_upgrade_test.go b/test/e2e/suites/chart-upgrade/chart_upgrade_test.go index c5d1a31be..6871107e2 100644 --- a/test/e2e/suites/chart-upgrade/chart_upgrade_test.go +++ b/test/e2e/suites/chart-upgrade/chart_upgrade_test.go @@ -59,6 +59,9 @@ var _ = Describe("Chart upgrade functionality should work", Label(e2e.ShortTestL testenv.DeployChartMuseum(ctx, chartMuseumDeployInput) + rtInput.AdditionalValues["cluster-api-operator.enabled"] = "false" + rtInput.AdditionalValues["rancherTurtles.features.embedded-operator.enabled"] = "true" + upgradeInput := testenv.UpgradeRancherTurtlesInput{ BootstrapClusterProxy: bootstrapClusterProxy, AdditionalValues: rtInput.AdditionalValues, diff --git a/test/e2e/suites/etcd-snapshot-restore/suite_test.go b/test/e2e/suites/etcd-snapshot-restore/suite_test.go index 34ff97e65..3cf778b16 100644 --- a/test/e2e/suites/etcd-snapshot-restore/suite_test.go +++ b/test/e2e/suites/etcd-snapshot-restore/suite_test.go @@ -80,6 +80,8 @@ var _ = SynchronizedBeforeSuite( AdditionalValues: map[string]string{ "rancherTurtles.features.day2operations.enabled": "true", // enable day2operations feature "rancherTurtles.features.day2operations.etcdBackupRestore.enabled": "true", // enable etcdBackupRestore feature + "cluster-api-operator.enabled": "false", + "rancherTurtles.features.embedded-operator.enabled": "true", }, WaitForDeployments: testenv.DefaultDeployments, }) diff --git a/test/e2e/suites/import-gitops-v3/suite_test.go b/test/e2e/suites/import-gitops-v3/suite_test.go index 487b01c6a..295236208 100644 --- a/test/e2e/suites/import-gitops-v3/suite_test.go +++ b/test/e2e/suites/import-gitops-v3/suite_test.go @@ -77,6 +77,10 @@ var _ = SynchronizedBeforeSuite( testenv.DeployRancherTurtles(ctx, testenv.DeployRancherTurtlesInput{ BootstrapClusterProxy: setupClusterResult.BootstrapClusterProxy, + AdditionalValues: map[string]string{ + "cluster-api-operator.enabled": "false", + "rancherTurtles.features.embedded-operator.enabled": "true", + }, }) data, err := json.Marshal(e2e.Setup{ diff --git a/test/e2e/suites/v2prov/suite_test.go b/test/e2e/suites/v2prov/suite_test.go index bf8d84934..0a8db4bda 100644 --- a/test/e2e/suites/v2prov/suite_test.go +++ b/test/e2e/suites/v2prov/suite_test.go @@ -84,6 +84,10 @@ var _ = SynchronizedBeforeSuite( BootstrapClusterProxy: setupClusterResult.BootstrapClusterProxy, CAPIProvidersYAML: e2e.CapiProviders, WaitForDeployments: testenv.DefaultDeployments, + AdditionalValues: map[string]string{ + "cluster-api-operator.enabled": "false", + "rancherTurtles.features.embedded-operator.enabled": "true", + }, }) testenv.RestartRancher(ctx, testenv.RestartRancherInput{ From 5538771bd97290c813ca89e329c62f026e102540 Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Mon, 7 Jul 2025 12:43:10 +0200 Subject: [PATCH 5/8] Verify CAPIO deployment is removed Signed-off-by: Danil-Grigorev --- .../chart-upgrade/chart_upgrade_test.go | 12 ++++++++++ test/framework/turtles.go | 23 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/test/e2e/suites/chart-upgrade/chart_upgrade_test.go b/test/e2e/suites/chart-upgrade/chart_upgrade_test.go index 6871107e2..1e956db6d 100644 --- a/test/e2e/suites/chart-upgrade/chart_upgrade_test.go +++ b/test/e2e/suites/chart-upgrade/chart_upgrade_test.go @@ -59,6 +59,7 @@ var _ = Describe("Chart upgrade functionality should work", Label(e2e.ShortTestL testenv.DeployChartMuseum(ctx, chartMuseumDeployInput) + // Perform upgrade with migration to embedded operator implementation rtInput.AdditionalValues["cluster-api-operator.enabled"] = "false" rtInput.AdditionalValues["rancherTurtles.features.embedded-operator.enabled"] = "true" @@ -68,6 +69,17 @@ var _ = Describe("Chart upgrade functionality should work", Label(e2e.ShortTestL PostUpgradeSteps: []func(){}, } + upgradeInput.PostUpgradeSteps = append(upgradeInput.PostUpgradeSteps, func() { + By("Waiting for the upstream CAPI operator deployment to be removed") + framework.WaitForDeploymentsRemoved(ctx, framework.WaitForDeploymentsRemovedInput{ + Getter: bootstrapClusterProxy.GetClient(), + Deployment: &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{ + Name: "rancher-turtles-cluster-api-operator", + Namespace: e2e.RancherTurtlesNamespace, + }}, + }, e2eConfig.GetIntervals(bootstrapClusterProxy.GetName(), "wait-controllers")...) + }) + upgradeInput.PostUpgradeSteps = append(upgradeInput.PostUpgradeSteps, func() { By("Waiting for CAAPF deployment to be available") capiframework.WaitForDeploymentsAvailable(ctx, capiframework.WaitForDeploymentsAvailableInput{ diff --git a/test/framework/turtles.go b/test/framework/turtles.go index fd6a65f36..ff63bfe3e 100644 --- a/test/framework/turtles.go +++ b/test/framework/turtles.go @@ -20,6 +20,7 @@ import ( "context" "strings" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "k8s.io/klog/v2" @@ -71,3 +72,25 @@ func WaitForCAPIProviderRollout(ctx context.Context, input WaitForCAPIProviderRo client.ObjectKeyFromObject(input.Deployment).String(), input.Image, klog.KObj(input.Deployment)) } } + +// WaitForDeploymentsRemovedInput is the input for WaitForDeploymentsRemoved. +type WaitForDeploymentsRemovedInput = capiframework.WaitForDeploymentsAvailableInput + +// WaitForDeploymentsAvRemoved waits until the Deployment is removed. +func WaitForDeploymentsRemoved(ctx context.Context, input WaitForDeploymentsRemovedInput, intervals ...interface{}) { + Byf("Waiting for deployment %s to be removed", klog.KObj(input.Deployment)) + deployment := &appsv1.Deployment{} + Eventually(func() bool { + key := client.ObjectKey{ + Namespace: input.Deployment.GetNamespace(), + Name: input.Deployment.GetName(), + } + if err := input.Getter.Get(ctx, key, deployment); err == nil { + return false + } else if apierrors.IsNotFound(err) { + return true + } + + return false + }, intervals...).Should(BeTrue(), func() string { return capiframework.DescribeFailedDeployment(input, deployment) }) +} From 1d11a6bde465f607e0ab83727a2d112c3c7fbe78 Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Mon, 7 Jul 2025 12:59:13 +0200 Subject: [PATCH 6/8] Set manager concurrency by default to 15 across all controllers Signed-off-by: Danil-Grigorev --- main.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/main.go b/main.go index cba9abae6..bded61e95 100644 --- a/main.go +++ b/main.go @@ -39,6 +39,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/config" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/metrics/server" @@ -70,6 +71,7 @@ var ( syncPeriod time.Duration healthAddr string concurrencyNumber int + managerConcurrency int rancherKubeconfig string insecureSkipVerify bool ) @@ -118,6 +120,9 @@ func initFlags(fs *pflag.FlagSet) { fs.IntVar(&concurrencyNumber, "concurrency", 1, "Number of resources to process simultaneously") + fs.IntVar(&managerConcurrency, "manager-concurrency", 15, + "Number of concurrent reconciles to process simultaneously across all controllers") + fs.StringVar(&rancherKubeconfig, "rancher-kubeconfig", "", "Path to the Rancher kubeconfig file. Only required if running out-of-cluster.") @@ -158,6 +163,9 @@ func main() { }, }, }, + Controller: config.Controller{ + MaxConcurrentReconciles: concurrencyNumber, + }, Cache: cache.Options{ SyncPeriod: &syncPeriod, }, From 377ef6ce6856ac731974f2819fbe320ff28ad7fb Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Mon, 7 Jul 2025 15:47:10 +0200 Subject: [PATCH 7/8] Remove CAPI operator dependency and move FG to beta Signed-off-by: Danil-Grigorev --- .github/workflows/test_chart.yaml | 3 --- charts/rancher-turtles/Chart.yaml | 5 ----- charts/rancher-turtles/values.yaml | 2 +- feature/feature.go | 2 +- scripts/turtles-dev.sh | 2 +- 5 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.github/workflows/test_chart.yaml b/.github/workflows/test_chart.yaml index c538b6ec8..d2704da2c 100644 --- a/.github/workflows/test_chart.yaml +++ b/.github/workflows/test_chart.yaml @@ -51,9 +51,6 @@ jobs: - name: Build docker image run: make docker-build - - name: Add CAPI operator chart repo - run: helm repo add capi-operator https://kubernetes-sigs.github.io/cluster-api-operator - - name: Package operator chart run: make release-chart diff --git a/charts/rancher-turtles/Chart.yaml b/charts/rancher-turtles/Chart.yaml index fd77b588b..7f432ed98 100644 --- a/charts/rancher-turtles/Chart.yaml +++ b/charts/rancher-turtles/Chart.yaml @@ -11,11 +11,6 @@ keywords: - cluster-api - capi - provisioning -dependencies: - - name: cluster-api-operator - version: v0.18.1 - repository: https://kubernetes-sigs.github.io/cluster-api-operator - condition: cluster-api-operator.enabled annotations: catalog.cattle.io/certified: rancher catalog.cattle.io/display-name: Rancher Turtles - the Cluster API Extension diff --git a/charts/rancher-turtles/values.yaml b/charts/rancher-turtles/values.yaml index dfa06314d..963b93b77 100644 --- a/charts/rancher-turtles/values.yaml +++ b/charts/rancher-turtles/values.yaml @@ -28,7 +28,7 @@ rancherTurtles: # embedded-operator: Embed operator controller loops. embedded-operator: # enabled: Turn on or off. - enabled: false + enabled: true # day2operations: Alpha feature. day2operations: # enabled: Turn on or off. diff --git a/feature/feature.go b/feature/feature.go index 76fb2d9b5..b96faed71 100644 --- a/feature/feature.go +++ b/feature/feature.go @@ -40,5 +40,5 @@ func init() { var defaultGates = map[featuregate.Feature]featuregate.FeatureSpec{ AgentTLSMode: {Default: true, PreRelease: featuregate.Beta}, UIPlugin: {Default: false, PreRelease: featuregate.Alpha}, - EmbeddedOperator: {Default: false, PreRelease: featuregate.Alpha}, + EmbeddedOperator: {Default: true, PreRelease: featuregate.Beta}, } diff --git a/scripts/turtles-dev.sh b/scripts/turtles-dev.sh index fc669f718..99dc98c84 100755 --- a/scripts/turtles-dev.sh +++ b/scripts/turtles-dev.sh @@ -40,7 +40,6 @@ kind load docker-image $RANCHER_IMAGE --name $CLUSTER_NAME kubectl rollout status deployment coredns -n kube-system --timeout=90s helm repo add rancher-latest https://releases.rancher.com/server-charts/latest --force-update -helm repo add capi-operator https://kubernetes-sigs.github.io/cluster-api-operator --force-update helm repo add jetstack https://charts.jetstack.io --force-update helm repo add ngrok https://charts.ngrok.com --force-update helm repo update @@ -95,6 +94,7 @@ install_local_rancher_turtles_chart() { -n rancher-turtles-system \ --set cluster-api-operator.enabled=true \ --set cluster-api-operator.cluster-api.enabled=false \ + --set rancherTurtles.features.embedded-operator.enabled=true \ --set rancherTurtles.features.day2operations.enabled=true \ --set rancherTurtles.features.day2operations.imageVersion=dev \ --set rancherTurtles.features.day2operations.etcdBackupRestore.enabled=true \ From 6e71c3318c932af19932383405dfc2ee396cf4d9 Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Mon, 7 Jul 2025 16:48:07 +0200 Subject: [PATCH 8/8] Remove outstandig bits and FG flag Signed-off-by: Danil-Grigorev --- Makefile | 1 - charts/rancher-turtles/questions.yml | 12 +- .../templates/clusterctl-config.yaml | 4 +- .../rancher-turtles/templates/deployment.yaml | 6 +- .../templates/operator-crds.yaml | 2 - charts/rancher-turtles/values.schema.json | 144 ------------------ charts/rancher-turtles/values.yaml | 46 ------ feature/feature.go | 8 +- main.go | 24 ++- scripts/turtles-dev.sh | 2 - .../chart-upgrade/chart_upgrade_test.go | 4 - .../etcd-snapshot-restore/suite_test.go | 2 - .../e2e/suites/import-gitops-v3/suite_test.go | 5 +- test/e2e/suites/v2prov/suite_test.go | 5 +- 14 files changed, 18 insertions(+), 247 deletions(-) diff --git a/Makefile b/Makefile index 8125d7ce8..4b107dc49 100644 --- a/Makefile +++ b/Makefile @@ -559,7 +559,6 @@ build-chart: $(HELM) $(KUSTOMIZE) $(RELEASE_DIR) $(CHART_RELEASE_DIR) $(CHART_PA $(KUSTOMIZE) build ./config/operatorchart > $(CHART_DIR)/templates/operator-crds.yaml $(KUSTOMIZE) build ./exp/day2/config/chart > $(CHART_DIR)/templates/rancher-turtles-exp-day2-components.yaml $(KUSTOMIZE) build ./exp/clusterclass/config/default > $(CHART_DIR)/templates/rancher-turtles-exp-clusterclass-components.yaml - ./scripts/process-manifests.sh embedded-operator $(CHART_DIR)/templates/operator-crds.yaml ./scripts/process-manifests.sh day2operations $(CHART_DIR)/templates/rancher-turtles-exp-day2-components.yaml ./scripts/process-manifests.sh clusterclass-operations $(CHART_DIR)/templates/rancher-turtles-exp-clusterclass-components.yaml cp -rf $(CHART_DIR)/* $(CHART_RELEASE_DIR) diff --git a/charts/rancher-turtles/questions.yml b/charts/rancher-turtles/questions.yml index a7f240fe7..9ea290d3d 100644 --- a/charts/rancher-turtles/questions.yml +++ b/charts/rancher-turtles/questions.yml @@ -8,11 +8,6 @@ questions: show_subquestion_if: true group: "Rancher Turtles Extra Settings" subquestions: - - variable: cluster-api-operator.cert-manager.enabled - default: false - type: boolean - description: "Flag to enable or disable installation of cert-manager. If set to false then you will need to install cert-manager manually." - label: "Enable Cert Manager" - variable: turtlesUI.enabled default: false type: boolean @@ -51,9 +46,4 @@ questions: description: "[ALPHA] Enable ETCD Backup and Restore functionality in Rancher Turtles." type: boolean group: "ETCD Backup and Restore Settings" - show_if: "rancherTurtles.features.day2operations.enabled" - - variable: rancherTurtles.features.embedded-operator.enabled - label: "Enable Turtles Embedded Operator" - description: "[ALPHA] Enable Turtles Embedded Operator functionality in Rancher Turtles." - type: boolean - group: "Embedded operator" \ No newline at end of file + show_if: "rancherTurtles.features.day2operations.enabled" \ No newline at end of file diff --git a/charts/rancher-turtles/templates/clusterctl-config.yaml b/charts/rancher-turtles/templates/clusterctl-config.yaml index 31df5bbb5..225f24db0 100644 --- a/charts/rancher-turtles/templates/clusterctl-config.yaml +++ b/charts/rancher-turtles/templates/clusterctl-config.yaml @@ -1,7 +1,5 @@ -{{- if index .Values "rancherTurtles" "features" "embedded-operator" "enabled" }} apiVersion: v1 kind: ConfigMap metadata: name: clusterctl-config - namespace: '{{ .Values.rancherTurtles.namespace }}' -{{- end}} \ No newline at end of file + namespace: '{{ .Values.rancherTurtles.namespace }}' \ No newline at end of file diff --git a/charts/rancher-turtles/templates/deployment.yaml b/charts/rancher-turtles/templates/deployment.yaml index 7c75e42b6..df9c84e61 100644 --- a/charts/rancher-turtles/templates/deployment.yaml +++ b/charts/rancher-turtles/templates/deployment.yaml @@ -26,7 +26,7 @@ spec: containers: - args: - --leader-elect - - --feature-gates=agent-tls-mode={{ index .Values "rancherTurtles" "features" "agent-tls-mode" "enabled"}},ui-plugin={{ index .Values "turtlesUI" "enabled"}},embedded-operator={{ index .Values "rancherTurtles" "features" "embedded-operator" "enabled"}} + - --feature-gates=agent-tls-mode={{ index .Values "rancherTurtles" "features" "agent-tls-mode" "enabled"}},ui-plugin={{ index .Values "turtlesUI" "enabled"}} {{- range .Values.rancherTurtles.managerArguments }} - {{ . }} {{- end }} @@ -71,20 +71,16 @@ spec: requests: cpu: 10m memory: 128Mi - {{- if index .Values "rancherTurtles" "features" "embedded-operator" "enabled" }} {{- with .Values.rancherTurtles.volumeMounts.manager }} volumeMounts: {{- toYaml . | nindent 12 }} {{- end }} - {{- end }} serviceAccountName: rancher-turtles-manager terminationGracePeriodSeconds: 10 - {{- if index .Values "rancherTurtles" "features" "embedded-operator" "enabled" }} {{- with .Values.rancherTurtles.volumes }} volumes: {{- toYaml . | nindent 8 }} {{- end }} - {{- end }} tolerations: - effect: NoSchedule key: node-role.kubernetes.io/master diff --git a/charts/rancher-turtles/templates/operator-crds.yaml b/charts/rancher-turtles/templates/operator-crds.yaml index 2ba51c824..2e223cd9c 100644 --- a/charts/rancher-turtles/templates/operator-crds.yaml +++ b/charts/rancher-turtles/templates/operator-crds.yaml @@ -1,4 +1,3 @@ -{{- if index .Values "rancherTurtles" "features" "embedded-operator" "enabled" }} apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -21824,4 +21823,3 @@ rules: - '*' verbs: - '*' -{{- end }} diff --git a/charts/rancher-turtles/values.schema.json b/charts/rancher-turtles/values.schema.json index 627e36a86..405c5f114 100644 --- a/charts/rancher-turtles/values.schema.json +++ b/charts/rancher-turtles/values.schema.json @@ -128,17 +128,6 @@ } } }, - "embedded-operator": { - "type": "object", - "description": "Enable embedded operator controller loops.", - "properties": { - "enabled": { - "type": "boolean", - "default": false, - "description": "Turn on or off." - } - } - }, "clusterclass-operations": { "type": "object", "description": "Alpha feature. Not ready for testing yet.", @@ -220,139 +209,6 @@ "type": "object", "description": "Manages Cluster API components.", "properties": { - "enabled": { - "type": "boolean", - "default": true, - "description": "Turn on or off." - }, - "cert-manager": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": false, - "description": "Turn on or off." - } - } - }, - "volumes": { - "type": "array", - "description": "Volumes for operator pods (certs, config).", - "items": { - "type": "object", - "oneOf": [ - { - "required": ["name", "secret"], - "properties": { - "name": { "type": "string" }, - "secret": { - "type": "object", - "properties": { - "defaultMode": { - "type": "integer", - "default": 420, - "description": "File permissions." - }, - "secretName": { - "type": "string", - "default": "capi-operator-webhook-service-cert", - "description": "Secret for webhook certs." - } - } - } - } - }, - { - "required": ["name", "configMap"], - "properties": { - "name": { "type": "string" }, - "configMap": { - "type": "object", - "properties": { - "name": { - "type": "string", - "default": "clusterctl-config", - "description": "ConfigMap for clusterctl." - } - } - } - } - } - ] - } - }, - "image": { - "type": "object", - "properties": { - "manager": { - "type": "object", - "properties": { - "repository": { - "type": "string", - "default": "registry.rancher.com/rancher/cluster-api-operator", - "description": "Image repo." - } - } - } - } - }, - "volumeMounts": { - "type": "object", - "properties": { - "manager": { - "type": "array", - "description": "Mount volumes to pods.", - "items": { - "type": "object", - "properties": { - "mountPath": { "type": "string" }, - "name": { "type": "string" }, - "readOnly": { - "type": "boolean", - "default": true, - "description": "Mount as read-only." - } - } - } - } - } - }, - "resources": { - "type": "object", - "properties": { - "manager": { - "type": "object", - "properties": { - "limits": { - "type": "object", - "properties": { - "cpu": { - "type": "string", - "description": "CPU limit." - }, - "memory": { - "type": "string", - "description": "Memory limit." - } - } - }, - "requests": { - "type": "object", - "properties": { - "cpu": { - "type": "string", - "description": "CPU request." - }, - "memory": { - "type": "string", - "description": "Memory request." - } - } - } - } - } - } - }, "cleanup": { "type": "boolean", "default": true, diff --git a/charts/rancher-turtles/values.yaml b/charts/rancher-turtles/values.yaml index 963b93b77..e3b736d6b 100644 --- a/charts/rancher-turtles/values.yaml +++ b/charts/rancher-turtles/values.yaml @@ -25,10 +25,6 @@ rancherTurtles: kubectlImage: registry.k8s.io/kubernetes/kubectl:v1.30.0 # features: Optional and experimental features. features: - # embedded-operator: Embed operator controller loops. - embedded-operator: - # enabled: Turn on or off. - enabled: true # day2operations: Alpha feature. day2operations: # enabled: Turn on or off. @@ -70,48 +66,6 @@ rancherTurtles: # cluster-api-operator: Manages Cluster API components. cluster-api-operator: - # enabled: Turn on or off. - enabled: true - # cert-manager: Cert-manager integration. - cert-manager: - # enabled: Turn on or off. - enabled: false - # volumes: Volumes for operator pods (certs, config). - volumes: - - name: cert - secret: - # defaultMode: File permissions. - defaultMode: 420 - # secretName: Secret for webhook certs. - secretName: capi-operator-webhook-service-cert - - name: clusterctl-config - configMap: - # name: ConfigMap for clusterctl. - name: clusterctl-config - resources: - manager: - limits: - cpu: 100m - memory: 300Mi - requests: - cpu: 100m - memory: 100Mi - # image: Operator manager image. - image: - manager: - # repository: Image repo. - repository: registry.rancher.com/rancher/cluster-api-operator - # volumeMounts: Mount volumes to pods. - volumeMounts: - manager: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - # readOnly: Mount as read-only. - readOnly: true - - mountPath: /config - name: clusterctl-config - # readOnly: Mount as read-only. - readOnly: true # cleanup: Enable cleanup tasks. cleanup: true # cluster-api: Cluster API component settings. diff --git a/feature/feature.go b/feature/feature.go index b96faed71..e5e264e69 100644 --- a/feature/feature.go +++ b/feature/feature.go @@ -28,9 +28,6 @@ const ( // UIPlugin if enabled Turtles will install and manage UIPlugin resource for CAPI UI. UIPlugin featuregate.Feature = "ui-plugin" - - // EmbeddedOperator is enabled when Turtles will perform operator tasks for CAPI. - EmbeddedOperator featuregate.Feature = "embedded-operator" ) func init() { @@ -38,7 +35,6 @@ func init() { } var defaultGates = map[featuregate.Feature]featuregate.FeatureSpec{ - AgentTLSMode: {Default: true, PreRelease: featuregate.Beta}, - UIPlugin: {Default: false, PreRelease: featuregate.Alpha}, - EmbeddedOperator: {Default: true, PreRelease: featuregate.Beta}, + AgentTLSMode: {Default: true, PreRelease: featuregate.Beta}, + UIPlugin: {Default: false, PreRelease: featuregate.Alpha}, } diff --git a/main.go b/main.go index bded61e95..0e8054848 100644 --- a/main.go +++ b/main.go @@ -276,20 +276,18 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager) { setupLog.Info("enabling CAPI Operator synchronization controller") - if feature.Gates.Enabled(feature.EmbeddedOperator) { - if err := (&controllers.OperatorReconciler{}).SetupWithManager(ctx, mgr, controller.Options{ - MaxConcurrentReconciles: concurrencyNumber, - }); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Operator") - os.Exit(1) - } + if err := (&controllers.OperatorReconciler{}).SetupWithManager(ctx, mgr, controller.Options{ + MaxConcurrentReconciles: concurrencyNumber, + }); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Operator") + os.Exit(1) + } - if err := (&controllers.ProviderHealthCheckReconciler{}).SetupWithManager(mgr, controller.Options{ - MaxConcurrentReconciles: concurrencyNumber, - }); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Healthcheck") - os.Exit(1) - } + if err := (&controllers.ProviderHealthCheckReconciler{}).SetupWithManager(mgr, controller.Options{ + MaxConcurrentReconciles: concurrencyNumber, + }); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Healthcheck") + os.Exit(1) } if err := (&controllers.CAPIProviderReconciler{ diff --git a/scripts/turtles-dev.sh b/scripts/turtles-dev.sh index 99dc98c84..c321ba874 100755 --- a/scripts/turtles-dev.sh +++ b/scripts/turtles-dev.sh @@ -92,9 +92,7 @@ install_local_rancher_turtles_chart() { # feature flags enabled to run day2 & clusterclass controllers helm upgrade --install rancher-turtles out/charts/rancher-turtles \ -n rancher-turtles-system \ - --set cluster-api-operator.enabled=true \ --set cluster-api-operator.cluster-api.enabled=false \ - --set rancherTurtles.features.embedded-operator.enabled=true \ --set rancherTurtles.features.day2operations.enabled=true \ --set rancherTurtles.features.day2operations.imageVersion=dev \ --set rancherTurtles.features.day2operations.etcdBackupRestore.enabled=true \ diff --git a/test/e2e/suites/chart-upgrade/chart_upgrade_test.go b/test/e2e/suites/chart-upgrade/chart_upgrade_test.go index 1e956db6d..01487b572 100644 --- a/test/e2e/suites/chart-upgrade/chart_upgrade_test.go +++ b/test/e2e/suites/chart-upgrade/chart_upgrade_test.go @@ -59,10 +59,6 @@ var _ = Describe("Chart upgrade functionality should work", Label(e2e.ShortTestL testenv.DeployChartMuseum(ctx, chartMuseumDeployInput) - // Perform upgrade with migration to embedded operator implementation - rtInput.AdditionalValues["cluster-api-operator.enabled"] = "false" - rtInput.AdditionalValues["rancherTurtles.features.embedded-operator.enabled"] = "true" - upgradeInput := testenv.UpgradeRancherTurtlesInput{ BootstrapClusterProxy: bootstrapClusterProxy, AdditionalValues: rtInput.AdditionalValues, diff --git a/test/e2e/suites/etcd-snapshot-restore/suite_test.go b/test/e2e/suites/etcd-snapshot-restore/suite_test.go index 3cf778b16..34ff97e65 100644 --- a/test/e2e/suites/etcd-snapshot-restore/suite_test.go +++ b/test/e2e/suites/etcd-snapshot-restore/suite_test.go @@ -80,8 +80,6 @@ var _ = SynchronizedBeforeSuite( AdditionalValues: map[string]string{ "rancherTurtles.features.day2operations.enabled": "true", // enable day2operations feature "rancherTurtles.features.day2operations.etcdBackupRestore.enabled": "true", // enable etcdBackupRestore feature - "cluster-api-operator.enabled": "false", - "rancherTurtles.features.embedded-operator.enabled": "true", }, WaitForDeployments: testenv.DefaultDeployments, }) diff --git a/test/e2e/suites/import-gitops-v3/suite_test.go b/test/e2e/suites/import-gitops-v3/suite_test.go index 295236208..d805bd1a0 100644 --- a/test/e2e/suites/import-gitops-v3/suite_test.go +++ b/test/e2e/suites/import-gitops-v3/suite_test.go @@ -77,10 +77,7 @@ var _ = SynchronizedBeforeSuite( testenv.DeployRancherTurtles(ctx, testenv.DeployRancherTurtlesInput{ BootstrapClusterProxy: setupClusterResult.BootstrapClusterProxy, - AdditionalValues: map[string]string{ - "cluster-api-operator.enabled": "false", - "rancherTurtles.features.embedded-operator.enabled": "true", - }, + AdditionalValues: map[string]string{}, }) data, err := json.Marshal(e2e.Setup{ diff --git a/test/e2e/suites/v2prov/suite_test.go b/test/e2e/suites/v2prov/suite_test.go index 0a8db4bda..3a399435f 100644 --- a/test/e2e/suites/v2prov/suite_test.go +++ b/test/e2e/suites/v2prov/suite_test.go @@ -84,10 +84,7 @@ var _ = SynchronizedBeforeSuite( BootstrapClusterProxy: setupClusterResult.BootstrapClusterProxy, CAPIProvidersYAML: e2e.CapiProviders, WaitForDeployments: testenv.DefaultDeployments, - AdditionalValues: map[string]string{ - "cluster-api-operator.enabled": "false", - "rancherTurtles.features.embedded-operator.enabled": "true", - }, + AdditionalValues: map[string]string{}, }) testenv.RestartRancher(ctx, testenv.RestartRancherInput{