From 4ce5ccaada6b51fb8418fa26a35294c4eb9eac74 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Fri, 20 Dec 2024 11:10:09 -0500 Subject: [PATCH 1/7] fix(tls): use fixed-length cert CommonNames (#968) * fix(tls): use fixed-length cert CommonNames * certificate change recreation * delete cert secret so they are also recreated --- ...yostat-operator.clusterserviceversion.yaml | 2 +- internal/controllers/certmanager.go | 25 +++++++- .../resource_definitions/certificates.go | 11 ++-- internal/controllers/constants/constants.go | 6 ++ internal/controllers/reconciler_test.go | 60 +++++++++++++++++++ internal/test/resources.go | 35 +++++++++-- 6 files changed, 125 insertions(+), 14 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 9aa268346..297b82986 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -30,7 +30,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:4.0.0-dev - createdAt: "2024-10-10T18:16:26Z" + createdAt: "2024-11-05T19:02:47Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/internal/controllers/certmanager.go b/internal/controllers/certmanager.go index 35df44c10..9305c77ed 100644 --- a/internal/controllers/certmanager.go +++ b/internal/controllers/certmanager.go @@ -24,6 +24,7 @@ import ( "github.com/cryostatio/cryostat-operator/internal/controllers/common" resources "github.com/cryostatio/cryostat-operator/internal/controllers/common/resource_definitions" "github.com/cryostatio/cryostat-operator/internal/controllers/model" + "github.com/google/go-cmp/cmp" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" @@ -398,25 +399,43 @@ func (r *Reconciler) reconcileAgentCertificate(ctx context.Context, cert *certv1 return nil } +var errCertificateModified error = errors.New("certificate has been modified") + func (r *Reconciler) createOrUpdateCertificate(ctx context.Context, cert *certv1.Certificate, owner metav1.Object) error { - certSpec := cert.Spec.DeepCopy() + certCopy := cert.DeepCopy() op, err := controllerutil.CreateOrUpdate(ctx, r.Client, cert, func() error { if owner != nil { if err := controllerutil.SetControllerReference(owner, cert, r.Scheme); err != nil { return err } } - // Update Certificate spec - cert.Spec = *certSpec + + if cert.CreationTimestamp.IsZero() { + cert.Spec = certCopy.Spec + } else if !cmp.Equal(cert.Spec, certCopy.Spec) { + return errCertificateModified + } + return nil }) if err != nil { + if err == errCertificateModified { + return r.recreateCertificate(ctx, certCopy, owner) + } return err } r.Log.Info(fmt.Sprintf("Certificate %s", op), "name", cert.Name, "namespace", cert.Namespace) return nil } +func (r *Reconciler) recreateCertificate(ctx context.Context, cert *certv1.Certificate, owner metav1.Object) error { + err := r.deleteCertWithSecret(ctx, cert) + if err != nil { + return err + } + return r.createOrUpdateCertificate(ctx, cert, owner) +} + func newKeystoreSecret(cr *model.CryostatInstance) *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ diff --git a/internal/controllers/common/resource_definitions/certificates.go b/internal/controllers/common/resource_definitions/certificates.go index be757c748..55bf76453 100644 --- a/internal/controllers/common/resource_definitions/certificates.go +++ b/internal/controllers/common/resource_definitions/certificates.go @@ -20,6 +20,7 @@ import ( certv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" certMeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" "github.com/cryostatio/cryostat-operator/internal/controllers/common" + "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/controllers/model" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -62,7 +63,7 @@ func NewCryostatCACert(gvk *schema.GroupVersionKind, cr *model.CryostatInstance) Namespace: cr.InstallNamespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf("ca.%s.cert-manager", cr.Name), + CommonName: constants.CryostatCATLSCommonName, SecretName: common.ClusterUniqueNameWithPrefix(gvk, "ca", cr.Name, cr.InstallNamespace), IssuerRef: certMeta.ObjectReference{ Name: cr.Name + "-self-signed", @@ -79,7 +80,7 @@ func NewCryostatCert(cr *model.CryostatInstance, keystoreSecretName string) *cer Namespace: cr.InstallNamespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf("%s.%s.svc", cr.Name, cr.InstallNamespace), + CommonName: constants.CryostatTLSCommonName, DNSNames: []string{ cr.Name, fmt.Sprintf("%s.%s.svc", cr.Name, cr.InstallNamespace), @@ -115,7 +116,7 @@ func NewReportsCert(cr *model.CryostatInstance) *certv1.Certificate { Namespace: cr.InstallNamespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf("%s-reports.%s.svc", cr.Name, cr.InstallNamespace), + CommonName: constants.ReportsTLSCommonName, DNSNames: []string{ cr.Name + "-reports", fmt.Sprintf("%s-reports.%s.svc", cr.Name, cr.InstallNamespace), @@ -140,7 +141,7 @@ func NewAgentCert(cr *model.CryostatInstance, namespace string, gvk *schema.Grou Namespace: cr.InstallNamespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf("*.%s.pod", namespace), + CommonName: constants.AgentsTLSCommonName, DNSNames: []string{ fmt.Sprintf("*.%s.pod", namespace), }, @@ -163,7 +164,7 @@ func NewAgentProxyCert(cr *model.CryostatInstance) *certv1.Certificate { Namespace: cr.InstallNamespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf("%s-agent.%s.svc", cr.Name, cr.InstallNamespace), + CommonName: constants.AgentAuthProxyTLSCommonName, DNSNames: []string{ cr.Name + "-agent", fmt.Sprintf("%s-agent.%s.svc", cr.Name, cr.InstallNamespace), diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index 59b7bd9b2..5b3b26ec0 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -50,4 +50,10 @@ const ( targetNamespaceCRLabelPrefix = "operator.cryostat.io/" TargetNamespaceCRNameLabel = targetNamespaceCRLabelPrefix + "name" TargetNamespaceCRNamespaceLabel = targetNamespaceCRLabelPrefix + "namespace" + + CryostatCATLSCommonName = "cryostat-ca-cert-manager" + CryostatTLSCommonName = "cryostat" + ReportsTLSCommonName = "cryostat-reports" + AgentsTLSCommonName = "cryostat-agent" + AgentAuthProxyTLSCommonName = "cryostat-agent-proxy" ) diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 612c69f4e..40a71f33f 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -1795,6 +1795,66 @@ func (c *controllerTest) commonTests() { t.expectCertificates() }) }) + Context("with modified certificates", func() { + var oldCerts []*certv1.Certificate + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostat().Object, t.OtherCAIssuer()) + oldCerts = []*certv1.Certificate{ + t.OtherCACert(), + t.OtherAgentProxyCert(), + t.OtherCryostatCert(), + t.OtherReportsCert(), + } + // Add an annotation for each cert, the test will assert that + // the annotation is gone. + for i, cert := range oldCerts { + metav1.SetMetaDataAnnotation(&oldCerts[i].ObjectMeta, "bad", "cert") + t.objs = append(t.objs, cert) + } + }) + JustBeforeEach(func() { + cr := t.getCryostatInstance() + for _, cert := range oldCerts { + // Make the old certs owned by the Cryostat CR + err := controllerutil.SetControllerReference(cr.Object, cert, t.Client.Scheme()) + Expect(err).ToNot(HaveOccurred()) + err = t.Client.Update(context.Background(), cert) + Expect(err).ToNot(HaveOccurred()) + } + t.reconcileCryostatFully() + }) + It("should recreate certificates", func() { + t.expectCertificates() + }) + }) + Context("with a modified certificate TLS CommonName", func() { + var oldCerts []*certv1.Certificate + BeforeEach(func() { + oldCerts = []*certv1.Certificate{ + t.NewCryostatCert(), + t.NewReportsCert(), + t.NewAgentProxyCert(), + } + t.objs = append(t.objs, t.NewCryostat().Object, t.OtherCAIssuer()) + for _, cert := range oldCerts { + t.objs = append(t.objs, cert) + } + }) + JustBeforeEach(func() { + cr := t.getCryostatInstance() + for _, cert := range oldCerts { + // Make the old certs owned by the Cryostat CR + err := controllerutil.SetControllerReference(cr.Object, cert, t.Client.Scheme()) + Expect(err).ToNot(HaveOccurred()) + err = t.Client.Update(context.Background(), cert) + Expect(err).ToNot(HaveOccurred()) + } + t.reconcileCryostatFully() + }) + It("should recreate certificates", func() { + t.expectCertificates() + }) + }) Context("reconciling a multi-namespace request", func() { targetNamespaces := []string{"multi-test-one", "multi-test-two"} diff --git a/internal/test/resources.go b/internal/test/resources.go index bc74bc9fe..6c1adf3d2 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1053,7 +1053,7 @@ func (r *TestResources) NewCryostatCert() *certv1.Certificate { Namespace: r.Namespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf(r.Name+".%s.svc", r.Namespace), + CommonName: "cryostat", DNSNames: []string{ r.Name, fmt.Sprintf(r.Name+".%s.svc", r.Namespace), @@ -1084,6 +1084,12 @@ func (r *TestResources) NewCryostatCert() *certv1.Certificate { } } +func (r *TestResources) OtherCryostatCert() *certv1.Certificate { + cert := r.NewCryostatCert() + cert.Spec.CommonName = fmt.Sprintf("%s.%s.svc", r.Name, r.Namespace) + return cert +} + func (r *TestResources) NewReportsCert() *certv1.Certificate { return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ @@ -1091,7 +1097,7 @@ func (r *TestResources) NewReportsCert() *certv1.Certificate { Namespace: r.Namespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf(r.Name+"-reports.%s.svc", r.Namespace), + CommonName: "cryostat-reports", DNSNames: []string{ r.Name + "-reports", fmt.Sprintf(r.Name+"-reports.%s.svc", r.Namespace), @@ -1110,6 +1116,12 @@ func (r *TestResources) NewReportsCert() *certv1.Certificate { } } +func (r *TestResources) OtherReportsCert() *certv1.Certificate { + cert := r.NewReportsCert() + cert.Spec.CommonName = fmt.Sprintf("%s-reports.%s.svc", r.Name, r.Namespace) + return cert +} + func (r *TestResources) NewAgentProxyCert() *certv1.Certificate { return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ @@ -1117,7 +1129,7 @@ func (r *TestResources) NewAgentProxyCert() *certv1.Certificate { Namespace: r.Namespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf(r.Name+"-agent.%s.svc", r.Namespace), + CommonName: "cryostat-agent-proxy", DNSNames: []string{ r.Name + "-agent", fmt.Sprintf(r.Name+"-agent.%s.svc", r.Namespace), @@ -1136,6 +1148,12 @@ func (r *TestResources) NewAgentProxyCert() *certv1.Certificate { } } +func (r *TestResources) OtherAgentProxyCert() *certv1.Certificate { + cert := r.NewAgentProxyCert() + cert.Spec.CommonName = fmt.Sprintf("%s-agent.%s.svc", r.Name, r.Namespace) + return cert +} + func (r *TestResources) NewCACert() *certv1.Certificate { return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ @@ -1143,7 +1161,7 @@ func (r *TestResources) NewCACert() *certv1.Certificate { Namespace: r.Namespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf("ca.%s.cert-manager", r.Name), + CommonName: "cryostat-ca-cert-manager", SecretName: r.getClusterUniqueNameForCA(), IssuerRef: certMeta.ObjectReference{ Name: r.Name + "-self-signed", @@ -1153,6 +1171,13 @@ func (r *TestResources) NewCACert() *certv1.Certificate { } } +func (r *TestResources) OtherCACert() *certv1.Certificate { + cert := r.NewCACert() + cert.Spec.CommonName = fmt.Sprintf("ca.%s.cert-manager", r.Name) + cert.Spec.SecretName = r.Name + "-ca" + return cert +} + func (r *TestResources) NewAgentCert(namespace string) *certv1.Certificate { name := r.getClusterUniqueNameForAgent(namespace) return &certv1.Certificate{ @@ -1161,7 +1186,7 @@ func (r *TestResources) NewAgentCert(namespace string) *certv1.Certificate { Namespace: r.Namespace, }, Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf("*.%s.pod", namespace), + CommonName: "cryostat-agent", DNSNames: []string{ fmt.Sprintf("*.%s.pod", namespace), }, From ae41d039dabf1a49013e83b682470f0e8547244b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:45:21 -0500 Subject: [PATCH 2/7] build(deps): bump github.com/cert-manager/cert-manager from 1.13.6 to 1.15.4 (#972) * build(deps): bump github.com/cert-manager/cert-manager Bumps [github.com/cert-manager/cert-manager](https://github.com/cert-manager/cert-manager) from 1.13.6 to 1.15.4. - [Release notes](https://github.com/cert-manager/cert-manager/releases) - [Changelog](https://github.com/cert-manager/cert-manager/blob/master/RELEASE.md) - [Commits](https://github.com/cert-manager/cert-manager/compare/v1.13.6...v1.15.4) --- updated-dependencies: - dependency-name: github.com/cert-manager/cert-manager dependency-type: direct:production ... Signed-off-by: dependabot[bot] * Fix build failure, sync deps * Update README * Update cert-manager in Makefile --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Elliott Baron --- Makefile | 2 +- README.md | 2 +- ...yostat-operator.clusterserviceversion.yaml | 2 +- .../operator.cryostat.io_cryostats.yaml | 1258 +++++++++++++++-- bundle/tests/scorecard/config.yaml | 12 +- .../bases/operator.cryostat.io_cryostats.yaml | 1258 +++++++++++++++-- config/scorecard/patches/custom.config.yaml | 12 +- go.mod | 83 +- go.sum | 213 ++- internal/test/resources.go | 10 +- internal/test/scorecard/common_utils.go | 2 +- 11 files changed, 2476 insertions(+), 378 deletions(-) diff --git a/Makefile b/Makefile index 5d9d34fc2..59701bf94 100644 --- a/Makefile +++ b/Makefile @@ -98,7 +98,7 @@ AGENT_PROXY_NAME ?= nginx-124 AGENT_PROXY_VERSION ?= latest export AGENT_PROXY_IMG = $(AGENT_PROXY_NAMESPACE)/$(AGENT_PROXY_NAME):$(AGENT_PROXY_VERSION) -CERT_MANAGER_VERSION ?= 1.11.5 +CERT_MANAGER_VERSION ?= 1.12.14 CERT_MANAGER_MANIFEST ?= \ https://github.com/cert-manager/cert-manager/releases/download/v$(CERT_MANAGER_VERSION)/cert-manager.yaml diff --git a/README.md b/README.md index d1dfbe7f0..795dfdecb 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ eyJhbGciOiJSUzI1NiIsImtpZCI6IkhYZC13eDdGVGwyQzdGNVpZVndScEZ2VmRxWTlzbnBUUG9HRkJp ## BUILDING ### Requirements -- `go` v1.21+ +- `go` v1.22+ - [`operator-sdk`](https://github.com/operator-framework/operator-sdk) v1.31.0 - `podman` or `docker` - [`jq`](https://stedolan.github.io/jq/) v1.6+ diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 297b82986..b6fd0997f 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -30,7 +30,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:4.0.0-dev - createdAt: "2024-11-05T19:02:47Z" + createdAt: "2024-12-20T16:25:35Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 5eceac388..33019160f 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -1191,11 +1191,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -1223,11 +1225,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -1241,6 +1245,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -1285,11 +1290,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -1317,14 +1324,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -1355,8 +1365,9 @@ spec: associated with the corresponding weight. properties: labelSelector: - description: A label query over a set of - resources, in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -1386,11 +1397,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1401,6 +1414,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -1437,11 +1480,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1461,6 +1506,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -1483,6 +1529,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -1502,8 +1549,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -1532,11 +1580,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1547,6 +1597,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -1582,11 +1662,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1606,6 +1688,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -1618,6 +1701,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: 'Pod anti-affinity scheduling rules for a @@ -1644,8 +1728,9 @@ spec: associated with the corresponding weight. properties: labelSelector: - description: A label query over a set of - resources, in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -1675,11 +1760,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1690,6 +1777,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -1726,11 +1843,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1750,6 +1869,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -1772,6 +1892,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -1791,8 +1912,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -1821,11 +1943,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1836,6 +1960,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -1871,11 +2025,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1895,6 +2051,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -1907,6 +2064,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object nodeSelector: @@ -1964,6 +2122,29 @@ spec: description: Security Context to apply to the Cryostat report generator pod. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -2083,6 +2264,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -2103,6 +2285,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -2150,6 +2333,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -2163,6 +2370,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -2170,6 +2378,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -2540,11 +2749,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -2572,11 +2783,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -2589,6 +2802,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -2633,11 +2847,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -2665,14 +2881,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -2703,8 +2922,9 @@ spec: with the corresponding weight. properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -2733,11 +2953,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2748,6 +2970,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -2783,11 +3035,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2807,6 +3061,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -2829,6 +3084,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -2848,8 +3104,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label @@ -2878,11 +3135,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2893,6 +3152,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -2928,11 +3217,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2952,6 +3243,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -2964,6 +3256,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: 'Pod anti-affinity scheduling rules for a Cryostat @@ -2990,8 +3283,9 @@ spec: with the corresponding weight. properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -3020,11 +3314,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3035,6 +3331,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -3070,11 +3396,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3094,6 +3422,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -3116,6 +3445,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -3135,8 +3465,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label @@ -3165,11 +3496,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3180,6 +3513,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -3215,11 +3578,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3239,6 +3604,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -3251,6 +3617,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object nodeSelector: @@ -3318,6 +3685,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -3331,6 +3722,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -3338,6 +3730,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -3486,6 +3879,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -3499,6 +3916,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -3506,6 +3924,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -3653,6 +4072,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -3666,6 +4109,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -3673,6 +4117,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -3820,6 +4265,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -3833,6 +4302,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -3840,6 +4310,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -3977,6 +4448,29 @@ spec: podSecurityContext: description: Security Context to apply to the Cryostat pod. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -4096,6 +4590,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -4115,6 +4610,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -4161,6 +4657,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -4174,6 +4694,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -4181,6 +4702,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -4498,6 +5020,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -4582,34 +5105,6 @@ spec: status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -4665,11 +5160,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -4685,6 +5182,21 @@ spec: storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string volumeMode: description: |- volumeMode defines what type of volume is required by the claim. @@ -5446,11 +5958,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -5478,11 +5992,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -5496,6 +6012,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -5540,11 +6057,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -5572,14 +6091,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -5610,8 +6132,9 @@ spec: associated with the corresponding weight. properties: labelSelector: - description: A label query over a set of - resources, in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -5641,11 +6164,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5656,6 +6181,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -5692,11 +6247,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5716,6 +6273,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -5738,6 +6296,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -5757,8 +6316,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -5787,11 +6347,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5802,10 +6364,40 @@ spec: type: object type: object x-kubernetes-map-type: atomic - namespaceSelector: + matchLabelKeys: description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. @@ -5837,11 +6429,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5861,6 +6455,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -5873,6 +6468,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: 'Pod anti-affinity scheduling rules for a @@ -5899,8 +6495,9 @@ spec: associated with the corresponding weight. properties: labelSelector: - description: A label query over a set of - resources, in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -5930,11 +6527,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5945,6 +6544,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -5981,11 +6610,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -6005,6 +6636,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -6027,6 +6659,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -6046,8 +6679,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -6076,11 +6710,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -6091,6 +6727,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -6126,11 +6792,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -6150,6 +6818,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -6162,6 +6831,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object nodeSelector: @@ -6219,6 +6889,29 @@ spec: description: Security Context to apply to the Cryostat report generator pod. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -6338,6 +7031,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -6358,6 +7052,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -6405,6 +7100,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -6418,6 +7137,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -6425,6 +7145,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7015,11 +7736,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -7047,11 +7770,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -7064,6 +7789,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -7108,11 +7834,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -7140,14 +7868,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -7178,8 +7909,9 @@ spec: with the corresponding weight. properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -7208,11 +7940,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7223,6 +7957,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -7258,11 +8022,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7282,6 +8048,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -7304,6 +8071,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -7323,8 +8091,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label @@ -7353,11 +8122,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7368,6 +8139,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -7403,11 +8204,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7427,6 +8230,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -7439,6 +8243,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: 'Pod anti-affinity scheduling rules for a Cryostat @@ -7465,8 +8270,9 @@ spec: with the corresponding weight. properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -7495,11 +8301,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7510,6 +8318,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -7545,11 +8383,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7569,6 +8409,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -7591,6 +8432,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -7610,8 +8452,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label @@ -7640,11 +8483,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7655,6 +8500,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -7690,11 +8565,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7714,6 +8591,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -7726,6 +8604,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object nodeSelector: @@ -7792,6 +8671,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7805,6 +8708,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7812,6 +8716,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7959,6 +8864,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7972,6 +8901,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7979,6 +8909,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8127,6 +9058,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8140,6 +9095,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8147,6 +9103,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8295,6 +9252,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8308,6 +9289,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8315,6 +9297,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8462,6 +9445,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8475,6 +9482,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8482,6 +9490,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8629,6 +9638,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8642,6 +9675,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8649,6 +9683,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8786,6 +9821,29 @@ spec: podSecurityContext: description: Security Context to apply to the Cryostat pod. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -8905,6 +9963,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -8924,6 +9983,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -8970,6 +10030,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8983,6 +10067,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8990,6 +10075,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -9273,6 +10359,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -9357,34 +10444,6 @@ spec: status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -9440,11 +10499,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -9460,6 +10521,21 @@ spec: storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string volumeMode: description: |- volumeMode defines what type of volume is required by the claim. diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml index 73fd622e4..c0e18790f 100644 --- a/bundle/tests/scorecard/config.yaml +++ b/bundle/tests/scorecard/config.yaml @@ -70,7 +70,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - operator-install - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 labels: suite: cryostat test: cryostat-multi-namespace @@ -100,7 +100,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 labels: suite: cryostat test: cryostat-recording @@ -110,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 labels: suite: cryostat test: cryostat-config-change @@ -120,7 +120,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 labels: suite: cryostat test: cryostat-report diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 109b114f6..297248604 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -1178,11 +1178,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -1210,11 +1212,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -1228,6 +1232,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -1272,11 +1277,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -1304,14 +1311,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -1342,8 +1352,9 @@ spec: associated with the corresponding weight. properties: labelSelector: - description: A label query over a set of - resources, in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -1373,11 +1384,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1388,6 +1401,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -1424,11 +1467,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1448,6 +1493,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -1470,6 +1516,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -1489,8 +1536,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -1519,11 +1567,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1534,6 +1584,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -1569,11 +1649,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1593,6 +1675,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -1605,6 +1688,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: 'Pod anti-affinity scheduling rules for a @@ -1631,8 +1715,9 @@ spec: associated with the corresponding weight. properties: labelSelector: - description: A label query over a set of - resources, in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -1662,11 +1747,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1677,6 +1764,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -1713,11 +1830,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1737,6 +1856,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -1759,6 +1879,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -1778,8 +1899,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -1808,11 +1930,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1823,6 +1947,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -1858,11 +2012,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -1882,6 +2038,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -1894,6 +2051,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object nodeSelector: @@ -1951,6 +2109,29 @@ spec: description: Security Context to apply to the Cryostat report generator pod. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -2070,6 +2251,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -2090,6 +2272,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -2137,6 +2320,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -2150,6 +2357,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -2157,6 +2365,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -2527,11 +2736,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -2559,11 +2770,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -2576,6 +2789,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -2620,11 +2834,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -2652,14 +2868,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -2690,8 +2909,9 @@ spec: with the corresponding weight. properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -2720,11 +2940,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2735,6 +2957,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -2770,11 +3022,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2794,6 +3048,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -2816,6 +3071,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -2835,8 +3091,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label @@ -2865,11 +3122,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2880,6 +3139,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -2915,11 +3204,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2939,6 +3230,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -2951,6 +3243,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: 'Pod anti-affinity scheduling rules for a Cryostat @@ -2977,8 +3270,9 @@ spec: with the corresponding weight. properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -3007,11 +3301,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3022,6 +3318,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -3057,11 +3383,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3081,6 +3409,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -3103,6 +3432,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -3122,8 +3452,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label @@ -3152,11 +3483,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3167,6 +3500,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -3202,11 +3565,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3226,6 +3591,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -3238,6 +3604,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object nodeSelector: @@ -3305,6 +3672,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -3318,6 +3709,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -3325,6 +3717,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -3473,6 +3866,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -3486,6 +3903,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -3493,6 +3911,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -3640,6 +4059,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -3653,6 +4096,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -3660,6 +4104,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -3807,6 +4252,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -3820,6 +4289,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -3827,6 +4297,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -3964,6 +4435,29 @@ spec: podSecurityContext: description: Security Context to apply to the Cryostat pod. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -4083,6 +4577,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -4102,6 +4597,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -4148,6 +4644,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -4161,6 +4681,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -4168,6 +4689,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -4485,6 +5007,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -4569,34 +5092,6 @@ spec: status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -4652,11 +5147,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -4672,6 +5169,21 @@ spec: storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string volumeMode: description: |- volumeMode defines what type of volume is required by the claim. @@ -5433,11 +5945,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -5465,11 +5979,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -5483,6 +5999,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -5527,11 +6044,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -5559,14 +6078,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -5597,8 +6119,9 @@ spec: associated with the corresponding weight. properties: labelSelector: - description: A label query over a set of - resources, in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -5628,11 +6151,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5643,6 +6168,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -5679,11 +6234,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5703,6 +6260,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -5725,6 +6283,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -5744,8 +6303,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -5774,11 +6334,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5789,10 +6351,40 @@ spec: type: object type: object x-kubernetes-map-type: atomic - namespaceSelector: + matchLabelKeys: description: |- - A label query over the set of namespaces that the term applies to. - The term is applied to the union of the namespaces selected by this field + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. @@ -5824,11 +6416,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5848,6 +6442,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -5860,6 +6455,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: 'Pod anti-affinity scheduling rules for a @@ -5886,8 +6482,9 @@ spec: associated with the corresponding weight. properties: labelSelector: - description: A label query over a set of - resources, in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -5917,11 +6514,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5932,6 +6531,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -5968,11 +6597,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5992,6 +6623,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -6014,6 +6646,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -6033,8 +6666,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -6063,11 +6697,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -6078,6 +6714,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -6113,11 +6779,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -6137,6 +6805,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -6149,6 +6818,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object nodeSelector: @@ -6206,6 +6876,29 @@ spec: description: Security Context to apply to the Cryostat report generator pod. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -6325,6 +7018,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -6345,6 +7039,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -6392,6 +7087,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -6405,6 +7124,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -6412,6 +7132,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7002,11 +7723,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -7034,11 +7757,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -7051,6 +7776,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -7095,11 +7821,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -7127,14 +7855,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -7165,8 +7896,9 @@ spec: with the corresponding weight. properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -7195,11 +7927,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7210,6 +7944,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -7245,11 +8009,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7269,6 +8035,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -7291,6 +8058,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -7310,8 +8078,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label @@ -7340,11 +8109,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7355,6 +8126,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -7390,11 +8191,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7414,6 +8217,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -7426,6 +8230,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: 'Pod anti-affinity scheduling rules for a Cryostat @@ -7452,8 +8257,9 @@ spec: with the corresponding weight. properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list @@ -7482,11 +8288,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7497,6 +8305,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -7532,11 +8370,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7556,6 +8396,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -7578,6 +8419,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -7597,8 +8439,9 @@ spec: a pod of the set of pods is running properties: labelSelector: - description: A label query over a set of resources, - in this case pods. + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. properties: matchExpressions: description: matchExpressions is a list of label @@ -7627,11 +8470,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7642,6 +8487,36 @@ spec: type: object type: object x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic namespaceSelector: description: |- A label query over the set of namespaces that the term applies to. @@ -7677,11 +8552,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7701,6 +8578,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -7713,6 +8591,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object nodeSelector: @@ -7779,6 +8658,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7792,6 +8695,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7799,6 +8703,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7946,6 +8851,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7959,6 +8888,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7966,6 +8896,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8114,6 +9045,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8127,6 +9082,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8134,6 +9090,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8282,6 +9239,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8295,6 +9276,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8302,6 +9284,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8449,6 +9432,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8462,6 +9469,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8469,6 +9477,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8616,6 +9625,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8629,6 +9662,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8636,6 +9670,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -8773,6 +9808,29 @@ spec: podSecurityContext: description: Security Context to apply to the Cryostat pod. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -8892,6 +9950,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -8911,6 +9970,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -8957,6 +10017,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -8970,6 +10054,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -8977,6 +10062,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -9260,6 +10346,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -9344,34 +10431,6 @@ spec: status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -9427,11 +10486,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -9447,6 +10508,21 @@ spec: storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string volumeMode: description: |- volumeMode defines what type of volume is required by the claim. diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index b68184f2e..7ce049f0d 100644 --- a/config/scorecard/patches/custom.config.yaml +++ b/config/scorecard/patches/custom.config.yaml @@ -8,7 +8,7 @@ entrypoint: - cryostat-scorecard-tests - operator-install - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" labels: suite: cryostat test: cryostat-multi-namespace @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" labels: suite: cryostat test: cryostat-recording @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" labels: suite: cryostat test: cryostat-config-change @@ -58,7 +58,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241004185220" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" labels: suite: cryostat test: cryostat-report diff --git a/go.mod b/go.mod index a84dd1161..e3f9d4903 100644 --- a/go.mod +++ b/go.mod @@ -1,35 +1,33 @@ module github.com/cryostatio/cryostat-operator -// Increment to go 1.22 once downstream is compatible -go 1.21 +go 1.22.0 require ( github.com/blang/semver/v4 v4.0.0 - github.com/cert-manager/cert-manager v1.13.6 + github.com/cert-manager/cert-manager v1.15.4 github.com/go-logr/logr v1.4.2 github.com/google/go-cmp v0.6.0 github.com/onsi/ginkgo/v2 v2.17.3 github.com/onsi/gomega v1.33.1 - github.com/openshift/api v0.0.0-20240228005710-4511c790cc60 // release-4.15 - github.com/operator-framework/api v0.22.0 - k8s.io/api v0.28.15 - k8s.io/apimachinery v0.28.15 - k8s.io/client-go v0.28.15 - sigs.k8s.io/controller-runtime v0.16.6 + github.com/openshift/api v0.0.0-20240912201240-0a8800162826 // release-4.17 + github.com/operator-framework/api v0.26.0 + k8s.io/api v0.30.8 + k8s.io/apimachinery v0.30.8 + k8s.io/client-go v0.30.8 + sigs.k8s.io/controller-runtime v0.18.6 ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // 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/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/zapr v1.2.4 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/emicklei/go-restful/v3 v3.12.0 // indirect + github.com/evanphx/json-patch v5.9.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // 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.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -37,47 +35,44 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/imdario/mergo v0.3.12 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/imdario/mergo v0.3.16 // 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/matttproud/golang_protobuf_extensions v1.0.4 // 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/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.47.0 // indirect + github.com/prometheus/procfs v0.15.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/oauth2 v0.12.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.20.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.28.9 // indirect - k8s.io/component-base v0.28.9 // indirect - k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230905202853-d090da108d2f // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - sigs.k8s.io/gateway-api v0.8.0 // indirect + k8s.io/apiextensions-apiserver v0.30.1 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + sigs.k8s.io/gateway-api v1.1.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) // Fix for CVE-2022-28948 diff --git a/go.sum b/go.sum index 223534548..388d5af20 100644 --- a/go.sum +++ b/go.sum @@ -1,47 +1,37 @@ -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/cert-manager/cert-manager v1.13.6 h1:yngKM4ZQoyFQ3LGHTx95fWqyiNJP11UM5PWq7pAr3T0= -github.com/cert-manager/cert-manager v1.13.6/go.mod h1:iWFePja8XKEl+Dv1kZtwPshT8D0SmC4Hyu5Qc5KS0tM= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cert-manager/cert-manager v1.15.4 h1:FtH6BOTmkNBNRjoYSW2b80MYpUq4Zw1zbEB6flYzkiM= +github.com/cert-manager/cert-manager v1.15.4/go.mod h1:stBge/DTvrhfQMB/93+Y62s+gQgZBsfL1o0C/4AL/mI= +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/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/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= +github.com/emicklei/go-restful/v3 v3.12.0/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.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +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/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= @@ -54,29 +44,22 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +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/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -88,151 +71,119 @@ github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= -github.com/openshift/api v0.0.0-20240228005710-4511c790cc60 h1:BfN2JThYjmpXhULHahY1heyfct+fsj4fhkUo3tVIGH4= -github.com/openshift/api v0.0.0-20240228005710-4511c790cc60/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU= -github.com/operator-framework/api v0.22.0 h1:UZSn+iaQih4rCReezOnWTTJkMyawwV5iLnIItaOzytY= -github.com/operator-framework/api v0.22.0/go.mod h1:p/7YDbr+n4fmESfZ47yLAV1SvkfE6NU2aX8KhcfI0GA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/openshift/api v0.0.0-20240912201240-0a8800162826 h1:A8D9SN/hJUwAbdO0rPCVTqmuBOctdgurr53gK701SYo= +github.com/openshift/api v0.0.0-20240912201240-0a8800162826/go.mod h1:OOh6Qopf21pSzqNVCB5gomomBXb8o5sGKZxG2KNpaXM= +github.com/operator-framework/api v0.26.0 h1:YVntU2NkVl5zSLLwK5kFcH6P3oSvN9QDgTsY9mb4yUM= +github.com/operator-framework/api v0.26.0/go.mod h1:3IxOwzVUeGxYlzfwKCcfCyS+q3EEhWA/4kv7UehbeyM= 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= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= +github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +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/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-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/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= 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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 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.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.28.15 h1:u+Sze8gI+DayQxndS0htiJf8yVooHyUx/H4jEehtmNs= -k8s.io/api v0.28.15/go.mod h1:SJuOJTphYG05iJC9UKnUTNkY84Mvveu1P7adCgWqjCg= -k8s.io/apiextensions-apiserver v0.28.9 h1:yzPHp+4IASHeu7XIPkAKJrY4UjWdjiAjOcQMd6oNKj0= -k8s.io/apiextensions-apiserver v0.28.9/go.mod h1:Rjhvq5y3JESdZgV2UOByldyefCfRrUguVpBLYOAIbVs= -k8s.io/apimachinery v0.28.15 h1:Jg15ZoCcAgnhSRKVS6tQyUZaX9c3i08bl2qAz8XE3bI= -k8s.io/apimachinery v0.28.15/go.mod h1:zUG757HaKs6Dc3iGtKjzIpBfqTM4yiRsEe3/E7NX15o= -k8s.io/client-go v0.28.15 h1:+g6Ub+i6tacV3tYJaoyK6bizpinPkamcEwsiKyHcIxc= -k8s.io/client-go v0.28.15/go.mod h1:/4upIpTbhWQVSXKDqTznjcAegj2Bx73mW/i0aennJrY= -k8s.io/component-base v0.28.9 h1:ySM2PR8Z/xaUSG1Akd3yM6dqUezTltI7S5aV41MMuuc= -k8s.io/component-base v0.28.9/go.mod h1:QtWzscEhCKRfHV24/S+11BwWjVxhC6fd3RYoEgZcWFU= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20230905202853-d090da108d2f h1:eeEUOoGYWhOz7EyXqhlR2zHKNw2mNJ9vzJmub6YN6kk= -k8s.io/kube-openapi v0.0.0-20230905202853-d090da108d2f/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.16.6 h1:FiXwTuFF5ZJKmozfP2Z0j7dh6kmxP4Ou1KLfxgKKC3I= -sigs.k8s.io/controller-runtime v0.16.6/go.mod h1:+dQzkZxnylD0u49e0a+7AR+vlibEBaThmPca7lTyUsI= -sigs.k8s.io/gateway-api v0.8.0 h1:isQQ3Jx2qFP7vaA3ls0846F0Amp9Eq14P08xbSwVbQg= -sigs.k8s.io/gateway-api v0.8.0/go.mod h1:okOnjPNBFbIS/Rw9kAhuIUaIkLhTKEu+ARIuXk2dgaM= +k8s.io/api v0.30.8 h1:Y+yZRF3c1WC0MTkLe0qBkiLCquRNa4I21/iDioGMCbo= +k8s.io/api v0.30.8/go.mod h1:89IE5MzirZ5HHxU/Hq1/KWGqXkhXClu/FHGesFhQ0A4= +k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= +k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= +k8s.io/apimachinery v0.30.8 h1:9jyTItYzmJc00cBDxZC5ArFNxUeKCwbw0m760iFUMKY= +k8s.io/apimachinery v0.30.8/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/client-go v0.30.8 h1:fC1SQMZm7bSWiVv9ydN+nv+sqGVAxMdf/5eKUVffNJE= +k8s.io/client-go v0.30.8/go.mod h1:daF3UcGVqGPHvH5mn/ESkp/VoR8i9tg9IBfKr+AeFYo= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f h1:0LQagt0gDpKqvIkAMPaRGcXawNMouPECM1+F9BVxEaM= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f/go.mod h1:S9tOR0FxgyusSNR+MboCuiDpVWkAifZvaYI1Q2ubgro= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.18.6 h1:UnEoLBLDpQwzJ2jYh6aTdiMhGjNDR7IdFn9YEqHIccc= +sigs.k8s.io/controller-runtime v0.18.6/go.mod h1:Dcsa9v8AEBWa3sQNJHsuWPT4ICv99irl5wj83NiC12U= +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-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= -sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/test/resources.go b/internal/test/resources.go index 6c1adf3d2..c482e61f2 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -592,7 +592,7 @@ func newPVCSpec(storageClass string, storageRequest string, return &corev1.PersistentVolumeClaimSpec{ StorageClassName: &storageClass, AccessModes: accessModes, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse(storageRequest), }, @@ -1266,7 +1266,7 @@ func (r *TestResources) newPVC(spec *corev1.PersistentVolumeClaimSpec, labels ma func (r *TestResources) NewDefaultPVC() *corev1.PersistentVolumeClaim { return r.newPVC(&corev1.PersistentVolumeClaimSpec{ AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse("500Mi"), }, @@ -1281,7 +1281,7 @@ func (r *TestResources) NewCustomPVC() *corev1.PersistentVolumeClaim { return r.newPVC(&corev1.PersistentVolumeClaimSpec{ StorageClassName: &storageClass, AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteMany}, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse("10Gi"), }, @@ -1299,7 +1299,7 @@ func (r *TestResources) NewCustomPVCSomeDefault() *corev1.PersistentVolumeClaim return r.newPVC(&corev1.PersistentVolumeClaimSpec{ StorageClassName: &storageClass, AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse("1Gi"), }, @@ -1312,7 +1312,7 @@ func (r *TestResources) NewCustomPVCSomeDefault() *corev1.PersistentVolumeClaim func (r *TestResources) NewDefaultPVCWithLabel() *corev1.PersistentVolumeClaim { return r.newPVC(&corev1.PersistentVolumeClaimSpec{ AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse("500Mi"), }, diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index 1ee9ecc93..377f0ea7d 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -527,7 +527,7 @@ func (r *TestResources) updateStorageOptions(ctx context.Context, cr *operatorv1 PVC: &operatorv1beta2.PersistentVolumeClaimConfig{ Spec: &corev1.PersistentVolumeClaimSpec{ StorageClassName: nil, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse("1Gi"), }, From 4360c3040f52ed6d8b9ed628b3783398e8e1f825 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Tue, 7 Jan 2025 12:22:05 -0500 Subject: [PATCH 3/7] ci(criu): add CRIU PPA for Podman dependency (#998) --- .github/workflows/build-ci.yml | 12 ++++++++---- .github/workflows/test-ci-reusable.yml | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index b16417c91..e91107ee6 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -29,12 +29,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Add CRIU PPA + run: sudo add-apt-repository ppa:criu/ppa && sudo apt update - name: Install podman v4 run: | echo "deb $OPENSUSE_UNOFFICIAL_LIBCONTAINERS_SOURCE_URL/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list curl -fsSL $OPENSUSE_UNOFFICIAL_LIBCONTAINERS_KEY_URL | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/devel_kubic_libcontainers_unstable.gpg > /dev/null - sudo apt update - sudo apt install podman + sudo apt -y update + sudo apt -y satisfy "podman (>= 4.0)" - name: Build operator image run: | IMAGE_NAMESPACE=${{ env.CI_REGISTRY }} SKIP_TESTS=true PLATFORMS=${{ env.CI_PLATFORMS }} MANIFEST_PUSH=false make oci-buildx @@ -116,12 +118,14 @@ jobs: fi echo "${CI_SCORECARD_IMG}:${{ steps.get-image-tag.outputs.tag }} exists: $EXIST" echo "exist=$EXIST" >> $GITHUB_OUTPUT + - name: Add CRIU PPA + run: sudo add-apt-repository ppa:criu/ppa && sudo apt update - name: Install podman v4 run: | echo "deb $OPENSUSE_UNOFFICIAL_LIBCONTAINERS_SOURCE_URL/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list curl -fsSL $OPENSUSE_UNOFFICIAL_LIBCONTAINERS_KEY_URL | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/devel_kubic_libcontainers_unstable.gpg > /dev/null - sudo apt update - sudo apt install podman + sudo apt -y update + sudo apt -y satisfy "podman (>= 4.0)" - name: Build scorecard image run: | CUSTOM_SCORECARD_IMG=${CI_SCORECARD_IMG}:${{ steps.get-image-tag.outputs.tag }} \ diff --git a/.github/workflows/test-ci-reusable.yml b/.github/workflows/test-ci-reusable.yml index 1566a5276..f762f8fcc 100644 --- a/.github/workflows/test-ci-reusable.yml +++ b/.github/workflows/test-ci-reusable.yml @@ -67,12 +67,14 @@ jobs: with: repository: ${{ inputs.repository }} ref: ${{ inputs.ref }} + - name: Add CRIU PPA + run: sudo add-apt-repository ppa:criu/ppa && sudo apt update - name: Install podman v4 run: | echo "deb $OPENSUSE_UNOFFICIAL_LIBCONTAINERS_SOURCE_URL/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list curl -fsSL $OPENSUSE_UNOFFICIAL_LIBCONTAINERS_KEY_URL | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/devel_kubic_libcontainers_unstable.gpg sudo apt -y update - sudo apt -y install podman + sudo apt -y satisfy "podman (>= 4.0)" - name: Build scorecard image for test run: | CUSTOM_SCORECARD_IMG=ghcr.io/${{ github.repository_owner }}/cryostat-operator-scorecard:${{ inputs.tag }} \ From 52fef0c7510ce129607b3bd44992c6cd27c7dea0 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Tue, 7 Jan 2025 14:10:38 -0500 Subject: [PATCH 4/7] build(oci): switch builder image to ubi9 go toolset (#997) --- Dockerfile | 5 ++--- .../cryostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 12 ++++++------ config/scorecard/patches/custom.config.yaml | 12 ++++++------ internal/images/custom-scorecard-tests/Dockerfile | 5 ++--- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/Dockerfile b/Dockerfile index e54f0c79b..c872524ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,8 @@ # Build the manager binary -FROM docker.io/library/golang:1.22 as builder +FROM registry.access.redhat.com/ubi9/go-toolset:1.22.9 as builder ARG TARGETOS ARG TARGETARCH -WORKDIR /workspace # Copy the Go Modules manifests COPY go.mod go.mod COPY go.sum go.sum @@ -26,7 +25,7 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} GO111MODULE=on go FROM registry.access.redhat.com/ubi8/ubi-minimal:latest WORKDIR / -COPY --from=builder /workspace/manager . +COPY --from=builder /opt/app-root/src/manager . USER 65532:65532 ENTRYPOINT ["/manager"] diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index b6fd0997f..cebc7894f 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -30,7 +30,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:4.0.0-dev - createdAt: "2024-12-20T16:25:35Z" + createdAt: "2025-01-07T17:50:16Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml index c0e18790f..1b76ea797 100644 --- a/bundle/tests/scorecard/config.yaml +++ b/bundle/tests/scorecard/config.yaml @@ -70,7 +70,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - operator-install - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 labels: suite: cryostat test: cryostat-multi-namespace @@ -100,7 +100,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 labels: suite: cryostat test: cryostat-recording @@ -110,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 labels: suite: cryostat test: cryostat-config-change @@ -120,7 +120,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 labels: suite: cryostat test: cryostat-report diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 7ce049f0d..d67447ed2 100644 --- a/config/scorecard/patches/custom.config.yaml +++ b/config/scorecard/patches/custom.config.yaml @@ -8,7 +8,7 @@ entrypoint: - cryostat-scorecard-tests - operator-install - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" labels: suite: cryostat test: cryostat-multi-namespace @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" labels: suite: cryostat test: cryostat-recording @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" labels: suite: cryostat test: cryostat-config-change @@ -58,7 +58,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20241220000429" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" labels: suite: cryostat test: cryostat-report diff --git a/internal/images/custom-scorecard-tests/Dockerfile b/internal/images/custom-scorecard-tests/Dockerfile index 0f9110bc5..f1d4ed6f0 100644 --- a/internal/images/custom-scorecard-tests/Dockerfile +++ b/internal/images/custom-scorecard-tests/Dockerfile @@ -13,11 +13,10 @@ # limitations under the License. # Build the manager binary -FROM docker.io/library/golang:1.22 as builder +FROM registry.access.redhat.com/ubi9/go-toolset:1.22.9 as builder ARG TARGETOS ARG TARGETARCH -WORKDIR /workspace # Copy the Go Modules manifests COPY go.mod go.mod COPY go.sum go.sum @@ -42,7 +41,7 @@ ENV TEST=/usr/local/bin/cryostat-scorecard-tests \ COPY internal/images/custom-scorecard-tests/bin/user_setup /usr/local/bin/ COPY internal/images/custom-scorecard-tests/bin/entrypoint /usr/local/bin/ -COPY --from=builder /workspace/cryostat-scorecard-tests /usr/local/bin/ +COPY --from=builder /opt/app-root/src/cryostat-scorecard-tests /usr/local/bin/ RUN /usr/local/bin/user_setup ENTRYPOINT ["/usr/local/bin/entrypoint"] From b834a8e793788c0240b46eac45336117412a6071 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Wed, 8 Jan 2025 09:52:47 -0500 Subject: [PATCH 5/7] chore(base): upgrade to UBI9 (#953) --- Dockerfile | 2 +- .../cryostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 12 ++++++------ config/scorecard/patches/custom.config.yaml | 12 ++++++------ internal/images/custom-scorecard-tests/Dockerfile | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index c872524ed..16f642660 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ COPY internal/webhooks/ internal/webhooks/ # by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} GO111MODULE=on go build -a -o manager internal/main.go -FROM registry.access.redhat.com/ubi8/ubi-minimal:latest +FROM registry.access.redhat.com/ubi9/ubi-minimal:latest WORKDIR / COPY --from=builder /opt/app-root/src/manager . USER 65532:65532 diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index cebc7894f..aa92d967b 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -30,7 +30,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:4.0.0-dev - createdAt: "2025-01-07T17:50:16Z" + createdAt: "2025-01-07T19:12:00Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml index 1b76ea797..4710aa0c8 100644 --- a/bundle/tests/scorecard/config.yaml +++ b/bundle/tests/scorecard/config.yaml @@ -70,7 +70,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - operator-install - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133 labels: suite: cryostat test: cryostat-multi-namespace @@ -100,7 +100,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133 labels: suite: cryostat test: cryostat-recording @@ -110,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133 labels: suite: cryostat test: cryostat-config-change @@ -120,7 +120,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133 labels: suite: cryostat test: cryostat-report diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index d67447ed2..0e7244dcb 100644 --- a/config/scorecard/patches/custom.config.yaml +++ b/config/scorecard/patches/custom.config.yaml @@ -8,7 +8,7 @@ entrypoint: - cryostat-scorecard-tests - operator-install - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133" labels: suite: cryostat test: cryostat-multi-namespace @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133" labels: suite: cryostat test: cryostat-recording @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133" labels: suite: cryostat test: cryostat-config-change @@ -58,7 +58,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107174829" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20250107191133" labels: suite: cryostat test: cryostat-report diff --git a/internal/images/custom-scorecard-tests/Dockerfile b/internal/images/custom-scorecard-tests/Dockerfile index f1d4ed6f0..143659717 100644 --- a/internal/images/custom-scorecard-tests/Dockerfile +++ b/internal/images/custom-scorecard-tests/Dockerfile @@ -33,7 +33,7 @@ COPY internal/test/scorecard/ internal/test/scorecard/ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} GO111MODULE=on go build -a -o cryostat-scorecard-tests \ internal/images/custom-scorecard-tests/main.go -FROM registry.access.redhat.com/ubi8/ubi-minimal:latest +FROM registry.access.redhat.com/ubi9/ubi-minimal:latest ENV TEST=/usr/local/bin/cryostat-scorecard-tests \ USER_UID=1001 \ From e101b6abd0f6dfe31cd13149adcaf5741d25bc02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:31:32 -0500 Subject: [PATCH 6/7] build(deps): bump golang.org/x/net from 0.26.0 to 0.33.0 (#1002) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.26.0 to 0.33.0. - [Commits](https://github.com/golang/net/compare/v0.26.0...v0.33.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index e3f9d4903..f15fb8b2d 100644 --- a/go.mod +++ b/go.mod @@ -53,11 +53,11 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 388d5af20..9da03cfea 100644 --- a/go.sum +++ b/go.sum @@ -118,8 +118,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -129,14 +129,14 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h 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-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= 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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From c891bbe12324c8c42c1ac3697dd6fe590ab1e7eb Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Tue, 14 Jan 2025 14:04:30 -0500 Subject: [PATCH 7/7] feat(agent): add pod mutation webhook to inject agent (#991) * wip: pod mutation * More agent config * wip: working without server TLS * wip: working with TLS * Work with agent callback components * Wrap webhook to never deny admission * Add tests for pod mutation webhook, related image * Refactor agent proxy service, add test * Add size limit for emptyDir volume * Resource requests, more cleanup * sample app config makefile recipe * fixup! sample app config makefile recipe * Use slices.Contains * Switch to FNV-1 hash, add service tests --------- Co-authored-by: Andrew Azores Co-authored-by: Andrew Azores --- Makefile | 37 +- ...yostat-operator.clusterserviceversion.yaml | 21 +- config/samples/sample-app-agent-injected.yaml | 93 +++++ config/samples/sample-app-agent.yaml | 5 +- config/webhook/manifests.yaml | 19 + internal/controllers/common/common_utils.go | 53 ++- internal/controllers/common/naming.go | 32 ++ .../resource_definitions/certificates.go | 12 +- .../resource_definitions.go | 31 +- internal/controllers/common/tls.go | 11 +- .../{ => constants}/const_generated.go | 5 +- internal/controllers/constants/constants.go | 9 + internal/controllers/cryostat_controller.go | 3 - internal/controllers/openshift.go | 3 +- internal/controllers/reconciler.go | 40 +- internal/controllers/reconciler_test.go | 50 +++ internal/controllers/services.go | 91 ++++- internal/main.go | 9 +- internal/test/reconciler.go | 18 +- internal/test/resources.go | 54 ++- internal/tools/const_generator.go | 8 +- internal/webhooks/agent/agent_suite_test.go | 151 +++++++ internal/webhooks/agent/pod_defaulter.go | 355 ++++++++++++++++ internal/webhooks/agent/pod_defaulter_test.go | 326 +++++++++++++++ internal/webhooks/agent/pod_webhook.go | 108 +++++ internal/webhooks/agent/test/resources.go | 381 ++++++++++++++++++ 26 files changed, 1828 insertions(+), 97 deletions(-) create mode 100644 config/samples/sample-app-agent-injected.yaml create mode 100644 internal/controllers/common/naming.go rename internal/controllers/{ => constants}/const_generated.go (89%) create mode 100644 internal/webhooks/agent/agent_suite_test.go create mode 100644 internal/webhooks/agent/pod_defaulter.go create mode 100644 internal/webhooks/agent/pod_defaulter_test.go create mode 100644 internal/webhooks/agent/pod_webhook.go create mode 100644 internal/webhooks/agent/test/resources.go diff --git a/Makefile b/Makefile index 59701bf94..03eb6bb9a 100644 --- a/Makefile +++ b/Makefile @@ -96,7 +96,11 @@ export STORAGE_IMG ?= $(STORAGE_NAMESPACE)/$(STORAGE_NAME):$(STORAGE_VERSION) AGENT_PROXY_NAMESPACE ?= registry.access.redhat.com/ubi8 AGENT_PROXY_NAME ?= nginx-124 AGENT_PROXY_VERSION ?= latest -export AGENT_PROXY_IMG = $(AGENT_PROXY_NAMESPACE)/$(AGENT_PROXY_NAME):$(AGENT_PROXY_VERSION) +export AGENT_PROXY_IMG ?= $(AGENT_PROXY_NAMESPACE)/$(AGENT_PROXY_NAME):$(AGENT_PROXY_VERSION) +AGENT_INIT_NAMESPACE ?= $(DEFAULT_NAMESPACE) +AGENT_INIT_NAME ?= cryostat-agent-init +AGENT_INIT_VERSION ?= latest +export AGENT_INIT_IMG ?= $(AGENT_INIT_NAMESPACE)/$(AGENT_INIT_NAME):$(AGENT_INIT_VERSION) CERT_MANAGER_VERSION ?= 1.12.14 CERT_MANAGER_MANIFEST ?= \ @@ -396,25 +400,13 @@ ifneq ($(origin SAMPLE_APP_NAMESPACE), undefined) SAMPLE_APP_FLAGS += -n $(SAMPLE_APP_NAMESPACE) endif -.PHONY: sample_app -sample_app: undeploy_sample_app ## Deploy sample app. - $(CLUSTER_CLIENT) apply $(SAMPLE_APP_FLAGS) -f config/samples/sample-app.yaml - .PHONY: undeploy_sample_app undeploy_sample_app: ## Undeploy sample app. - $(CLUSTER_CLIENT) delete $(SAMPLE_APP_FLAGS) --ignore-not-found=$(ignore-not-found) -f config/samples/sample-app.yaml -.PHONY: sample_app_agent -sample_app_agent: undeploy_sample_app_agent ## Deploy sample app with Cryostat Agent. - @if [ -z "${AUTH_TOKEN}" ]; then \ - if [ "${CLUSTER_CLIENT}" = "oc" ]; then\ - AUTH_TOKEN=`oc whoami -t`; \ - else \ - echo "'AUTH_TOKEN' must be specified."; \ - exit 1; \ - fi; \ - fi; \ - $(CLUSTER_CLIENT) apply $(SAMPLE_APP_FLAGS) -f config/samples/sample-app-agent.yaml; \ +.PHONY: sample_app +sample_app: undeploy_sample_app ## Deploy sample app. + $(CLUSTER_CLIENT) apply $(SAMPLE_APP_FLAGS) -f config/samples/sample-app.yaml .PHONY: undeploy_sample_app_agent_proxy undeploy_sample_app_agent_proxy: ## Undeploy sample app with Cryostat Agent configured for TLS client auth on nginx proxy. @@ -437,6 +429,19 @@ sample_app_agent_proxy: undeploy_sample_app_agent_proxy ## Deploy sample app wit undeploy_sample_app_agent: ## Undeploy sample app with Cryostat Agent. - $(CLUSTER_CLIENT) delete $(SAMPLE_APP_FLAGS) --ignore-not-found=$(ignore-not-found) -f config/samples/sample-app-agent.yaml +.PHONY: sample_app_agent +sample_app_agent: undeploy_sample_app_agent ## Deploy sample app with Cryostat Agent. + $(CLUSTER_CLIENT) apply $(SAMPLE_APP_FLAGS) -f config/samples/sample-app-agent.yaml + +.PHONY: undeploy_sample_app_agent_injected +undeploy_sample_app_agent_injected: ## Undeploy sample app with Cryostat Agent deployed by Operator injection. + - $(CLUSTER_CLIENT) delete $(SAMPLE_APP_FLAGS) --ignore-not-found=$(ignore-not-found) -f config/samples/sample-app-agent-injected.yaml + +.PHONY: sample_app_agent_injected +sample_app_agent_injected: undeploy_sample_app_agent_injected ## Deploy sample app with Cryostat Agent deployed by Operator injection. + $(CLUSTER_CLIENT) apply $(SAMPLE_APP_FLAGS) -f config/samples/sample-app-agent-injected.yaml + $(CLUSTER_CLIENT) patch --type=merge -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"cryostat.io/namespace\":\"${DEPLOY_NAMESPACE}\"}}}}}" deployment/quarkus-cryostat-agent + .PHONY: cert_manager cert_manager: remove_cert_manager ## Install cert manager. $(CLUSTER_CLIENT) create --validate=false -f $(CERT_MANAGER_MANIFEST) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index aa92d967b..709fdcc65 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -30,7 +30,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:4.0.0-dev - createdAt: "2025-01-07T19:12:00Z" + createdAt: "2025-01-13T22:30:07Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -1220,6 +1220,25 @@ spec: targetPort: 9443 type: MutatingAdmissionWebhook webhookPath: /mutate-operator-cryostat-io-v1beta2-cryostat + - admissionReviewVersions: + - v1 + containerPort: 443 + deploymentName: cryostat-operator-controller + failurePolicy: Ignore + generateName: mpod.cryostat.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None + targetPort: 9443 + type: MutatingAdmissionWebhook + webhookPath: /mutate--v1-pod - admissionReviewVersions: - v1 containerPort: 443 diff --git a/config/samples/sample-app-agent-injected.yaml b/config/samples/sample-app-agent-injected.yaml new file mode 100644 index 000000000..c2c05d006 --- /dev/null +++ b/config/samples/sample-app-agent-injected.yaml @@ -0,0 +1,93 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: quarkus-cryostat-agent + name: quarkus-cryostat-agent +spec: + replicas: 1 + selector: + matchLabels: + app: quarkus-cryostat-agent + template: + metadata: + labels: + app: quarkus-cryostat-agent + cryostat.io/name: cryostat-sample + cryostat.io/namespace: cryostat-operator-system + spec: + serviceAccountName: quarkus-cryostat-agent-serviceaccount + containers: + - env: + - name: JAVA_OPTS_APPEND + value: |- + -Dquarkus.http.host=0.0.0.0 + -Djava.util.logging.manager=org.jboss.logmanager.LogManager + -Dio.cryostat.agent.shaded.org.slf4j.simpleLogger.defaultLogLevel=debug + image: quay.io/redhat-java-monitoring/quarkus-cryostat-agent:latest + imagePullPolicy: Always + name: quarkus-cryostat-agent + ports: + - containerPort: 10010 + protocol: TCP + resources: + limits: + cpu: 500m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + restartPolicy: Always + securityContext: + runAsNonRoot: true +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: quarkus-cryostat-agent + name: quarkus-cryostat-agent +spec: + selector: + app: quarkus-cryostat-agent + ports: + - name: agent-http + port: 9977 + protocol: TCP + targetPort: 9977 + - name: app-http + port: 10010 + protocol: TCP + targetPort: 10010 +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: quarkus-cryostat-agent-serviceaccount +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: quarkus-cryostat-agent-role +rules: +- apiGroups: + - "" + verbs: + - create + resources: + - pods/exec +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: quarkus-cryostat-agent-role-binding +subjects: +- kind: ServiceAccount + name: quarkus-cryostat-agent-serviceaccount +roleRef: + kind: Role + name: quarkus-cryostat-agent-role + apiGroup: rbac.authorization.k8s.io diff --git a/config/samples/sample-app-agent.yaml b/config/samples/sample-app-agent.yaml index 5e6d0efde..620f0bead 100644 --- a/config/samples/sample-app-agent.yaml +++ b/config/samples/sample-app-agent.yaml @@ -60,12 +60,9 @@ spec: - containerPort: 9097 protocol: TCP resources: - requests: - cpu: 200m - memory: 96Mi limits: cpu: 500m - memory: 192Mi + memory: 256Mi securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 8bd6292db..cf61bbc99 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -24,6 +24,25 @@ webhooks: resources: - cryostats sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate--v1-pod + failurePolicy: Ignore + name: mpod.cryostat.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration diff --git a/internal/controllers/common/common_utils.go b/internal/controllers/common/common_utils.go index b1be06bc1..239379c6d 100644 --- a/internal/controllers/common/common_utils.go +++ b/internal/controllers/common/common_utils.go @@ -17,9 +17,11 @@ package common import ( "crypto/sha256" "fmt" + "hash/fnv" "io/ioutil" "math/rand" "os" + "regexp" "strings" "time" @@ -36,6 +38,7 @@ var log = logf.Log.WithName("common") // OSUtils is an abstraction on functionality that interacts with the operating system type OSUtils interface { GetEnv(name string) string + GetEnvOrDefault(name string, defaultVal string) string GetFileContents(path string) ([]byte, error) GenPasswd(length int) string } @@ -48,6 +51,16 @@ func (o *DefaultOSUtils) GetEnv(name string) string { return os.Getenv(name) } +// GetEnvOrDefault returns the value of the environment variable with the provided name. +// If no such variable exists, the provided default value is returned. +func (o *DefaultOSUtils) GetEnvOrDefault(name string, defaultVal string) string { + val := o.GetEnv(name) + if len(val) > 0 { + return val + } + return defaultVal +} + // GetFileContents reads and returns the entire file contents specified by the path func (o *DefaultOSUtils) GetFileContents(path string) ([]byte, error) { return ioutil.ReadFile(path) @@ -77,21 +90,44 @@ func ClusterUniqueNameWithPrefix(gvk *schema.GroupVersionKind, prefix string, na return ClusterUniqueNameWithPrefixTargetNS(gvk, prefix, name, namespace, "") } +// ClusterUniqueShortName returns a name for cluster-scoped objects that is +// uniquely identified by a namespace and name. Appends the prefix to the +// provided Kind. The total length should be at most 63 characters. +func ClusterUniqueShortNameWithPrefix(gvk *schema.GroupVersionKind, prefix string, name string, namespace string) string { + return clusterUniqueName(gvk, prefix, name, namespace, "", true) +} + // ClusterUniqueNameWithPrefixTargetNS returns a name for cluster-scoped objects that is // uniquely identified by a namespace and name, and a target namespace. // Appends the prefix to the provided Kind. func ClusterUniqueNameWithPrefixTargetNS(gvk *schema.GroupVersionKind, prefix string, name string, namespace string, targetNS string) string { + return clusterUniqueName(gvk, prefix, name, namespace, targetNS, false) +} + +func clusterUniqueName(gvk *schema.GroupVersionKind, prefix string, name string, namespace string, targetNS string, + short bool) string { prefixWithKind := strings.ToLower(gvk.Kind) if len(prefix) > 0 { prefixWithKind += "-" + prefix } + toHash := namespace + "/" + name if len(targetNS) > 0 { toHash += "/" + targetNS } - // Use the SHA256 checksum of the namespaced name as a suffix - suffix := fmt.Sprintf("%x", sha256.Sum256([]byte(toHash))) + + var suffix string + if short { + // Use the 128-bit FNV-1 checksum of the namespaced name as a suffix. + // Suffix is 32 bytes + hash := fnv.New128() + hash.Write([]byte(toHash)) + suffix = fmt.Sprintf("%x", hash.Sum([]byte{})) + } else { + // Use the SHA256 checksum of the namespaced name as a suffix + suffix = fmt.Sprintf("%x", sha256.Sum256([]byte(toHash))) + } return prefixWithKind + "-" + suffix } @@ -125,6 +161,19 @@ func LabelsForTargetNamespaceObject(cr *model.CryostatInstance) map[string]strin } } +// Matches image tags of the form "major.minor.patch" +var develVerRegexp = regexp.MustCompile(`(?i)(:latest|SNAPSHOT|dev|BETA\d+)$`) + +// GetPullPolicy returns an image pull policy based on the image tag provided. +func GetPullPolicy(imageTag string) corev1.PullPolicy { + // Use Always for tags that have a known development suffix + if develVerRegexp.MatchString(imageTag) { + return corev1.PullAlways + } + // Likely a release, use IfNotPresent + return corev1.PullIfNotPresent +} + // SeccompProfile returns a SeccompProfile for the restricted // Pod Security Standard that, on OpenShift, is backwards-compatible // with OpenShift < 4.11. diff --git a/internal/controllers/common/naming.go b/internal/controllers/common/naming.go new file mode 100644 index 000000000..a9671c89e --- /dev/null +++ b/internal/controllers/common/naming.go @@ -0,0 +1,32 @@ +// Copyright The Cryostat Authors. +// +// 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 common + +import ( + "github.com/cryostatio/cryostat-operator/internal/controllers/model" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func AgentHeadlessServiceName(gvk *schema.GroupVersionKind, cr *model.CryostatInstance) string { + return ClusterUniqueShortNameWithPrefix(gvk, "agent", cr.Name, cr.InstallNamespace) +} + +func AgentProxyServiceName(cr *model.CryostatInstance) string { + return cr.Name + "-agent" +} + +func AgentCertificateName(gvk *schema.GroupVersionKind, cr *model.CryostatInstance, targetNamespace string) string { + return ClusterUniqueNameWithPrefixTargetNS(gvk, "agent", cr.Name, cr.InstallNamespace, targetNamespace) +} diff --git a/internal/controllers/common/resource_definitions/certificates.go b/internal/controllers/common/resource_definitions/certificates.go index 55bf76453..214175e91 100644 --- a/internal/controllers/common/resource_definitions/certificates.go +++ b/internal/controllers/common/resource_definitions/certificates.go @@ -134,7 +134,8 @@ func NewReportsCert(cr *model.CryostatInstance) *certv1.Certificate { } func NewAgentCert(cr *model.CryostatInstance, namespace string, gvk *schema.GroupVersionKind) *certv1.Certificate { - name := common.ClusterUniqueNameWithPrefixTargetNS(gvk, "agent", cr.Name, cr.InstallNamespace, namespace) + svcName := common.AgentHeadlessServiceName(gvk, cr) + name := common.AgentCertificateName(gvk, cr, namespace) return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -143,7 +144,7 @@ func NewAgentCert(cr *model.CryostatInstance, namespace string, gvk *schema.Grou Spec: certv1.CertificateSpec{ CommonName: constants.AgentsTLSCommonName, DNSNames: []string{ - fmt.Sprintf("*.%s.pod", namespace), + fmt.Sprintf("*.%s.%s.svc", svcName, namespace), }, SecretName: name, IssuerRef: certMeta.ObjectReference{ @@ -158,6 +159,7 @@ func NewAgentCert(cr *model.CryostatInstance, namespace string, gvk *schema.Grou } func NewAgentProxyCert(cr *model.CryostatInstance) *certv1.Certificate { + svcName := common.AgentProxyServiceName(cr) return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name + "-agent-proxy", @@ -166,9 +168,9 @@ func NewAgentProxyCert(cr *model.CryostatInstance) *certv1.Certificate { Spec: certv1.CertificateSpec{ CommonName: constants.AgentAuthProxyTLSCommonName, DNSNames: []string{ - cr.Name + "-agent", - fmt.Sprintf("%s-agent.%s.svc", cr.Name, cr.InstallNamespace), - fmt.Sprintf("%s-agent.%s.svc.cluster.local", cr.Name, cr.InstallNamespace), + svcName, + fmt.Sprintf("%s.%s.svc", svcName, cr.InstallNamespace), + fmt.Sprintf("%s.%s.svc.cluster.local", svcName, cr.InstallNamespace), }, SecretName: cr.Name + "-agent-tls", IssuerRef: certMeta.ObjectReference{ diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index e89f487b5..6b325678c 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -18,7 +18,6 @@ import ( "encoding/json" "fmt" "net/url" - "regexp" "strconv" "strings" @@ -618,7 +617,7 @@ func NewPodForReports(cr *model.CryostatInstance, imageTags *ImageTags, tls *TLS { Name: cr.Name + "-reports", Image: imageTags.ReportsImageTag, - ImagePullPolicy: getPullPolicy(imageTags.ReportsImageTag), + ImagePullPolicy: common.GetPullPolicy(imageTags.ReportsImageTag), Ports: []corev1.ContainerPort{ { ContainerPort: constants.ReportsContainerPort, @@ -749,7 +748,7 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp return &corev1.Container{ Name: cr.Name + "-auth-proxy", Image: imageTag, - ImagePullPolicy: getPullPolicy(imageTag), + ImagePullPolicy: common.GetPullPolicy(imageTag), VolumeMounts: volumeMounts, Ports: []corev1.ContainerPort{ { @@ -884,7 +883,7 @@ func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, im return &corev1.Container{ Name: cr.Name + "-auth-proxy", Image: imageTag, - ImagePullPolicy: getPullPolicy(imageTag), + ImagePullPolicy: common.GetPullPolicy(imageTag), VolumeMounts: volumeMounts, Ports: []corev1.ContainerPort{ { @@ -1212,7 +1211,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag return corev1.Container{ Name: cr.Name, Image: imageTag, - ImagePullPolicy: getPullPolicy(imageTag), + ImagePullPolicy: common.GetPullPolicy(imageTag), VolumeMounts: mounts, Ports: []corev1.ContainerPort{ { @@ -1282,7 +1281,7 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo return corev1.Container{ Name: cr.Name + "-grafana", Image: imageTag, - ImagePullPolicy: getPullPolicy(imageTag), + ImagePullPolicy: common.GetPullPolicy(imageTag), Ports: []corev1.ContainerPort{ { ContainerPort: constants.GrafanaContainerPort, @@ -1384,7 +1383,7 @@ func NewStorageContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo return corev1.Container{ Name: cr.Name + "-storage", Image: imageTag, - ImagePullPolicy: getPullPolicy(imageTag), + ImagePullPolicy: common.GetPullPolicy(imageTag), VolumeMounts: mounts, SecurityContext: containerSc, Env: envs, @@ -1478,7 +1477,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC return corev1.Container{ Name: cr.Name + "-db", Image: imageTag, - ImagePullPolicy: getPullPolicy(imageTag), + ImagePullPolicy: common.GetPullPolicy(imageTag), VolumeMounts: mounts, SecurityContext: containerSc, Env: envs, @@ -1527,7 +1526,7 @@ func NewJfrDatasourceContainer(cr *model.CryostatInstance, imageTag string) core return corev1.Container{ Name: cr.Name + "-jfr-datasource", Image: imageTag, - ImagePullPolicy: getPullPolicy(imageTag), + ImagePullPolicy: common.GetPullPolicy(imageTag), Ports: []corev1.ContainerPort{ { ContainerPort: constants.DatasourceContainerPort, @@ -1590,7 +1589,7 @@ func newAgentProxyContainer(cr *model.CryostatInstance, imageTag string, tls *TL return corev1.Container{ Name: cr.Name + "-agent-proxy", Image: imageTag, - ImagePullPolicy: getPullPolicy(imageTag), + ImagePullPolicy: common.GetPullPolicy(imageTag), Ports: []corev1.ContainerPort{ { ContainerPort: constants.AgentProxyContainerPort, @@ -1646,18 +1645,6 @@ func getInternalDashboardURL() string { return fmt.Sprintf("http://localhost:%d", constants.GrafanaContainerPort) } -// Matches image tags of the form "major.minor.patch" -var develVerRegexp = regexp.MustCompile(`(?i)(:latest|SNAPSHOT|dev|BETA\d+)$`) - -func getPullPolicy(imageTag string) corev1.PullPolicy { - // Use Always for tags that have a known development suffix - if develVerRegexp.MatchString(imageTag) { - return corev1.PullAlways - } - // Likely a release, use IfNotPresent - return corev1.PullIfNotPresent -} - func newVolumeForCR(cr *model.CryostatInstance) []corev1.Volume { var volumeSource corev1.VolumeSource if useEmptyDir(cr) { diff --git a/internal/controllers/common/tls.go b/internal/controllers/common/tls.go index 037230175..23d4aa0ac 100644 --- a/internal/controllers/common/tls.go +++ b/internal/controllers/common/tls.go @@ -32,7 +32,6 @@ import ( type ReconcilerTLS interface { IsCertManagerEnabled(cr *model.CryostatInstance) bool GetCertificateSecret(ctx context.Context, cert *certv1.Certificate) (*corev1.Secret, error) - OSUtils } // ReconcilerTLSConfig contains parameters used to create a ReconcilerTLS @@ -42,7 +41,7 @@ type ReconcilerTLSConfig struct { Client client.Client // Optional field to override the default behaviour when interacting // with the operating system - OSUtils + OS OSUtils } type reconcilerTLS struct { @@ -58,8 +57,8 @@ const disableServiceTLS = "DISABLE_SERVICE_TLS" // NewReconcilerTLS creates a new ReconcilerTLS using the provided configuration func NewReconcilerTLS(config *ReconcilerTLSConfig) ReconcilerTLS { configCopy := *config - if config.OSUtils == nil { - configCopy.OSUtils = &DefaultOSUtils{} + if config.OS == nil { + configCopy.OS = &DefaultOSUtils{} } return &reconcilerTLS{ ReconcilerTLSConfig: &configCopy, @@ -75,12 +74,12 @@ func (r *reconcilerTLS) IsCertManagerEnabled(cr *model.CryostatInstance) bool { } // Otherwise, fall back to DISABLE_SERVICE_TLS environment variable - return strings.ToLower(r.GetEnv(disableServiceTLS)) != "true" + return strings.ToLower(r.OS.GetEnv(disableServiceTLS)) != "true" } // ErrCertNotReady is returned when cert-manager has not marked the certificate // as ready, and no TLS secret has been populated yet. -var ErrCertNotReady error = errors.New("Certificate secret not yet ready") +var ErrCertNotReady error = errors.New("certificate secret not yet ready") // GetCertificateSecret returns the Secret corresponding to the named // cert-manager Certificate. This can return ErrCertNotReady if the diff --git a/internal/controllers/const_generated.go b/internal/controllers/constants/const_generated.go similarity index 89% rename from internal/controllers/const_generated.go rename to internal/controllers/constants/const_generated.go index 8ab5bced8..7e3be0b77 100644 --- a/internal/controllers/const_generated.go +++ b/internal/controllers/constants/const_generated.go @@ -1,5 +1,5 @@ // Code generated by const_generator.go; DO NOT EDIT. -package controllers +package constants // User facing name of the operand application const AppName = "Cryostat" @@ -33,3 +33,6 @@ const DefaultDatabaseImageTag = "quay.io/cryostat/cryostat-db:latest" // Default image tag for the agent proxy image const DefaultAgentProxyImageTag = "registry.access.redhat.com/ubi8/nginx-124:latest" + +// Default image tag for the agent init container image +const DefaultAgentInitImageTag = "quay.io/cryostat/cryostat-agent-init:latest" diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index 5b3b26ec0..816ec32f9 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -19,6 +19,9 @@ import ( corev1 "k8s.io/api/core/v1" ) +// Generates constants from environment variables at build time +//go:generate go run ../../tools/const_generator.go + const ( AuthProxyHttpContainerPort int32 = 4180 CryostatHTTPContainerPort int32 = 8181 @@ -47,10 +50,16 @@ const ( AgentProxyConfigFilePath string = "/etc/nginx-cryostat" AgentProxyConfigFileName string = "nginx.conf" + // Labels applied by operator to track cross-namespace ownership targetNamespaceCRLabelPrefix = "operator.cryostat.io/" TargetNamespaceCRNameLabel = targetNamespaceCRLabelPrefix + "name" TargetNamespaceCRNamespaceLabel = targetNamespaceCRLabelPrefix + "namespace" + // Labels for agent auto-configuration + agentLabelPrefix = "cryostat.io/" + AgentLabelCryostatName = agentLabelPrefix + "name" + AgentLabelCryostatNamespace = agentLabelPrefix + "namespace" + CryostatCATLSCommonName = "cryostat-ca-cert-manager" CryostatTLSCommonName = "cryostat" ReportsTLSCommonName = "cryostat-reports" diff --git a/internal/controllers/cryostat_controller.go b/internal/controllers/cryostat_controller.go index 2abdd6144..5d1a00b12 100644 --- a/internal/controllers/cryostat_controller.go +++ b/internal/controllers/cryostat_controller.go @@ -26,9 +26,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -// Generates constants from environment variables at build time -//go:generate go run ../tools/const_generator.go - // Verify that *CryostatReconciler implements CommonReconciler. var _ CommonReconciler = (*CryostatReconciler)(nil) diff --git a/internal/controllers/openshift.go b/internal/controllers/openshift.go index bdda3d5f1..0f73bf0b7 100644 --- a/internal/controllers/openshift.go +++ b/internal/controllers/openshift.go @@ -20,6 +20,7 @@ import ( "regexp" "github.com/cryostatio/cryostat-operator/internal/controllers/common" + "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/controllers/model" "github.com/go-logr/logr" configv1 "github.com/openshift/api/config/v1" @@ -78,7 +79,7 @@ func (r *Reconciler) reconcileConsoleLink(ctx context.Context, cr *model.Cryosta } op, err := controllerutil.CreateOrUpdate(ctx, r.Client, link, func() error { link.Spec.Link = consolev1.Link{ - Text: AppName, + Text: constants.AppName, Href: url, } link.Spec.Location = consolev1.NamespaceDashboard diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index 37c5226f6..60ed58f5d 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -65,6 +65,7 @@ type ReconcilerConfig struct { InsightsProxy *url.URL // Only defined if Insights is enabled NewControllerBuilder func(ctrl.Manager) common.ControllerBuilder common.ReconcilerTLS + common.OSUtils } // CommonReconciler is an interface for behaviour of the Cryostat reconciler @@ -145,6 +146,9 @@ func newReconciler(config *ReconcilerConfig, objType client.Object, isNamespaced if err != nil { return nil, err } + if config.OSUtils == nil { + config.OSUtils = &common.DefaultOSUtils{} + } return &Reconciler{ ReconcilerConfig: config, objectType: objType, @@ -171,6 +175,12 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn return reconcile.Result{}, err } + // Delete headless services in target namespaces + err = r.finalizeAgentHeadlessServices(ctx, cr) + if err != nil { + return reconcile.Result{}, err + } + // Finalizer for certificates and associated secrets if r.IsCertManagerEnabled(cr) { err = r.finalizeTLS(ctx, cr) @@ -273,6 +283,10 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn if err != nil { return reconcile.Result{}, err } + err = r.reconcileAgentHeadlessServices(ctx, cr) + if err != nil { + return reconcile.Result{}, err + } imageTags := r.getImageTags() fsGroup, err := r.getFSGroup(ctx, cr.InstallNamespace) @@ -395,24 +409,16 @@ func (r *Reconciler) reconcileReports(ctx context.Context, reqLogger logr.Logger func (r *Reconciler) getImageTags() *resources.ImageTags { return &resources.ImageTags{ - OAuth2ProxyImageTag: r.getEnvOrDefault(oauth2ProxyImageTagEnv, DefaultOAuth2ProxyImageTag), - OpenShiftOAuthProxyImageTag: r.getEnvOrDefault(openshiftOauthProxyImageTagEnv, DefaultOpenShiftOAuthProxyImageTag), - CoreImageTag: r.getEnvOrDefault(coreImageTagEnv, DefaultCoreImageTag), - DatasourceImageTag: r.getEnvOrDefault(datasourceImageTagEnv, DefaultDatasourceImageTag), - GrafanaImageTag: r.getEnvOrDefault(grafanaImageTagEnv, DefaultGrafanaImageTag), - ReportsImageTag: r.getEnvOrDefault(reportsImageTagEnv, DefaultReportsImageTag), - StorageImageTag: r.getEnvOrDefault(storageImageTagEnv, DefaultStorageImageTag), - DatabaseImageTag: r.getEnvOrDefault(databaseImageTagEnv, DefaultDatabaseImageTag), - AgentProxyImageTag: r.getEnvOrDefault(agentProxyImageTagEnv, DefaultAgentProxyImageTag), - } -} - -func (r *Reconciler) getEnvOrDefault(name string, defaultVal string) string { - val := r.GetEnv(name) - if len(val) > 0 { - return val + OAuth2ProxyImageTag: r.GetEnvOrDefault(oauth2ProxyImageTagEnv, constants.DefaultOAuth2ProxyImageTag), + OpenShiftOAuthProxyImageTag: r.GetEnvOrDefault(openshiftOauthProxyImageTagEnv, constants.DefaultOpenShiftOAuthProxyImageTag), + CoreImageTag: r.GetEnvOrDefault(coreImageTagEnv, constants.DefaultCoreImageTag), + DatasourceImageTag: r.GetEnvOrDefault(datasourceImageTagEnv, constants.DefaultDatasourceImageTag), + GrafanaImageTag: r.GetEnvOrDefault(grafanaImageTagEnv, constants.DefaultGrafanaImageTag), + ReportsImageTag: r.GetEnvOrDefault(reportsImageTagEnv, constants.DefaultReportsImageTag), + StorageImageTag: r.GetEnvOrDefault(storageImageTagEnv, constants.DefaultStorageImageTag), + DatabaseImageTag: r.GetEnvOrDefault(databaseImageTagEnv, constants.DefaultDatabaseImageTag), + AgentProxyImageTag: r.GetEnvOrDefault(agentProxyImageTagEnv, constants.DefaultAgentProxyImageTag), } - return defaultVal } // fsGroup to use when not constrained diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 40a71f33f..e5202d6fd 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -131,6 +131,7 @@ func (t *cryostatTestInput) newReconcilerConfig(scheme *runtime.Scheme, client c InsightsProxy: insightsURL, IsCertManagerInstalled: !t.CertManagerMissing, NewControllerBuilder: test.NewControllerBuilder(&t.TestReconcilerConfig), + OSUtils: test.NewTestOSUtils(&t.TestReconcilerConfig), } } @@ -160,6 +161,7 @@ func resourceChecks() []resourceCheck { {(*cryostatTestInput).expectLockConfigMap, "lock config map"}, {(*cryostatTestInput).expectAgentProxyConfigMap, "agent proxy config map"}, {(*cryostatTestInput).expectAgentProxyService, "agent proxy service"}, + {(*cryostatTestInput).expectAgentHeadlessService, "agent headless service"}, } } @@ -1930,6 +1932,27 @@ func (c *controllerTest) commonTests() { t.expectNoCryostat() }) }) + Context("Agent headless service exists", func() { + JustBeforeEach(func() { + t.reconcileDeletedCryostat() + }) + It("should delete the service", func() { + t.checkAgentHeadlessServiceDeleted() + }) + It("should delete Cryostat", func() { + t.expectNoCryostat() + }) + }) + Context("Agent headless service does not exist", func() { + JustBeforeEach(func() { + err := t.Client.Delete(context.Background(), t.NewAgentHeadlessService(targetNamespaces[0])) + Expect(err).ToNot(HaveOccurred()) + t.reconcileDeletedCryostat() + }) + It("should delete Cryostat", func() { + t.expectNoCryostat() + }) + }) }) }) @@ -2750,6 +2773,15 @@ func (t *cryostatTestInput) checkRoleBindingsDeleted() { } } +func (t *cryostatTestInput) checkAgentHeadlessServiceDeleted() { + for _, ns := range t.TargetNamespaces { + expected := t.NewAgentHeadlessService(ns) + svc := &corev1.Service{} + err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, svc) + Expect(kerrors.IsNotFound(err)).To(BeTrue()) + } +} + func (t *cryostatTestInput) checkCASecretsDeleted() { for _, ns := range t.TargetNamespaces { expected := t.NewCACertSecret(ns) @@ -2876,6 +2908,10 @@ func (t *cryostatTestInput) expectAgentProxyService() { t.checkService(t.NewAgentProxyService()) } +func (t *cryostatTestInput) expectAgentHeadlessService() { + t.checkServiceNoOwner(t.NewAgentHeadlessService(t.Namespace)) +} + func (t *cryostatTestInput) expectStatusApplicationURL() { instance := t.getCryostatInstance() Expect(instance.Status.ApplicationURL).To(Equal(fmt.Sprintf("https://%s.example.com", t.Name))) @@ -2927,9 +2963,23 @@ func (t *cryostatTestInput) checkService(expected *corev1.Service) { Expect(err).ToNot(HaveOccurred()) t.checkMetadata(service, expected) + t.checkServiceSpec(service, expected) +} + +func (t *cryostatTestInput) checkServiceNoOwner(expected *corev1.Service) { + service := &corev1.Service{} + err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, service) + Expect(err).ToNot(HaveOccurred()) + + t.checkMetadataNoOwner(service, expected) + t.checkServiceSpec(service, expected) +} + +func (t *cryostatTestInput) checkServiceSpec(service *corev1.Service, expected *corev1.Service) { Expect(service.Spec.Type).To(Equal(expected.Spec.Type)) Expect(service.Spec.Selector).To(Equal(expected.Spec.Selector)) Expect(service.Spec.Ports).To(Equal(expected.Spec.Ports)) + Expect(service.Spec.ClusterIP).To(Equal(expected.Spec.ClusterIP)) } func (t *cryostatTestInput) expectNoService(svcName string) { diff --git a/internal/controllers/services.go b/internal/controllers/services.go index 5be4c1ac1..342404bdb 100644 --- a/internal/controllers/services.go +++ b/internal/controllers/services.go @@ -18,7 +18,6 @@ import ( "context" "fmt" "net/url" - "strconv" operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" common "github.com/cryostatio/cryostat-operator/internal/controllers/common" @@ -50,7 +49,7 @@ func (r *Reconciler) reconcileCoreService(ctx context.Context, cr *model.Cryosta appProtocol := "http" svc.Spec.Ports = []corev1.ServicePort{ { - Name: "http", + Name: constants.HttpPortName, Port: *config.HTTPPort, TargetPort: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, AppProtocol: &appProtocol, @@ -90,7 +89,7 @@ func (r *Reconciler) reconcileReportsService(ctx context.Context, cr *model.Cryo } svc.Spec.Ports = []corev1.ServicePort{ { - Name: "http", + Name: constants.HttpPortName, Port: *config.HTTPPort, TargetPort: intstr.IntOrString{IntVal: constants.ReportsContainerPort}, }, @@ -108,19 +107,23 @@ func (r *Reconciler) reconcileReportsService(ctx context.Context, cr *model.Cryo } specs.ReportsURL = &url.URL{ Scheme: scheme, - Host: svc.Name + ":" + strconv.Itoa(int(svc.Spec.Ports[0].Port)), // TODO use getHTTPPort? + Host: fmt.Sprintf("%s:%d", svc.Name, *config.HTTPPort), } return nil } -func (r *Reconciler) reconcileAgentService(ctx context.Context, cr *model.CryostatInstance) error { - config := configureAgentService(cr) - svc := &corev1.Service{ +func newAgentService(cr *model.CryostatInstance) *corev1.Service { + return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name + "-agent", Namespace: cr.InstallNamespace, }, } +} + +func (r *Reconciler) reconcileAgentService(ctx context.Context, cr *model.CryostatInstance) error { + svc := newAgentService(cr) + config := configureAgentService(cr) return r.createOrUpdateService(ctx, svc, cr.Object, &config.ServiceConfig, func() error { svc.Spec.Selector = map[string]string{ @@ -129,7 +132,7 @@ func (r *Reconciler) reconcileAgentService(ctx context.Context, cr *model.Cryost } svc.Spec.Ports = []corev1.ServicePort{ { - Name: "http", + Name: constants.HttpPortName, Port: *config.HTTPPort, TargetPort: intstr.IntOrString{IntVal: constants.AgentProxyContainerPort}, }, @@ -138,6 +141,72 @@ func (r *Reconciler) reconcileAgentService(ctx context.Context, cr *model.Cryost }) } +func (r *Reconciler) newAgentHeadlessService(cr *model.CryostatInstance, namespace string) *corev1.Service { + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: common.AgentHeadlessServiceName(r.gvk, cr), + Namespace: namespace, + }, + } +} + +func (r *Reconciler) reconcileAgentHeadlessServices(ctx context.Context, cr *model.CryostatInstance) error { + svcType := corev1.ServiceTypeClusterIP + // TODO make configurable through CRD + config := &operatorv1beta2.ServiceConfig{ + ServiceType: &svcType, + Labels: common.LabelsForTargetNamespaceObject(cr), + } + configureService(config, cr.Name, "agent") + + // Create a headless Service in each target namespace + for _, ns := range cr.TargetNamespaces { + svc := r.newAgentHeadlessService(cr, ns) + + err := r.createOrUpdateService(ctx, svc, nil, config, func() error { + // Select agent auto-configuration labels + svc.Spec.Selector = map[string]string{ + constants.AgentLabelCryostatName: cr.Name, + constants.AgentLabelCryostatNamespace: cr.InstallNamespace, + } + svc.Spec.Ports = []corev1.ServicePort{ + { + Name: constants.HttpPortName, + Port: 9977, // TODO make configurable + TargetPort: intstr.IntOrString{IntVal: 9977}, + }, + } + svc.Spec.ClusterIP = corev1.ClusterIPNone + return nil + }) + if err != nil { + return err + } + } + + // Delete any RoleBindings in target namespaces that are no longer requested + for _, ns := range toDelete(cr) { + svc := r.newAgentHeadlessService(cr, ns) + err := r.deleteService(ctx, svc) + if err != nil { + return err + } + } + + return nil +} + +func (r *Reconciler) finalizeAgentHeadlessServices(ctx context.Context, cr *model.CryostatInstance) error { + for _, ns := range cr.TargetNamespaces { + svc := r.newAgentHeadlessService(cr, ns) + err := r.deleteService(ctx, svc) + if err != nil { + return err + } + } + return nil +} + func configureCoreService(cr *model.CryostatInstance) *operatorv1beta2.CoreServiceConfig { // Check CR for config var config *operatorv1beta2.CoreServiceConfig @@ -229,8 +298,10 @@ func (r *Reconciler) createOrUpdateService(ctx context.Context, svc *corev1.Serv common.MergeLabelsAndAnnotations(&svc.ObjectMeta, config.Labels, config.Annotations) // Set the Cryostat CR as controller - if err := controllerutil.SetControllerReference(owner, svc, r.Scheme); err != nil { - return err + if owner != nil { + if err := controllerutil.SetControllerReference(owner, svc, r.Scheme); err != nil { + return err + } } // Update the service type svc.Spec.Type = *config.ServiceType diff --git a/internal/main.go b/internal/main.go index 4ea9cc952..643233ae2 100644 --- a/internal/main.go +++ b/internal/main.go @@ -44,7 +44,9 @@ import ( operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" "github.com/cryostatio/cryostat-operator/internal/controllers" "github.com/cryostatio/cryostat-operator/internal/controllers/common" + "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/webhooks" + "github.com/cryostatio/cryostat-operator/internal/webhooks/agent" // +kubebuilder:scaffold:imports ) @@ -192,6 +194,11 @@ func main() { setupLog.Error(err, "unable to create webhook", "webhook", "Cryostat") os.Exit(1) } + agentWebhook := agent.NewAgentWebhook(&agent.AgentWebhookConfig{}) + if err = agentWebhook.SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Pod") + os.Exit(1) + } // +kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { @@ -203,7 +210,7 @@ func main() { os.Exit(1) } - setupLog.Info("starting manager", "version", controllers.OperatorVersion) + setupLog.Info("starting manager", "version", constants.OperatorVersion) if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { setupLog.Error(err, "problem running manager") os.Exit(1) diff --git a/internal/test/reconciler.go b/internal/test/reconciler.go index 8b339d8b1..9c831e6a7 100644 --- a/internal/test/reconciler.go +++ b/internal/test/reconciler.go @@ -36,6 +36,7 @@ type TestReconcilerConfig struct { EnvGrafanaImageTag *string EnvReportsImageTag *string EnvAgentProxyImageTag *string + EnvAgentInitImageTag *string GeneratedPasswords []string ControllerBuilder *TestCtrlBuilder CertManagerMissing bool @@ -43,8 +44,8 @@ type TestReconcilerConfig struct { func NewTestReconcilerTLS(config *TestReconcilerConfig) common.ReconcilerTLS { return common.NewReconcilerTLS(&common.ReconcilerTLSConfig{ - Client: config.Client, - OSUtils: newTestOSUtils(config), + Client: config.Client, + OS: NewTestOSUtils(config), }) } @@ -54,7 +55,7 @@ type testOSUtils struct { numPassGen int } -func newTestOSUtils(config *TestReconcilerConfig) *testOSUtils { +func NewTestOSUtils(config *TestReconcilerConfig) common.OSUtils { envs := map[string]string{} if config.EnvDisableTLS != nil { envs["DISABLE_SERVICE_TLS"] = strconv.FormatBool(*config.EnvDisableTLS) @@ -86,6 +87,9 @@ func newTestOSUtils(config *TestReconcilerConfig) *testOSUtils { if config.EnvAgentProxyImageTag != nil { envs["RELATED_IMAGE_AGENT_PROXY"] = *config.EnvAgentProxyImageTag } + if config.EnvAgentInitImageTag != nil { + envs["RELATED_IMAGE_AGENT_INIT"] = *config.EnvAgentInitImageTag + } return &testOSUtils{envs: envs, passwords: config.GeneratedPasswords} } @@ -98,6 +102,14 @@ func (o *testOSUtils) GetEnv(name string) string { return o.envs[name] } +func (o *testOSUtils) GetEnvOrDefault(name string, defaultVal string) string { + val := o.GetEnv(name) + if len(val) > 0 { + return val + } + return defaultVal +} + func (o *testOSUtils) GenPasswd(length int) string { gomega.Expect(o.numPassGen < len(o.passwords)).To(gomega.BeTrue()) password := o.passwords[o.numPassGen] diff --git a/internal/test/resources.go b/internal/test/resources.go index c482e61f2..1e4f3d82d 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -18,6 +18,7 @@ import ( "crypto/sha256" "encoding/json" "fmt" + "hash/fnv" "strings" certv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" @@ -854,6 +855,40 @@ func (r *TestResources) NewAgentProxyService() *corev1.Service { } } +func (r *TestResources) NewAgentHeadlessService(namespace string) *corev1.Service { + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.GetAgentServiceName(), + Namespace: namespace, + Labels: map[string]string{ + "app": r.Name, + "component": "agent", + "app.kubernetes.io/name": "cryostat", + "app.kubernetes.io/instance": r.Name, + "app.kubernetes.io/component": "agent", + "app.kubernetes.io/part-of": "cryostat", + "operator.cryostat.io/name": r.Name, + "operator.cryostat.io/namespace": r.Namespace, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeClusterIP, + ClusterIP: corev1.ClusterIPNone, + Selector: map[string]string{ + "cryostat.io/name": r.Name, + "cryostat.io/namespace": r.Namespace, + }, + Ports: []corev1.ServicePort{ + { + Name: "http", + Port: 9977, + TargetPort: intstr.FromInt(9977), + }, + }, + }, + } +} + func (r *TestResources) NewCustomizedCoreService() *corev1.Service { svc := r.NewCryostatService() svc.Spec.Type = corev1.ServiceTypeNodePort @@ -947,7 +982,7 @@ func (r *TestResources) NewCACertSecret(ns string) *corev1.Secret { } func (r *TestResources) NewAgentCertSecret(ns string) *corev1.Secret { - name := r.getClusterUniqueNameForAgent(ns) + name := r.GetClusterUniqueNameForAgent(ns) return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -1179,7 +1214,7 @@ func (r *TestResources) OtherCACert() *certv1.Certificate { } func (r *TestResources) NewAgentCert(namespace string) *certv1.Certificate { - name := r.getClusterUniqueNameForAgent(namespace) + name := r.GetClusterUniqueNameForAgent(namespace) return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -1188,7 +1223,7 @@ func (r *TestResources) NewAgentCert(namespace string) *certv1.Certificate { Spec: certv1.CertificateSpec{ CommonName: "cryostat-agent", DNSNames: []string{ - fmt.Sprintf("*.%s.pod", namespace), + fmt.Sprintf("*.%s.%s.svc", r.GetAgentServiceName(), namespace), }, SecretName: name, IssuerRef: certMeta.ObjectReference{ @@ -3007,6 +3042,13 @@ func (r *TestResources) clusterUniqueSuffix(namespace string) string { return fmt.Sprintf("%x", sha256.Sum256([]byte(toEncode))) } +func (r *TestResources) clusterUniqueShortSuffix() string { + toEncode := r.Namespace + "/" + r.Name + hash := fnv.New128() + hash.Write([]byte(toEncode)) + return fmt.Sprintf("%x", hash.Sum([]byte{})) +} + func (r *TestResources) NewClusterRoleBinding() *rbacv1.ClusterRoleBinding { return &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ @@ -3580,7 +3622,7 @@ func (r *TestResources) getClusterUniqueNameForCA() string { return "cryostat-ca-" + r.clusterUniqueSuffix("") } -func (r *TestResources) getClusterUniqueNameForAgent(namespace string) string { +func (r *TestResources) GetClusterUniqueNameForAgent(namespace string) string { return r.GetAgentCertPrefix() + r.clusterUniqueSuffix(namespace) } @@ -3588,6 +3630,10 @@ func (r *TestResources) GetAgentCertPrefix() string { return "cryostat-agent-" } +func (r *TestResources) GetAgentServiceName() string { + return "cryostat-agent-" + r.clusterUniqueShortSuffix() +} + func (r *TestResources) NewCreateEvent(obj ctrlclient.Object) event.CreateEvent { return event.CreateEvent{ Object: obj, diff --git a/internal/tools/const_generator.go b/internal/tools/const_generator.go index 1c60c0ae3..0c0342c17 100644 --- a/internal/tools/const_generator.go +++ b/internal/tools/const_generator.go @@ -33,6 +33,7 @@ const reportsImageEnv = "REPORTS_IMG" const storageImageEnv = "STORAGE_IMG" const databaseImageEnv = "DATABASE_IMG" const agentProxyImageEnv = "AGENT_PROXY_IMG" +const agentInitImageEnv = "AGENT_INIT_IMG" // This program generates a const_generated.go file containing image tag // constants for each container image deployed by the operator, along with @@ -51,6 +52,7 @@ func main() { StorageImageTag string DatabaseImageTag string AgentProxyImageTag string + AgentInitImageTag string }{ AppName: getEnvVar(appNameEnv), OperatorVersion: getEnvVar(operatorVersionEnv), @@ -63,6 +65,7 @@ func main() { StorageImageTag: getEnvVar(storageImageEnv), DatabaseImageTag: getEnvVar(databaseImageEnv), AgentProxyImageTag: getEnvVar(agentProxyImageEnv), + AgentInitImageTag: getEnvVar(agentInitImageEnv), } // Create the source file to generate @@ -87,7 +90,7 @@ func getEnvVar(name string) string { } var fileTemplate = template.Must(template.New("").Parse(`// Code generated by const_generator.go; DO NOT EDIT. -package controllers +package constants // User facing name of the operand application const AppName = "{{ .AppName }}" @@ -121,4 +124,7 @@ const DefaultDatabaseImageTag = "{{ .DatabaseImageTag }}" // Default image tag for the agent proxy image const DefaultAgentProxyImageTag = "{{ .AgentProxyImageTag }}" + +// Default image tag for the agent init container image +const DefaultAgentInitImageTag = "{{ .AgentInitImageTag }}" `)) diff --git a/internal/webhooks/agent/agent_suite_test.go b/internal/webhooks/agent/agent_suite_test.go new file mode 100644 index 000000000..10005686b --- /dev/null +++ b/internal/webhooks/agent/agent_suite_test.go @@ -0,0 +1,151 @@ +// Copyright The Cryostat Authors. +// +// 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 agent_test + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "github.com/cryostatio/cryostat-operator/internal/test" + "github.com/cryostatio/cryostat-operator/internal/webhooks" + "github.com/cryostatio/cryostat-operator/internal/webhooks/agent" + admissionv1beta1 "k8s.io/api/admission/v1beta1" + + //+kubebuilder:scaffold:imports + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc +var k8sScheme *runtime.Scheme +var agentWebhookConfig *agent.AgentWebhookConfig + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Agent Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, + }, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + k8sScheme = runtime.NewScheme() + err = scheme.AddToScheme(k8sScheme) + Expect(err).NotTo(HaveOccurred()) + err = operatorv1beta2.AddToScheme(k8sScheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.AddToScheme(k8sScheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: k8sScheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: k8sScheme, + WebhookServer: webhook.NewServer(webhook.Options{ + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + }), + LeaderElection: false, + Metrics: metricsserver.Options{BindAddress: "0"}, + }) + Expect(err).NotTo(HaveOccurred()) + + err = webhooks.SetupWebhookWithManager(mgr, &operatorv1beta2.Cryostat{}) + Expect(err).NotTo(HaveOccurred()) + + agentWebhookConfig = &agent.AgentWebhookConfig{ + OSUtils: test.NewTestOSUtils(&test.TestReconcilerConfig{}), + } + agentWebhook := agent.NewAgentWebhook(agentWebhookConfig) + err = agentWebhook.SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + conn.Close() + return nil + }).Should(Succeed()) + +}) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/internal/webhooks/agent/pod_defaulter.go b/internal/webhooks/agent/pod_defaulter.go new file mode 100644 index 000000000..c3f033672 --- /dev/null +++ b/internal/webhooks/agent/pod_defaulter.go @@ -0,0 +1,355 @@ +// Copyright The Cryostat Authors. +// +// 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 agent + +import ( + "context" + "errors" + "fmt" + "slices" + + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "github.com/cryostatio/cryostat-operator/internal/controllers/common" + "github.com/cryostatio/cryostat-operator/internal/controllers/constants" + "github.com/cryostatio/cryostat-operator/internal/controllers/model" + "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +type podMutator struct { + client client.Client + log *logr.Logger + gvk *schema.GroupVersionKind + config *AgentWebhookConfig + common.ReconcilerTLS +} + +var _ admission.CustomDefaulter = &podMutator{} + +const ( + agentArg = "-javaagent:/tmp/cryostat-agent/cryostat-agent-shaded.jar" + podNameEnvVar = "CRYOSTAT_AGENT_POD_NAME" + podIPEnvVar = "CRYOSTAT_AGENT_POD_IP" + agentMaxSizeBytes = "50Mi" + agentInitCpuRequest = "10m" + agentInitMemoryRequest = "32Mi" +) + +// Default optionally mutates a pod to inject the Cryostat agent +func (r *podMutator) Default(ctx context.Context, obj runtime.Object) error { + pod, ok := obj.(*corev1.Pod) + if !ok { + return fmt.Errorf("expected a Pod, but received a %T", obj) + } + + // TODO do this with objectSelector: https://github.com/kubernetes-sigs/controller-tools/issues/553 + // Check for required labels and return early if missing + if !metav1.HasLabel(pod.ObjectMeta, constants.AgentLabelCryostatName) || !metav1.HasLabel(pod.ObjectMeta, constants.AgentLabelCryostatNamespace) { + return nil + } + + // Look up Cryostat + cr := &operatorv1beta2.Cryostat{} + err := r.client.Get(ctx, types.NamespacedName{ + Name: pod.Labels[constants.AgentLabelCryostatName], + Namespace: pod.Labels[constants.AgentLabelCryostatNamespace], + }, cr) + if err != nil { + return err + } + + // Check if this pod is within a target namespace of the CR + if !slices.Contains(cr.Status.TargetNamespaces, pod.Namespace) { + return fmt.Errorf("pod's namespace \"%s\" is not a target namespace of Cryostat \"%s\" in \"%s\"", + pod.Namespace, cr.Name, cr.Namespace) + } + + // Check whether TLS is enabled for this CR + crModel := model.FromCryostat(cr) + tlsEnabled := r.IsCertManagerEnabled(crModel) + + // Select target container + if len(pod.Spec.Containers) == 0 { + // Should never happen, Kubernetes doesn't allow this + return errors.New("pod has no containers") + } + // TODO make configurable with label + container := &pod.Spec.Containers[0] + + // Add init container + nonRoot := true + imageTag := r.getImageTag() + pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{ + Name: "cryostat-agent-init", + Image: imageTag, + ImagePullPolicy: common.GetPullPolicy(imageTag), + Command: []string{"cp", "-v", "/cryostat/agent/cryostat-agent-shaded.jar", "/tmp/cryostat-agent/cryostat-agent-shaded.jar"}, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "cryostat-agent-init", + MountPath: "/tmp/cryostat-agent", + }, + }, + SecurityContext: &corev1.SecurityContext{ + RunAsNonRoot: &nonRoot, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + constants.CapabilityAll, + }, + }, + }, + Resources: corev1.ResourceRequirements{ // TODO allow customization with CRD + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse(agentInitCpuRequest), + corev1.ResourceMemory: resource.MustParse(agentInitMemoryRequest), + }, + }, + }) + + // Add emptyDir volume to copy agent into, and mount it + sizeLimit := resource.MustParse(agentMaxSizeBytes) + pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ + Name: "cryostat-agent-init", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + SizeLimit: &sizeLimit, + }, + }, + }) + + container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ + Name: "cryostat-agent-init", + MountPath: "/tmp/cryostat-agent", + ReadOnly: true, + }) + + container.Env = append(container.Env, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_BASEURI", + Value: cryostatURL(crModel, tlsEnabled), + }, + corev1.EnvVar{ + Name: podNameEnvVar, + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "metadata.name", + }, + }, + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_APP_NAME", + Value: fmt.Sprintf("$(%s)", podNameEnvVar), + }, + corev1.EnvVar{ + Name: podIPEnvVar, + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "status.podIP", + }, + }, + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_API_WRITES_ENABLED", + Value: "true", // TODO default to writes enabled, separate label? + }, + ) + + // Append callback environment variables + container.Env = append(container.Env, r.callbackEnv(crModel, pod.Namespace, tlsEnabled)...) + + if tlsEnabled { + // Mount the certificate volume + readOnlyMode := int32(0440) + pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ + Name: "cryostat-agent-tls", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: common.AgentCertificateName(r.gvk, crModel, pod.Namespace), + DefaultMode: &readOnlyMode, + }, + }, + }) + + container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ + Name: "cryostat-agent-tls", + MountPath: "/var/run/secrets/io.cryostat/cryostat-agent", + ReadOnly: true, + }) + + // Configure the Cryostat agent to use client certificate authentication + container.Env = append(container.Env, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_CLIENT_AUTH_CERT_PATH", + Value: fmt.Sprintf("/var/run/secrets/io.cryostat/cryostat-agent/%s", corev1.TLSCertKey), + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_CLIENT_AUTH_KEY_PATH", + Value: fmt.Sprintf("/var/run/secrets/io.cryostat/cryostat-agent/%s", corev1.TLSPrivateKeyKey), + }, + ) + + // Configure the Cryostat agent to trust the Cryostat CA + container.Env = append(container.Env, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_TRUSTSTORE_CERT_0__PATH", + Value: fmt.Sprintf("/var/run/secrets/io.cryostat/cryostat-agent/%s", constants.CAKey), + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_TRUSTSTORE_CERT_0__TYPE", + Value: "X.509", + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_TRUSTSTORE_CERT_0__ALIAS", + Value: "cryostat", + }, + ) + + // Configure the Cryostat agent to use HTTPS for its callback server + container.Env = append(container.Env, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_CERT_FILE", + Value: fmt.Sprintf("/var/run/secrets/io.cryostat/cryostat-agent/%s", corev1.TLSCertKey), + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_CERT_TYPE", + Value: "X.509", + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_CERT_ALIAS", + Value: "cryostat", + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_KEY_PATH", + Value: fmt.Sprintf("/var/run/secrets/io.cryostat/cryostat-agent/%s", corev1.TLSPrivateKeyKey), + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_KEY_TYPE", + Value: "RSA", + }, + corev1.EnvVar{ + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_KEY_ALIAS", + Value: "cryostat", + }, + ) + } + // Inject agent using JAVA_TOOL_OPTIONS, appending to any existing value + extended, err := extendJavaToolOptions(container.Env) + if err != nil { + return err + } + container.Env = extended + + // Use GenerateName for logging if no explicit Name is given + podName := pod.Name + if len(podName) == 0 { + podName = pod.GenerateName + } + r.log.Info("configured Cryostat agent for pod", "name", podName, "namespace", pod.Namespace) + + return nil +} + +func cryostatURL(cr *model.CryostatInstance, tls bool) string { + // Build the URL to the agent proxy service + scheme := "https" + if !tls { + scheme = "http" + } + return fmt.Sprintf("%s://%s.%s.svc:%d", scheme, common.AgentProxyServiceName(cr), cr.InstallNamespace, + getAgentProxyHTTPPort(cr)) +} + +func getAgentProxyHTTPPort(cr *model.CryostatInstance) int32 { + port := constants.AgentProxyContainerPort + if cr.Spec.ServiceOptions != nil && cr.Spec.ServiceOptions.AgentConfig != nil && cr.Spec.ServiceOptions.AgentConfig.HTTPPort != nil { + port = *cr.Spec.ServiceOptions.AgentConfig.HTTPPort + } + return port +} + +func (r *podMutator) callbackEnv(cr *model.CryostatInstance, namespace string, tls bool) []corev1.EnvVar { + scheme := "https" + if !tls { + scheme = "http" + } + envs := []corev1.EnvVar{ + { + Name: "CRYOSTAT_AGENT_CALLBACK_SCHEME", + Value: scheme, + }, + { + Name: "CRYOSTAT_AGENT_CALLBACK_HOST_NAME", + Value: fmt.Sprintf("$(%s), $(%s)[replace(\".\"\\, \"-\")]", podNameEnvVar, podIPEnvVar), + }, + { + Name: "CRYOSTAT_AGENT_CALLBACK_DOMAIN_NAME", + Value: fmt.Sprintf("%s.%s.svc", common.AgentHeadlessServiceName(r.gvk, cr), namespace), + }, + { + Name: "CRYOSTAT_AGENT_CALLBACK_PORT", + Value: "9977", + }, + } + + return envs +} + +func (r *podMutator) getImageTag() string { + // Lazily look up image tag + if r.config.InitImageTag == nil { + agentInitImage := r.config.GetEnvOrDefault(agentInitImageTagEnv, constants.DefaultAgentInitImageTag) + r.config.InitImageTag = &agentInitImage + } + return *r.config.InitImageTag +} + +func extendJavaToolOptions(envs []corev1.EnvVar) ([]corev1.EnvVar, error) { + existing, err := findJavaToolOptions(envs) + if err != nil { + return nil, err + } + + if existing != nil { + existing.Value += " " + agentArg + } else { + envs = append(envs, corev1.EnvVar{ + Name: "JAVA_TOOL_OPTIONS", + Value: agentArg, + }) + } + + return envs, nil +} + +var errJavaToolOptionsValueFrom error = errors.New("environment variable JAVA_TOOL_OPTIONS uses \"valueFrom\" and cannot be extended") + +func findJavaToolOptions(envs []corev1.EnvVar) (*corev1.EnvVar, error) { + for i, env := range envs { + if env.Name == "JAVA_TOOL_OPTIONS" { + if env.ValueFrom != nil { + return nil, errJavaToolOptionsValueFrom + } + return &envs[i], nil + } + } + return nil, nil +} diff --git a/internal/webhooks/agent/pod_defaulter_test.go b/internal/webhooks/agent/pod_defaulter_test.go new file mode 100644 index 000000000..f816a53af --- /dev/null +++ b/internal/webhooks/agent/pod_defaulter_test.go @@ -0,0 +1,326 @@ +// Copyright The Cryostat Authors. +// +// 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 agent_test + +import ( + "context" + "strconv" + "strings" + + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "github.com/cryostatio/cryostat-operator/internal/controllers/common" + "github.com/cryostatio/cryostat-operator/internal/controllers/model" + "github.com/cryostatio/cryostat-operator/internal/test" + webhooktests "github.com/cryostatio/cryostat-operator/internal/webhooks/agent/test" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +type defaulterTestInput struct { + client ctrlclient.Client + objs []ctrlclient.Object + *webhooktests.AgentWebhookTestResources +} + +var _ = Describe("PodDefaulter", func() { + var t *defaulterTestInput + var otherNS string + count := 0 + + namespaceWithSuffix := func(name string) string { + return name + "-agent-" + strconv.Itoa(count) + } + + BeforeEach(func() { + ns := namespaceWithSuffix("test") + otherNS = namespaceWithSuffix("other") + t = &defaulterTestInput{ + AgentWebhookTestResources: &webhooktests.AgentWebhookTestResources{ + TestResources: &test.TestResources{ + Name: "cryostat", + Namespace: ns, + TargetNamespaces: []string{ns}, + TLS: true, + }, + }, + } + t.objs = []ctrlclient.Object{ + t.NewNamespace(), t.NewOtherNamespace(otherNS), + } + }) + + JustBeforeEach(func() { + logger := zap.New() + logf.SetLogger(logger) + + t.client = k8sClient + for _, obj := range t.objs { + err := t.client.Create(ctx, obj) + Expect(err).ToNot(HaveOccurred()) + } + }) + + JustAfterEach(func() { + for _, obj := range t.objs { + err := ctrlclient.IgnoreNotFound(t.client.Delete(ctx, obj)) + Expect(err).ToNot(HaveOccurred()) + } + }) + + AfterEach(func() { + count++ + }) + + Context("configuring a pod", func() { + var originalPod *corev1.Pod + var expectedPod *corev1.Pod + + ExpectPod := func() { + It("should add init container", func() { + actual := t.getPod(expectedPod) + expectedInitContainers := expectedPod.Spec.InitContainers + Expect(actual.Spec.InitContainers).To(HaveLen(len(expectedInitContainers))) + for idx := range expectedInitContainers { + expected := expectedPod.Spec.InitContainers[idx] + container := actual.Spec.InitContainers[idx] + Expect(container.Name).To(Equal(expected.Name)) + Expect(container.Command).To(Equal(expected.Command)) + Expect(container.Args).To(Equal(expected.Args)) + Expect(container.Env).To(Equal(expected.Env)) + Expect(container.EnvFrom).To(Equal(expected.EnvFrom)) + Expect(container.Image).To(HavePrefix(expected.Image[:strings.Index(expected.Image, ":")])) + Expect(container.ImagePullPolicy).To(Equal(expected.ImagePullPolicy)) + Expect(container.VolumeMounts).To(Equal(expected.VolumeMounts)) + Expect(container.SecurityContext).To(Equal(expected.SecurityContext)) + Expect(container.Ports).To(Equal(expected.Ports)) + Expect(container.LivenessProbe).To(Equal(expected.LivenessProbe)) + Expect(container.ReadinessProbe).To(Equal(expected.ReadinessProbe)) + } + }) + + It("should add volume(s)", func() { + actual := t.getPod(expectedPod) + Expect(actual.Spec.Volumes).To(ConsistOf(expectedPod.Spec.Volumes)) + }) + + It("should add volume mounts(s)", func() { + actual := t.getPod(expectedPod) + expected := expectedPod.Spec.Containers[0] + Expect(actual.Spec.Containers).To(HaveLen(1)) + container := actual.Spec.Containers[0] + Expect(container.VolumeMounts).To(ConsistOf(expected.VolumeMounts)) + }) + + It("should add environment variables", func() { + actual := t.getPod(expectedPod) + expected := expectedPod.Spec.Containers[0] + Expect(actual.Spec.Containers).To(HaveLen(1)) + container := actual.Spec.Containers[0] + Expect(container.Env).To(ConsistOf(expected.Env)) + Expect(container.EnvFrom).To(ConsistOf(expected.EnvFrom)) + }) + } + + Context("with a Cryostat CR", func() { + JustBeforeEach(func() { + cr := t.getCryostatInstance() + cr.Status.TargetNamespaces = cr.Spec.TargetNamespaces + t.updateCryostatInstanceStatus(cr) + + err := t.client.Create(ctx, originalPod) + Expect(err).ToNot(HaveOccurred()) + }) + + Context("with TLS enabled", func() { + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostat().Object) + originalPod = t.NewPod() + expectedPod = t.NewMutatedPod() + }) + + ExpectPod() + }) + + Context("with TLS disabled", func() { + BeforeEach(func() { + t.TLS = false + t.objs = append(t.objs, t.NewCryostatCertManagerDisabled().Object) + originalPod = t.NewPod() + expectedPod = t.NewMutatedPod() + }) + + ExpectPod() + }) + + Context("with existing JAVA_TOOL_OPTIONS", func() { + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostat().Object) + originalPod = t.NewPodJavaToolOptions() + expectedPod = t.NewMutatedPodJavaToolOptions() + }) + + ExpectPod() + }) + + Context("with existing JAVA_TOOL_OPTIONS using valueFrom", func() { + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostat().Object) + originalPod = t.NewPodJavaToolOptionsFrom() + // Should fail + expectedPod = originalPod + }) + + ExpectPod() + }) + + Context("in a different namespace", func() { + BeforeEach(func() { + t.TargetNamespaces = append(t.TargetNamespaces, otherNS) + t.objs = append(t.objs, t.NewCryostat().Object) + originalPod = t.NewPodOtherNamespace(otherNS) + expectedPod = t.NewMutatedPodOtherNamespace(otherNS) + }) + + ExpectPod() + }) + + Context("in a non-target namespace", func() { + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostat().Object) + originalPod = t.NewPodOtherNamespace(otherNS) + // Should fail + expectedPod = originalPod + }) + + ExpectPod() + }) + + Context("with no name label", func() { + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostat().Object) + originalPod = t.NewPodNoNameLabel() + // Should fail + expectedPod = originalPod + }) + + ExpectPod() + }) + + Context("with no namespace label", func() { + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostat().Object) + originalPod = t.NewPodNoNamespaceLabel() + // Should fail + expectedPod = originalPod + }) + + ExpectPod() + }) + + Context("with custom image tag", func() { + var saveOSUtils common.OSUtils + + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostat().Object) + originalPod = t.NewPod() + }) + + setImageTag := func(imageTag string) { + saveOSUtils = agentWebhookConfig.OSUtils + // Force webhook to query environment again + agentWebhookConfig.InitImageTag = nil + agentWebhookConfig.OSUtils = test.NewTestOSUtils(&test.TestReconcilerConfig{ + EnvAgentInitImageTag: &[]string{imageTag}[0], + }) + } + + JustAfterEach(func() { + // Reset state + agentWebhookConfig.OSUtils = saveOSUtils + agentWebhookConfig.InitImageTag = nil + }) + + Context("for development", func() { + BeforeEach(func() { + expectedPod = t.NewMutatedPodCustomDevImage() + setImageTag("example.com/agent-init:latest") + }) + + ExpectPod() + }) + + Context("for release", func() { + BeforeEach(func() { + expectedPod = t.NewMutatedPodCustomImage() + setImageTag("example.com/agent-init:2.0.0") + }) + + ExpectPod() + }) + }) + + Context("with a custom proxy port", func() { + BeforeEach(func() { + t.objs = append(t.objs, t.NewCryostatWithAgentSvc().Object) + originalPod = t.NewPod() + expectedPod = t.NewMutatedPodProxyPort() + }) + + ExpectPod() + }) + }) + + Context("with a missing Cryostat CR", func() { + BeforeEach(func() { + originalPod = t.NewPod() + // Should fail + expectedPod = originalPod + }) + + JustBeforeEach(func() { + err := t.client.Create(ctx, originalPod) + Expect(err).ToNot(HaveOccurred()) + }) + + ExpectPod() + }) + }) + +}) + +func (t *defaulterTestInput) getPod(expected *corev1.Pod) *corev1.Pod { + pod := &corev1.Pod{} + err := t.client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, pod) + Expect(err).ToNot(HaveOccurred()) + return pod +} + +func (t *defaulterTestInput) getCryostatInstance() *model.CryostatInstance { + cr := &operatorv1beta2.Cryostat{} + err := t.client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, cr) + Expect(err).ToNot(HaveOccurred()) + return t.ConvertNamespacedToModel(cr) +} + +func (t *defaulterTestInput) updateCryostatInstanceStatus(cr *model.CryostatInstance) { + err := t.client.Status().Update(context.Background(), cr.Object) + Expect(err).ToNot(HaveOccurred()) +} diff --git a/internal/webhooks/agent/pod_webhook.go b/internal/webhooks/agent/pod_webhook.go new file mode 100644 index 000000000..1b528bcc0 --- /dev/null +++ b/internal/webhooks/agent/pod_webhook.go @@ -0,0 +1,108 @@ +// Copyright The Cryostat Authors. +// +// 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 agent + +import ( + "context" + + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "github.com/cryostatio/cryostat-operator/internal/controllers/common" + corev1 "k8s.io/api/core/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// podWebhookLog is for logging in this package. +var podWebhookLog = logf.Log.WithName("pod-webhook") + +// Environment variable to override the agent init container image +const agentInitImageTagEnv = "RELATED_IMAGE_AGENT_INIT" + +//+kubebuilder:webhook:path=/mutate--v1-pod,mutating=true,failurePolicy=ignore,sideEffects=None,groups="",resources=pods,verbs=create,versions=v1,name=mpod.cryostat.io,admissionReviewVersions=v1 + +type AgentWebhook interface { + SetupWebhookWithManager(mgr ctrl.Manager) error +} + +type AgentWebhookConfig struct { + InitImageTag *string + common.OSUtils +} + +type agentWebhook struct { + *AgentWebhookConfig +} + +var _ AgentWebhook = &agentWebhook{} + +func NewAgentWebhook(config *AgentWebhookConfig) AgentWebhook { + if config.OSUtils == nil { + config.OSUtils = &common.DefaultOSUtils{} + } + return &agentWebhook{ + AgentWebhookConfig: config, + } +} + +func (r *agentWebhook) SetupWebhookWithManager(mgr ctrl.Manager) error { + gvk, err := apiutil.GVKForObject(&operatorv1beta2.Cryostat{}, mgr.GetScheme()) + if err != nil { + return err + } + + webhook := admission.WithCustomDefaulter(mgr.GetScheme(), &corev1.Pod{}, &podMutator{ + client: mgr.GetClient(), + config: r.AgentWebhookConfig, + log: &podWebhookLog, + gvk: &gvk, + ReconcilerTLS: common.NewReconcilerTLS(&common.ReconcilerTLSConfig{ + Client: mgr.GetClient(), + OS: r.OSUtils, + }), + }).WithRecoverPanic(true) + // Modify the webhook to never deny the pod from being admitted + webhook.Handler = allowAllRequests(webhook.Handler) + mgr.GetWebhookServer().Register("/mutate--v1-pod", webhook) + return nil +} + +type allowAllHandlerWrapper struct { + impl admission.Handler +} + +func (r *allowAllHandlerWrapper) Handle(ctx context.Context, req admission.Request) admission.Response { + // Call the handler implementation + result := r.impl.Handle(ctx, req) + if !result.Allowed { + msg := "" + if result.Result != nil { + msg = result.Result.Message + } + podWebhookLog.Info("pod mutation failed", "result", msg) + } + // Modify the result to always permit the request + result.Allowed = true + return result +} + +var _ admission.Handler = &allowAllHandlerWrapper{} + +func allowAllRequests(handler admission.Handler) admission.Handler { + return &allowAllHandlerWrapper{ + impl: handler, + } +} diff --git a/internal/webhooks/agent/test/resources.go b/internal/webhooks/agent/test/resources.go new file mode 100644 index 000000000..a9ccb72b8 --- /dev/null +++ b/internal/webhooks/agent/test/resources.go @@ -0,0 +1,381 @@ +// Copyright The Cryostat Authors. +// +// 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 test + +import ( + "fmt" + + "github.com/cryostatio/cryostat-operator/internal/test" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type AgentWebhookTestResources struct { + *test.TestResources +} + +func (r *AgentWebhookTestResources) NewPod() *corev1.Pod { + return &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name + "-webhook-test", + Namespace: r.Namespace, + Labels: map[string]string{ + "cryostat.io/name": r.Name, + "cryostat.io/namespace": r.Namespace, + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test", + Image: "example.com/test:latest", + Env: []corev1.EnvVar{ + { + Name: "TEST", + Value: "some-value", + }, + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: &[]bool{false}[0], + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + }, + }, + }, + SecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: &[]bool{true}[0], + }, + }, + } +} + +func (r *AgentWebhookTestResources) NewPodJavaToolOptions() *corev1.Pod { + pod := r.NewPod() + container := &pod.Spec.Containers[0] + container.Env = append(container.Env, + corev1.EnvVar{ + Name: "JAVA_TOOL_OPTIONS", + Value: "-Dexisting=var", + }) + return pod +} + +func (r *AgentWebhookTestResources) NewPodJavaToolOptionsFrom() *corev1.Pod { + pod := r.NewPod() + container := &pod.Spec.Containers[0] + container.Env = append(container.Env, + corev1.EnvVar{ + Name: "JAVA_TOOL_OPTIONS", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "my-config", + }, + Key: "java-tool-options", + Optional: &[]bool{true}[0], + }, + }, + }) + return pod +} + +func (r *AgentWebhookTestResources) NewPodOtherNamespace(namespace string) *corev1.Pod { + pod := r.NewPod() + pod.Namespace = namespace + return pod +} + +func (r *AgentWebhookTestResources) NewPodNoNameLabel() *corev1.Pod { + pod := r.NewPod() + delete(pod.Labels, "cryostat.io/name") + return pod +} + +func (r *AgentWebhookTestResources) NewPodNoNamespaceLabel() *corev1.Pod { + pod := r.NewPod() + delete(pod.Labels, "cryostat.io/namespace") + return pod +} + +type mutatedPodOptions struct { + javaToolOptions string + namespace string + image string + pullPolicy corev1.PullPolicy + proxyPort int32 +} + +func (r *AgentWebhookTestResources) setDefaultMutatedPodOptions(options *mutatedPodOptions) { + if len(options.namespace) == 0 { + options.namespace = r.Namespace + } + if len(options.image) == 0 { + options.image = "quay.io/cryostat/cryostat-agent-init:latest" + } + if len(options.pullPolicy) == 0 { + options.pullPolicy = corev1.PullAlways + } + if options.proxyPort == 0 { + options.proxyPort = 8282 + } +} + +func (r *AgentWebhookTestResources) NewMutatedPod() *corev1.Pod { + return r.newMutatedPod(&mutatedPodOptions{}) +} + +func (r *AgentWebhookTestResources) NewMutatedPodJavaToolOptions() *corev1.Pod { + return r.newMutatedPod(&mutatedPodOptions{ + javaToolOptions: "-Dexisting=var ", + }) +} + +func (r *AgentWebhookTestResources) NewMutatedPodOtherNamespace(namespace string) *corev1.Pod { + return r.newMutatedPod(&mutatedPodOptions{ + namespace: namespace, + }) +} + +func (r *AgentWebhookTestResources) NewMutatedPodCustomImage() *corev1.Pod { + return r.newMutatedPod(&mutatedPodOptions{ + image: "example.com/agent-init:2.0.0", + pullPolicy: corev1.PullIfNotPresent, + }) +} + +func (r *AgentWebhookTestResources) NewMutatedPodCustomDevImage() *corev1.Pod { + return r.newMutatedPod(&mutatedPodOptions{ + image: "example.com/agent-init:latest", + pullPolicy: corev1.PullAlways, + }) +} + +func (r *AgentWebhookTestResources) NewMutatedPodProxyPort() *corev1.Pod { + return r.newMutatedPod(&mutatedPodOptions{ + proxyPort: 8080, + }) +} + +func (r *AgentWebhookTestResources) newMutatedPod(options *mutatedPodOptions) *corev1.Pod { + r.setDefaultMutatedPodOptions(options) + scheme := "https" + if !r.TLS { + scheme = "http" + } + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name + "-webhook-test", + Namespace: options.namespace, + Labels: map[string]string{ + "cryostat.io/name": r.Name, + "cryostat.io/namespace": r.Namespace, + }, + }, + Spec: corev1.PodSpec{ + InitContainers: []corev1.Container{ + { + Name: "cryostat-agent-init", + Image: options.image, + ImagePullPolicy: options.pullPolicy, + Command: []string{"cp", "-v", "/cryostat/agent/cryostat-agent-shaded.jar", "/tmp/cryostat-agent/cryostat-agent-shaded.jar"}, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "cryostat-agent-init", + MountPath: "/tmp/cryostat-agent", + }, + }, + SecurityContext: &corev1.SecurityContext{ + RunAsNonRoot: &[]bool{true}[0], + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + }, + }, + }, + Containers: []corev1.Container{ + { + Name: "test", + Image: "example.com/test:latest", + Env: []corev1.EnvVar{ + { + Name: "TEST", + Value: "some-value", + }, + { + Name: "CRYOSTAT_AGENT_BASEURI", + Value: fmt.Sprintf("%s://%s-agent.%s.svc:%d", scheme, r.Name, r.Namespace, options.proxyPort), + }, + { + Name: "CRYOSTAT_AGENT_POD_NAME", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }, + }, + }, + { + Name: "CRYOSTAT_AGENT_APP_NAME", + Value: "$(CRYOSTAT_AGENT_POD_NAME)", + }, + { + Name: "CRYOSTAT_AGENT_POD_IP", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "status.podIP", + }, + }, + }, + { + Name: "CRYOSTAT_AGENT_API_WRITES_ENABLED", + Value: "true", + }, + + { + Name: "CRYOSTAT_AGENT_CALLBACK_SCHEME", + Value: scheme, + }, + { + Name: "CRYOSTAT_AGENT_CALLBACK_HOST_NAME", + Value: "$(CRYOSTAT_AGENT_POD_NAME), $(CRYOSTAT_AGENT_POD_IP)[replace(\".\"\\, \"-\")]", + }, + { + Name: "CRYOSTAT_AGENT_CALLBACK_DOMAIN_NAME", + Value: fmt.Sprintf("%s.%s.svc", r.GetAgentServiceName(), options.namespace), + }, + { + Name: "CRYOSTAT_AGENT_CALLBACK_PORT", + Value: "9977", + }, + { + Name: "JAVA_TOOL_OPTIONS", + Value: options.javaToolOptions + "-javaagent:/tmp/cryostat-agent/cryostat-agent-shaded.jar", + }, + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: &[]bool{false}[0], + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "cryostat-agent-init", + MountPath: "/tmp/cryostat-agent", + ReadOnly: true, + }, + }, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("10m"), + corev1.ResourceMemory: resource.MustParse("32Mi"), + }, + }, + }, + }, + SecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: &[]bool{true}[0], + }, + Volumes: []corev1.Volume{ + { + Name: "cryostat-agent-init", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + SizeLimit: &[]resource.Quantity{resource.MustParse("50Mi")}[0], + }, + }, + }, + }, + }, + } + + if r.TLS { + container := &pod.Spec.Containers[0] + tlsEnvs := []corev1.EnvVar{ + { + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_CLIENT_AUTH_CERT_PATH", + Value: "/var/run/secrets/io.cryostat/cryostat-agent/tls.crt", + }, + { + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_CLIENT_AUTH_KEY_PATH", + Value: "/var/run/secrets/io.cryostat/cryostat-agent/tls.key", + }, + { + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_TRUSTSTORE_CERT_0__PATH", + Value: "/var/run/secrets/io.cryostat/cryostat-agent/ca.crt", + }, + { + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_TRUSTSTORE_CERT_0__TYPE", + Value: "X.509", + }, + { + Name: "CRYOSTAT_AGENT_WEBCLIENT_TLS_TRUSTSTORE_CERT_0__ALIAS", + Value: "cryostat", + }, + { + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_CERT_FILE", + Value: "/var/run/secrets/io.cryostat/cryostat-agent/tls.crt", + }, + { + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_CERT_TYPE", + Value: "X.509", + }, + { + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_CERT_ALIAS", + Value: "cryostat", + }, + { + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_KEY_PATH", + Value: "/var/run/secrets/io.cryostat/cryostat-agent/tls.key", + }, + { + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_KEY_TYPE", + Value: "RSA", + }, + { + Name: "CRYOSTAT_AGENT_WEBSERVER_TLS_KEY_ALIAS", + Value: "cryostat", + }, + } + container.Env = append(container.Env, tlsEnvs...) + container.VolumeMounts = append(container.VolumeMounts, + corev1.VolumeMount{ + Name: "cryostat-agent-tls", + MountPath: "/var/run/secrets/io.cryostat/cryostat-agent", + ReadOnly: true, + }) + pod.Spec.Volumes = append(pod.Spec.Volumes, + corev1.Volume{ + Name: "cryostat-agent-tls", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: r.GetClusterUniqueNameForAgent(options.namespace), + DefaultMode: &[]int32{0440}[0], + }, + }, + }) + } + + return pod +}