diff --git a/cmd/postgres-operator/main.go b/cmd/postgres-operator/main.go index 73a718f6f4..0fa41ba988 100644 --- a/cmd/postgres-operator/main.go +++ b/cmd/postgres-operator/main.go @@ -7,6 +7,7 @@ package main import ( "context" "fmt" + "github.com/percona/percona-postgresql-operator/percona/certmanager" "os" goruntime "runtime" "strconv" @@ -27,6 +28,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/manager" + certmanagerscheme "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned/scheme" "github.com/percona/percona-postgresql-operator/internal/controller/pgupgrade" "github.com/percona/percona-postgresql-operator/internal/controller/postgrescluster" "github.com/percona/percona-postgresql-operator/internal/controller/runtime" @@ -123,6 +125,10 @@ func main() { // Add Percona custom resource types to scheme assertNoError(v2.AddToScheme(mgr.GetScheme())) + // K8SPG-552 + // Add Scheme for cert-manager resources like Issuer and Certificate. + assertNoError(certmanagerscheme.AddToScheme(mgr.GetScheme())) + // add all PostgreSQL Operator controllers to the runtime manager err = addControllersToManager(ctx, mgr) assertNoError(err) @@ -148,11 +154,14 @@ func addControllersToManager(ctx context.Context, mgr manager.Manager) error { os.Setenv("REGISTRATION_REQUIRED", "false") r := &postgrescluster.Reconciler{ - Client: mgr.GetClient(), - Owner: postgrescluster.ControllerName, - Recorder: mgr.GetEventRecorderFor(postgrescluster.ControllerName), - Tracer: otel.Tracer(postgrescluster.ControllerName), - IsOpenShift: isOpenshift(ctx, mgr.GetConfig()), + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Owner: postgrescluster.ControllerName, + Recorder: mgr.GetEventRecorderFor(postgrescluster.ControllerName), + Tracer: otel.Tracer(postgrescluster.ControllerName), + IsOpenShift: isOpenshift(ctx, mgr.GetConfig()), + CertManagerCtrlFunc: certmanager.NewController, + RestConfig: mgr.GetConfig(), } cm := &perconaController.CustomManager{Manager: mgr} if err := r.SetupWithManager(cm); err != nil { diff --git a/config/bundle/kustomization.yaml b/config/bundle/kustomization.yaml index a803332017..924f145dc8 100644 --- a/config/bundle/kustomization.yaml +++ b/config/bundle/kustomization.yaml @@ -7,4 +7,4 @@ resources: images: - name: postgres-operator newName: perconalab/percona-postgresql-operator - newTag: main + newTag: K8SPG-552-5 diff --git a/config/cw-bundle/kustomization.yaml b/config/cw-bundle/kustomization.yaml index 164176a224..1c8d25d093 100644 --- a/config/cw-bundle/kustomization.yaml +++ b/config/cw-bundle/kustomization.yaml @@ -8,4 +8,4 @@ resources: images: - name: postgres-operator newName: perconalab/percona-postgresql-operator - newTag: main + newTag: K8SPG-552-5 diff --git a/config/manager/cluster/kustomization.yaml b/config/manager/cluster/kustomization.yaml index f5eedfb3e1..7bcbe02cbb 100644 --- a/config/manager/cluster/kustomization.yaml +++ b/config/manager/cluster/kustomization.yaml @@ -9,4 +9,4 @@ patchesStrategicMerge: images: - name: postgres-operator newName: perconalab/percona-postgresql-operator - newTag: main + newTag: K8SPG-552-5 diff --git a/config/manager/namespace/kustomization.yaml b/config/manager/namespace/kustomization.yaml index 721fe3093d..26e7f07f9a 100644 --- a/config/manager/namespace/kustomization.yaml +++ b/config/manager/namespace/kustomization.yaml @@ -10,4 +10,4 @@ patchesStrategicMerge: images: - name: postgres-operator newName: perconalab/percona-postgresql-operator - newTag: main + newTag: K8SPG-552-5 diff --git a/config/rbac/cluster/role.yaml b/config/rbac/cluster/role.yaml index 45467fc81c..65a185f7ee 100644 --- a/config/rbac/cluster/role.yaml +++ b/config/rbac/cluster/role.yaml @@ -83,6 +83,22 @@ rules: - patch - update - watch +- apiGroups: + - cert-manager.io + - certmanager.k8s.io + resources: + - certificaterequests + - certificates + - issuers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch - apiGroups: - coordination.k8s.io resources: diff --git a/config/rbac/namespace/role.yaml b/config/rbac/namespace/role.yaml index 316361007e..7b63d10641 100644 --- a/config/rbac/namespace/role.yaml +++ b/config/rbac/namespace/role.yaml @@ -83,6 +83,22 @@ rules: - patch - update - watch +- apiGroups: + - cert-manager.io + - certmanager.k8s.io + resources: + - certificaterequests + - certificates + - issuers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch - apiGroups: - coordination.k8s.io resources: diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index 5ec0a7101f..4fcb24ff8e 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -47414,6 +47414,22 @@ rules: - patch - update - watch +- apiGroups: + - cert-manager.io + - certmanager.k8s.io + resources: + - certificaterequests + - certificates + - issuers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch - apiGroups: - coordination.k8s.io resources: @@ -47640,7 +47656,7 @@ spec: value: "false" - name: PGO_WORKERS value: "1" - image: perconalab/percona-postgresql-operator:main + image: perconalab/percona-postgresql-operator:K8SPG-552-5 imagePullPolicy: Always livenessProbe: failureThreshold: 3 diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index 0e0dc91efb..d5e69ddac0 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -47414,6 +47414,22 @@ rules: - patch - update - watch +- apiGroups: + - cert-manager.io + - certmanager.k8s.io + resources: + - certificaterequests + - certificates + - issuers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch - apiGroups: - coordination.k8s.io resources: @@ -47638,7 +47654,7 @@ spec: value: "false" - name: PGO_WORKERS value: "1" - image: perconalab/percona-postgresql-operator:main + image: perconalab/percona-postgresql-operator:K8SPG-552-5 imagePullPolicy: Always livenessProbe: failureThreshold: 3 diff --git a/deploy/cw-operator.yaml b/deploy/cw-operator.yaml index 90232d8f7d..3b0f26ca57 100644 --- a/deploy/cw-operator.yaml +++ b/deploy/cw-operator.yaml @@ -44,7 +44,7 @@ spec: value: "false" - name: PGO_WORKERS value: "1" - image: perconalab/percona-postgresql-operator:main + image: perconalab/percona-postgresql-operator:K8SPG-552-5 imagePullPolicy: Always livenessProbe: failureThreshold: 3 diff --git a/deploy/cw-rbac.yaml b/deploy/cw-rbac.yaml index fb053043de..4fd524706b 100644 --- a/deploy/cw-rbac.yaml +++ b/deploy/cw-rbac.yaml @@ -87,6 +87,22 @@ rules: - patch - update - watch +- apiGroups: + - cert-manager.io + - certmanager.k8s.io + resources: + - certificaterequests + - certificates + - issuers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch - apiGroups: - coordination.k8s.io resources: diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 24e1f7081e..4ea59acabc 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -47,7 +47,7 @@ spec: value: "false" - name: PGO_WORKERS value: "1" - image: perconalab/percona-postgresql-operator:main + image: perconalab/percona-postgresql-operator:K8SPG-552-5 imagePullPolicy: Always livenessProbe: failureThreshold: 3 diff --git a/deploy/rbac.yaml b/deploy/rbac.yaml index 5d24b58335..34f259fd41 100644 --- a/deploy/rbac.yaml +++ b/deploy/rbac.yaml @@ -87,6 +87,22 @@ rules: - patch - update - watch +- apiGroups: + - cert-manager.io + - certmanager.k8s.io + resources: + - certificaterequests + - certificates + - issuers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch - apiGroups: - coordination.k8s.io resources: diff --git a/e2e-tests/functions b/e2e-tests/functions index 817c9233ca..077fbfc475 100644 --- a/e2e-tests/functions +++ b/e2e-tests/functions @@ -921,7 +921,7 @@ deploy_cert_manager() { echo 'deploy cert manager' kubectl create namespace cert-manager || : kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true || : - kubectl apply -f "https://github.com/jetstack/cert-manager/releases/download/v${CERT_MANAGER_VER}/cert-manager.yaml" --validate=false > /dev/null 2>&1 || : + kubectl apply -f "https://github.com/jetstack/cert-manager/releases/download/v1.17.1/cert-manager.yaml" --validate=false > /dev/null 2>&1 || : kubectl wait deployment cert-manager cert-manager-webhook cert-manager-cainjector \ --for=condition=available \ diff --git a/go.mod b/go.mod index a95b5c268e..5331b42cbe 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ toolchain go1.24.1 require ( github.com/Percona-Lab/percona-version-service v0.0.0-20230404081016-ea25e30cdcbc + github.com/cert-manager/cert-manager v1.18.2 github.com/go-logr/logr v1.4.3 github.com/go-openapi/errors v0.22.1 github.com/go-openapi/runtime v0.28.0 @@ -43,21 +44,27 @@ require ( ) require ( + github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.6 // indirect + github.com/go-ldap/ldap/v3 v3.4.8 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/google/btree v1.1.3 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/mod v0.26.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + sigs.k8s.io/gateway-api v1.1.0 // indirect sigs.k8s.io/randfill v1.0.0 // indirect ) @@ -69,7 +76,7 @@ require ( github.com/bool64/shared v0.1.5 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect @@ -85,7 +92,7 @@ require ( github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 github.com/iancoleman/orderedmap v0.3.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.9.0 // indirect @@ -132,7 +139,7 @@ require ( k8s.io/apiextensions-apiserver v0.33.2 k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + k8s.io/utils v0.0.0-20241210054802-24370beab758 + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect ) diff --git a/go.sum b/go.sum index 509d8047d6..4b09c29eed 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/Percona-Lab/percona-version-service v0.0.0-20230404081016-ea25e30cdcbc h1:aBpUepmWt8NsLH0fOA6vb8CCvIIJ4jMNxpvR36PaRSs= github.com/Percona-Lab/percona-version-service v0.0.0-20230404081016-ea25e30cdcbc/go.mod h1:dOzRkbUNd/qpn35nOSy60ZQBiP9wa9g1kh9kaMg/tOk= +github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= +github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -16,16 +20,19 @@ github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E= github.com/bool64/shared v0.1.5/go.mod h1:081yz68YC9jeFB3+Bbmno2RFWvGKv1lPKkMP6MHJlPs= github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cert-manager/cert-manager v1.18.2 h1:H2P75ycGcTMauV3gvpkDqLdS3RSXonWF2S49QGA1PZE= +github.com/cert-manager/cert-manager v1.18.2/go.mod h1:icDJx4kG9BCNpGjBvrmsFd99d+lXUvWdkkcrSSQdIiw= 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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= 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= @@ -34,6 +41,11 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.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-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-asn1-ber/asn1-ber v1.5.6 h1:CYsqysemXfEaQbyrLJmdsCRuufHoLa3P/gGWGl5TDrM= +github.com/go-asn1-ber/asn1-ber v1.5.6/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ= +github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk= 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= @@ -85,18 +97,37 @@ 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/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 h1:liMMTbpW34dhU4az1GN0pTPADwNmvoRSeoZ6PItiqnY= +github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -120,10 +151,10 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= @@ -170,20 +201,28 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ= @@ -249,19 +288,29 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= 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/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= 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-20200114155413-6afb5195e5aa/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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= @@ -270,6 +319,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -280,16 +330,27 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= 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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= @@ -299,6 +360,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn 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.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -350,12 +412,14 @@ k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= +k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM= +sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= diff --git a/internal/controller/postgrescluster/controller.go b/internal/controller/postgrescluster/controller.go index 12b806b5e0..50a16ef0e8 100644 --- a/internal/controller/postgrescluster/controller.go +++ b/internal/controller/postgrescluster/controller.go @@ -8,7 +8,9 @@ import ( "context" "errors" "fmt" + "github.com/percona/percona-postgresql-operator/percona/certmanager" "io" + "k8s.io/client-go/rest" "time" "go.opentelemetry.io/otel/trace" @@ -21,6 +23,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/client-go/discovery" "k8s.io/client-go/tools/record" @@ -58,6 +61,7 @@ const ( // Reconciler holds resources for the PostgresCluster reconciler type Reconciler struct { Client client.Client + Scheme *k8sruntime.Scheme DiscoveryClient *discovery.DiscoveryClient IsOpenShift bool Owner client.FieldOwner @@ -65,9 +69,11 @@ type Reconciler struct { ctx context.Context, namespace, pod, container string, stdin io.Reader, stdout, stderr io.Writer, command ...string, ) error - Recorder record.EventRecorder - Registration registration.Registration - Tracer trace.Tracer + Recorder record.EventRecorder + Registration registration.Registration + Tracer trace.Tracer + CertManagerCtrlFunc certmanager.NewControllerFunc + RestConfig *rest.Config } // +kubebuilder:rbac:groups="",resources="events",verbs={create,patch} diff --git a/internal/controller/postgrescluster/instance.go b/internal/controller/postgrescluster/instance.go index 079b1d2e4f..e731559f33 100644 --- a/internal/controller/postgrescluster/instance.go +++ b/internal/controller/postgrescluster/instance.go @@ -1448,7 +1448,7 @@ func (r *Reconciler) reconcileInstanceConfigMap( func (r *Reconciler) reconcileInstanceCertificates( ctx context.Context, cluster *v1beta1.PostgresCluster, spec *v1beta1.PostgresInstanceSetSpec, instance *appsv1.StatefulSet, - root *pki.RootCertificateAuthority, + rootCertificateAuth *pki.RootCertificateAuthority, ) (*corev1.Secret, error) { existing := &corev1.Secret{ObjectMeta: naming.InstanceCertificates(instance)} err := errors.WithStack(client.IgnoreNotFound( @@ -1486,16 +1486,16 @@ func (r *Reconciler) reconcileInstanceCertificates( var leafCert *pki.LeafCertificate if err == nil { - leafCert, err = r.instanceCertificate(ctx, instance, existing, instanceCerts, root) + leafCert, err = r.instanceCertificate(ctx, instance, existing, instanceCerts, rootCertificateAuth) } if err == nil { err = patroni.InstanceCertificates(ctx, - root.Certificate, leafCert.Certificate, + rootCertificateAuth.Certificate, leafCert.Certificate, leafCert.PrivateKey, instanceCerts) } if err == nil { err = pgbackrest.InstanceCertificates(ctx, cluster, - root.Certificate, leafCert.Certificate, leafCert.PrivateKey, + rootCertificateAuth.Certificate, leafCert.Certificate, leafCert.PrivateKey, instanceCerts) } if err == nil { diff --git a/internal/controller/postgrescluster/pki.go b/internal/controller/postgrescluster/pki.go index 8fad9f6da6..b0577244d4 100644 --- a/internal/controller/postgrescluster/pki.go +++ b/internal/controller/postgrescluster/pki.go @@ -6,6 +6,9 @@ package postgrescluster import ( "context" + "github.com/percona/percona-postgresql-operator/internal/logging" + "github.com/percona/percona-postgresql-operator/percona/certmanager" + logf "sigs.k8s.io/controller-runtime/pkg/log" gover "github.com/hashicorp/go-version" "github.com/pkg/errors" @@ -77,6 +80,14 @@ func (r *Reconciler) reconcileRootCertificate( } if k8serrors.IsNotFound(err) { err = nil + + certManagerSecret, certManagerErr := r.reconcileCertManagerRootCertificate(ctx, cluster) + if certManagerErr != nil { + return nil, certManagerErr + } + if certManagerSecret != nil { + existing = certManagerSecret + } } root := &pki.RootCertificateAuthority{} @@ -145,6 +156,35 @@ func (r *Reconciler) reconcileRootCertificate( return root, err } +// +kubebuilder:rbac:groups=certmanager.k8s.io,resources=issuers;certificates;certificaterequests,verbs=get;list;watch;create;update;patch;delete;deletecollection +// +kubebuilder:rbac:groups=cert-manager.io,resources=issuers;certificates;certificaterequests,verbs=get;list;watch;create;update;patch;delete;deletecollection + +// reconcileCertManagerRootCertificate func. +func (r *Reconciler) reconcileCertManagerRootCertificate( + ctx context.Context, cluster *v1beta1.PostgresCluster, +) (*corev1.Secret, error) { + log := logging.FromContext(ctx) + installed, err := r.isCertManagerInstalled(ctx, cluster.Namespace) + if err != nil { + return nil, errors.Wrap(err, "error checking if cert-manager is installed") + } + if !installed { + log.Info("cert-manager is not installed") + return nil, nil + } + c := r.CertManagerCtrlFunc(r.Client, r.Scheme, false) + err = c.ApplyCAIssuer(ctx, cluster) + if err != nil { + return nil, errors.Wrap(err, "error applying CA issuer") + } + err = c.ApplyCACertificate(ctx, cluster) + if err != nil { + return nil, errors.Wrap(err, "error applying CA certificate") + } + + return nil, nil +} + // +kubebuilder:rbac:groups="",resources="secrets",verbs={get} // +kubebuilder:rbac:groups="",resources="secrets",verbs={create,patch} @@ -169,6 +209,8 @@ func (r *Reconciler) reconcileClusterCertificate( return cluster.Spec.CustomTLSSecret, nil } + //r.reconcileCertManagerClusterCertificate(ctx, root, cluster, primaryService, replicaService) + const keyCertificate, keyPrivateKey, rootCA = "tls.crt", "tls.key", "ca.crt" existing := &corev1.Secret{ObjectMeta: naming.PostgresTLSSecret(cluster)} @@ -233,6 +275,68 @@ func (r *Reconciler) reconcileClusterCertificate( return clusterCertSecretProjection(intent), err } +func (r *Reconciler) reconcileCertManagerClusterCertificate( + ctx context.Context, root *pki.RootCertificateAuthority, + cluster *v1beta1.PostgresCluster, primaryService *corev1.Service, + replicaService *corev1.Service, +) ( + *corev1.SecretProjection, error, +) { + log := logging.FromContext(ctx) + exists, err := r.isCertManagerInstalled(ctx, cluster.Namespace) + if err != nil { + return nil, errors.Wrap(err, "failed to check if cert manager is installed") + } + if !exists { + log.Info("cert manager is not installed") + return nil, nil + } + + log.Info("reconciling cert manager cluster certificate") + + return r.createCertManagerClusterCertificate(ctx, root, cluster, primaryService, replicaService) +} + +func (r *Reconciler) isCertManagerInstalled(ctx context.Context, ns string) (bool, error) { + c := r.CertManagerCtrlFunc(r.Client, r.Scheme, true) + err := c.Check(ctx, r.RestConfig, ns) + if err != nil { + switch { + case errors.Is(err, certmanager.ErrCertManagerNotFound): + return false, nil + case errors.Is(err, certmanager.ErrCertManagerNotReady): + return true, nil + } + return false, err + } + return true, nil +} + +func (r *Reconciler) createCertManagerClusterCertificate( + ctx context.Context, root *pki.RootCertificateAuthority, + cluster *v1beta1.PostgresCluster, primaryService *corev1.Service, + replicaService *corev1.Service, +) (*corev1.SecretProjection, error) { + log := logf.FromContext(ctx).WithName("createCertManagerClusterCertificate") + + c := r.CertManagerCtrlFunc(r.Client, r.Scheme, false) + err := r.applyCertManagerCertificates(ctx, cluster, c) + if err != nil { + log.Error(err, "failed to reconcile cert manager cluster certificate") + return nil, err + } + return nil, nil +} + +func (r *Reconciler) applyCertManagerCertificates(ctx context.Context, cluster *v1beta1.PostgresCluster, controller certmanager.Controller) error { + err := controller.ApplyIssuer(ctx, cluster) + if err != nil { + return errors.Wrap(err, "failed to apply issuer") + } + + return nil +} + // +kubebuilder:rbac:groups="",resources="secrets",verbs={get} // +kubebuilder:rbac:groups="",resources="secrets",verbs={create,patch} diff --git a/internal/naming/names.go b/internal/naming/names.go index d5da45b024..7ba00ef509 100644 --- a/internal/naming/names.go +++ b/internal/naming/names.go @@ -614,3 +614,19 @@ func UpgradeCheckConfigMap() metav1.ObjectMeta { Name: "pgo-upgrade-check", } } + +// CAIssuer returns the ObjectMeta for the CA Issuer used by cert-manager. +func CAIssuer(cluster *v1beta1.PostgresCluster) metav1.ObjectMeta { + return metav1.ObjectMeta{ + Namespace: config.PGONamespace(), + Name: cluster.Name + "-ca-issuer", + } +} + +// TLSIssuer returns the ObjectMeta for the TLS Issuer used by cert-manager. +func TLSIssuer(cluster *v1beta1.PostgresCluster) metav1.ObjectMeta { + return metav1.ObjectMeta{ + Namespace: config.PGONamespace(), + Name: cluster.Name + "-tls-issuer", + } +} diff --git a/percona/certmanager/certmanager.go b/percona/certmanager/certmanager.go new file mode 100644 index 0000000000..263ecfaa28 --- /dev/null +++ b/percona/certmanager/certmanager.go @@ -0,0 +1,164 @@ +package certmanager + +import ( + "context" + v1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" + cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" + "github.com/percona/percona-postgresql-operator/internal/naming" + "github.com/percona/percona-postgresql-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "regexp" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "time" + + "github.com/cert-manager/cert-manager/pkg/util/cmapichecker" + "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +type Controller interface { + Check(ctx context.Context, config *rest.Config, ns string) error + ApplyIssuer(ctx context.Context, cluster *v1beta1.PostgresCluster) error + ApplyCAIssuer(ctx context.Context, cluster *v1beta1.PostgresCluster) error + ApplyCACertificate(ctx context.Context, cluster *v1beta1.PostgresCluster) error +} + +type controller struct { + cl client.Client + scheme *runtime.Scheme + dryRun bool +} + +var _ Controller = new(controller) + +type NewControllerFunc func(cl client.Client, scheme *runtime.Scheme, dryRun bool) Controller + +func NewController(cl client.Client, scheme *runtime.Scheme, dryRun bool) Controller { + if dryRun { + cl = client.NewDryRunClient(cl) + } + return &controller{ + cl: cl, + scheme: scheme, + dryRun: dryRun, + } +} + +var ( + ErrCertManagerNotFound = errors.New("cert-manager is not found") + ErrCertManagerNotReady = errors.New("cert-manager is not ready") +) + +func (c *controller) Check(ctx context.Context, config *rest.Config, ns string) error { + log := logf.FromContext(ctx) + checker, err := cmapichecker.New(config, ns) + if err != nil { + return err + } + err = checker.Check(ctx) + if err != nil { + switch err := translateCheckError(err); { + case errors.Is(err, cmapichecker.ErrCertManagerCRDsNotFound): + return ErrCertManagerNotFound + case errors.Is(err, cmapichecker.ErrWebhookCertificateFailure), errors.Is(err, cmapichecker.ErrWebhookServiceFailure), errors.Is(err, cmapichecker.ErrWebhookDeploymentFailure): + log.Error(cmapichecker.TranslateToSimpleError(err), "cert-manager is not ready") + return ErrCertManagerNotReady + } + return err + } + return nil +} + +func (c *controller) ApplyIssuer(ctx context.Context, cluster *v1beta1.PostgresCluster) error { + issuer := &v1.Issuer{ + ObjectMeta: naming.TLSIssuer(cluster), + Spec: v1.IssuerSpec{ + IssuerConfig: v1.IssuerConfig{ + CA: &v1.CAIssuer{ + SecretName: naming.PostgresRootCASecret(cluster).Name, + }, + }, + }, + } + + if err := controllerutil.SetControllerReference(cluster, issuer, c.scheme); err != nil { + return errors.Wrap(err, "failed to set controller reference") + } + + err := c.cl.Create(ctx, issuer) + if err != nil { + return err + } + + return nil +} + +// ApplyCAIssuer creates a SelfSigned Issuer resource for the given PostgresCluster. +func (c *controller) ApplyCAIssuer(ctx context.Context, cluster *v1beta1.PostgresCluster) error { + issuer := &v1.Issuer{ + ObjectMeta: naming.CAIssuer(cluster), + Spec: v1.IssuerSpec{ + IssuerConfig: v1.IssuerConfig{ + SelfSigned: &v1.SelfSignedIssuer{}, + }, + }, + } + + if err := controllerutil.SetControllerReference(cluster, issuer, c.scheme); err != nil { + return errors.Wrap(err, "failed to set controller reference") + } + + err := c.cl.Create(ctx, issuer) + if err != nil { + return errors.Wrap(err, "failed to create the issuer") + } + + return nil +} + +func (c *controller) ApplyCACertificate(ctx context.Context, cluster *v1beta1.PostgresCluster) error { + cert := &v1.Certificate{ + ObjectMeta: metav1.ObjectMeta{ + Name: naming.PostgresRootCASecret(cluster).Name, + Namespace: cluster.Namespace, + Labels: cluster.Labels, + }, + Spec: v1.CertificateSpec{ + SecretName: naming.PostgresRootCASecret(cluster).Name, + CommonName: cluster.Name + "-ca", + IsCA: true, + IssuerRef: cmmeta.ObjectReference{ + Name: naming.CAIssuer(cluster).Name, + Kind: v1.IssuerKind, + }, + Duration: &metav1.Duration{Duration: time.Hour * 24 * 365}, + RenewBefore: &metav1.Duration{Duration: 730 * time.Hour}, + }, + } + + if err := controllerutil.SetControllerReference(cluster, cert, c.scheme); err != nil { + return errors.Wrap(err, "failed to set controller reference") + } + + err := c.cl.Create(ctx, cert) + if err != nil { + return errors.Wrap(err, "failed to create the issuer") + } + + return nil +} + +func translateCheckError(err error) error { + const crdsMapping3Error = `error finding the scope of the object: failed to get restmapping: unable to retrieve the complete list of server APIs: cert-manager.io/v1: no matches for cert-manager.io/v1, Resource=` + // TODO: remove as soon as TranslateToSimpleError uses this regexp + regexErrCertManagerCRDsNotFound := regexp.MustCompile(`^(` + regexp.QuoteMeta(crdsMapping3Error) + `)$`) + + if regexErrCertManagerCRDsNotFound.MatchString(err.Error()) { + return cmapichecker.ErrCertManagerCRDsNotFound + } + + return cmapichecker.TranslateToSimpleError(err) +}