From a57cc036bb3ac0ff8263b3e20207bb1c99c0e5a5 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Mon, 12 Feb 2024 10:07:28 -0500 Subject: [PATCH 01/53] feat(csv): require AllNamespaces install mode (#719) * feat(csv): require AllNamespaces install mode * Remove unused function * Remove install mode variable from Makefile --- Makefile | 3 +- ...yostat-operator.clusterserviceversion.yaml | 4 +- ...yostat-operator.clusterserviceversion.yaml | 4 +- internal/controllers/reconciler.go | 32 -------- internal/controllers/reconciler_test.go | 7 +- internal/controllers/reconciler_unit_test.go | 79 ------------------- internal/main.go | 43 +--------- 7 files changed, 10 insertions(+), 162 deletions(-) delete mode 100644 internal/controllers/reconciler_unit_test.go diff --git a/Makefile b/Makefile index 897010c8a..4dbf7bfb8 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,6 @@ USE_IMAGE_DIGESTS ?= false ifeq ($(USE_IMAGE_DIGESTS), true) BUNDLE_GEN_FLAGS += --use-image-digests endif -BUNDLE_INSTALL_MODE ?= AllNamespaces IMAGE_BUILDER ?= podman # Image URL to use all building/pushing image targets @@ -474,7 +473,7 @@ undeploy: ## Undeploy controller from the configured cluster in ~/.kube/config. .PHONY: deploy_bundle deploy_bundle: check_cert_manager undeploy_bundle ## Deploy the controller in the bundle format with OLM. - $(OPERATOR_SDK) run bundle --install-mode $(BUNDLE_INSTALL_MODE) $(BUNDLE_IMG) + $(OPERATOR_SDK) run bundle --install-mode AllNamespaces $(BUNDLE_IMG) ifeq ($(DISABLE_SERVICE_TLS), true) @echo "Disabling TLS for in-cluster communication between Services" @current_ns=`$(CLUSTER_CLIENT) config view --minify -o 'jsonpath={.contexts[0].context.namespace}'` && \ diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index e29650bae..5da0012f5 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -1236,9 +1236,9 @@ spec: serviceAccountName: cryostat-operator-service-account strategy: deployment installModes: - - supported: true + - supported: false type: OwnNamespace - - supported: true + - supported: false type: SingleNamespace - supported: false type: MultiNamespace diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index f5d5f8b02..760d31451 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -866,9 +866,9 @@ spec: deployments: null strategy: "" installModes: - - supported: true + - supported: false type: OwnNamespace - - supported: true + - supported: false type: SingleNamespace - supported: false type: MultiNamespace diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index be5d46055..f15d4d3d5 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -47,7 +47,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -61,7 +60,6 @@ type ReconcilerConfig struct { IsCertManagerInstalled bool EventRecorder record.EventRecorder RESTMapper meta.RESTMapper - Namespaces []string InsightsProxy *url.URL // Only defined if Insights is enabled common.ReconcilerTLS } @@ -299,32 +297,10 @@ func (r *Reconciler) reconcile(ctx context.Context, cr *model.CryostatInstance) return reconcile.Result{}, nil } -func namespaceEventFilter(scheme *runtime.Scheme, namespaceList []string) predicate.Predicate { - namespaces := namespacesToSet(namespaceList) - return predicate.NewPredicateFuncs(func(object client.Object) bool { - // Restrict watch for namespaced objects to specified namespaces - if len(object.GetNamespace()) > 0 { - _, pres := namespaces[object.GetNamespace()] - if !pres { - return false - } - } - return true - }) -} - func (r *Reconciler) setupWithManager(mgr ctrl.Manager, impl reconcile.Reconciler) error { c := ctrl.NewControllerManagedBy(mgr). For(r.objectType) - // Filter watch to specified namespaces only if the CRD is namespaced and - // we're not running in AllNamespace mode - // TODO remove this once only AllNamespace mode is supported - if r.isNamespaced && len(r.Namespaces) > 0 { - r.Log.Info(fmt.Sprintf("Adding EventFilter for namespaces: %v", r.Namespaces)) - c = c.WithEventFilter(namespaceEventFilter(mgr.GetScheme(), r.Namespaces)) - } - // Watch for changes to secondary resources and requeue the owner Cryostat resources := []client.Object{&appsv1.Deployment{}, &corev1.Service{}, &corev1.Secret{}, &corev1.PersistentVolumeClaim{}, &corev1.ServiceAccount{}, &rbacv1.Role{}, &rbacv1.RoleBinding{}, &netv1.Ingress{}} @@ -595,11 +571,3 @@ func findDeployCondition(conditions []appsv1.DeploymentCondition, condType appsv } return nil } - -func namespacesToSet(namespaces []string) map[string]struct{} { - result := make(map[string]struct{}, len(namespaces)) - for _, namespace := range namespaces { - result[namespace] = struct{}{} - } - return result -} diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index cdfb547c6..4241d0ae4 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -58,9 +58,8 @@ type controllerTest struct { } type cryostatTestInput struct { - controller controllers.CommonReconciler - objs []ctrlclient.Object - watchNamespaces []string + controller controllers.CommonReconciler + objs []ctrlclient.Object test.TestReconcilerConfig *test.TestResources } @@ -83,7 +82,6 @@ func (c *controllerTest) commonBeforeEach() *cryostatTestInput { t.NewNamespace(), t.NewApiServer(), } - t.watchNamespaces = []string{t.Namespace} return t } @@ -125,7 +123,6 @@ func (t *cryostatTestInput) newReconcilerConfig(scheme *runtime.Scheme, client c RESTMapper: test.NewTESTRESTMapper(), Log: logger, ReconcilerTLS: test.NewTestReconcilerTLS(&t.TestReconcilerConfig), - Namespaces: t.watchNamespaces, InsightsProxy: insightsURL, } } diff --git a/internal/controllers/reconciler_unit_test.go b/internal/controllers/reconciler_unit_test.go deleted file mode 100644 index bec0e97de..000000000 --- a/internal/controllers/reconciler_unit_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// 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 controllers - -import ( - "github.com/cryostatio/cryostat-operator/internal/controllers/model" - "github.com/cryostatio/cryostat-operator/internal/test" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/predicate" -) - -type cryostatUnitTestInput struct { - scheme *runtime.Scheme - watchNamespaces []string - *test.TestResources -} - -var _ = Describe("Reconciler", func() { - Describe("filtering requests", func() { - Context("watches the configured namespace(s)", func() { - var t *cryostatUnitTestInput - var filter predicate.Predicate - var cr *model.CryostatInstance - - BeforeEach(func() { - resources := &test.TestResources{ - Name: "cryostat", - Namespace: "test", - } - t = &cryostatUnitTestInput{ - scheme: test.NewTestScheme(), - watchNamespaces: []string{resources.Namespace}, - TestResources: resources, - } - }) - JustBeforeEach(func() { - filter = namespaceEventFilter(t.scheme, t.watchNamespaces) - }) - Context("creating a CR in the watched namespace", func() { - BeforeEach(func() { - cr = t.NewCryostat() - }) - It("should reconcile the CR", func() { - result := filter.Create(event.CreateEvent{ - Object: cr.Object, - }) - Expect(result).To(BeTrue()) - }) - }) - Context("creating a CR in a non-watched namespace", func() { - BeforeEach(func() { - t.Namespace = "something-else" - cr = t.NewCryostat() - }) - It("should reconcile the CR", func() { - result := filter.Create(event.CreateEvent{ - Object: cr.Object, - }) - Expect(result).To(BeFalse()) - }) - }) - }) - }) -}) diff --git a/internal/main.go b/internal/main.go index 80630250c..229200b95 100644 --- a/internal/main.go +++ b/internal/main.go @@ -19,7 +19,6 @@ import ( "fmt" "net/url" "os" - "strings" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. @@ -30,12 +29,10 @@ import ( configv1 "github.com/openshift/api/config/v1" consolev1 "github.com/openshift/api/console/v1" routev1 "github.com/openshift/api/route/v1" - rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -80,26 +77,8 @@ func main() { opts.BindFlags(flag.CommandLine) flag.Parse() - watchNamespace, err := getWatchNamespace() - if err != nil { - setupLog.Error(err, "unable to get WatchNamespace, "+ - "the manager will watch and manage resources in all namespaces") - } - namespaces := []string{} - if len(watchNamespace) > 0 { - namespaces = append(namespaces, strings.Split(watchNamespace, ",")...) - } - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - // For OwnNamespace install mode, we need to see RoleBindings in other namespaces - // when used with ClusterCryostat - // https://github.com/cryostatio/cryostat-operator/issues/580 - disableCache := []client.Object{} - if len(namespaces) > 0 { - disableCache = append(disableCache, &rbacv1.RoleBinding{}) - } - // FIXME Disable metrics until this issue is resolved: // https://github.com/operator-framework/operator-sdk/issues/4684 metricsAddr = "0" @@ -110,7 +89,6 @@ func main() { HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionID: "d696d7ab.redhat.com", - ClientDisableCacheFor: disableCache, // TODO can probably remove }) if err != nil { setupLog.Error(err, "unable to start manager") @@ -156,7 +134,7 @@ func main() { } config := newReconcilerConfig(mgr, "ClusterCryostat", "clustercryostat-controller", openShift, - certManager, namespaces, insightsURL) + certManager, insightsURL) clusterController, err := controllers.NewClusterCryostatReconciler(config) if err != nil { setupLog.Error(err, "unable to create controller", "controller", "ClusterCryostat") @@ -167,7 +145,7 @@ func main() { os.Exit(1) } config = newReconcilerConfig(mgr, "Cryostat", "cryostat-controller", openShift, certManager, - namespaces, insightsURL) + insightsURL) controller, err := controllers.NewCryostatReconciler(config) if err != nil { setupLog.Error(err, "unable to create controller", "controller", "Cryostat") @@ -195,20 +173,6 @@ func main() { } } -// getWatchNamespace returns the Namespace the operator should be watching for changes -func getWatchNamespace() (string, error) { - // WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE - // which specifies the Namespace to watch. - // An empty value means the operator is running with cluster scope. - var watchNamespaceEnvVar = "WATCH_NAMESPACE" - - ns, found := os.LookupEnv(watchNamespaceEnvVar) - if !found { - return "", fmt.Errorf("%s must be set", watchNamespaceEnvVar) - } - return ns, nil -} - func isOpenShift(client discovery.DiscoveryInterface) (bool, error) { return discovery.IsResourceEnabled(client, routev1.GroupVersion.WithResource("routes")) } @@ -218,7 +182,7 @@ func isCertManagerInstalled(client discovery.DiscoveryInterface) (bool, error) { } func newReconcilerConfig(mgr ctrl.Manager, logName string, eventRecorderName string, openShift bool, - certManager bool, namespaces []string, insightsURL *url.URL) *controllers.ReconcilerConfig { + certManager bool, insightsURL *url.URL) *controllers.ReconcilerConfig { return &controllers.ReconcilerConfig{ Client: mgr.GetClient(), Log: ctrl.Log.WithName("controllers").WithName(logName), @@ -227,7 +191,6 @@ func newReconcilerConfig(mgr ctrl.Manager, logName string, eventRecorderName str IsCertManagerInstalled: certManager, EventRecorder: mgr.GetEventRecorderFor(eventRecorderName), RESTMapper: mgr.GetRESTMapper(), - Namespaces: namespaces, InsightsProxy: insightsURL, ReconcilerTLS: common.NewReconcilerTLS(&common.ReconcilerTLSConfig{ Client: mgr.GetClient(), From 1a667807f942beb3c6b2e055670ea241d00cb11a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:29:59 -0500 Subject: [PATCH 02/53] feat(discovery): options to configure discovery port names and numbers (backport #715) (#725) * feat(discovery): options to configure discovery port names and numbers (#715) Signed-off-by: Thuan Vo (cherry picked from commit a55202198f41debba71c521817c56162ebc1fce5) * resolve conflict --------- Co-authored-by: Thuan Vo Co-authored-by: Andrew Azores --- bundle/manifests/cryostat-operator.clusterserviceversion.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 5da0012f5..6cfe13ae4 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -54,7 +54,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-02-04T06:09:16Z" + createdAt: "2024-02-12T21:32:06Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { From c981a961b51bc3b74e8494ffb32e4fbe6be23531 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Tue, 13 Feb 2024 09:57:22 -0500 Subject: [PATCH 03/53] feat(api): combine Cryostat and ClusterCryostat CRDs (#721) * feat(api): combine Cryostat and ClusterCryostat CRDs * Make webhook internal, add tests * Add v1beta2 apiVersion with conversion webhook * Add conversion webhook tests * Run multi-namespace tests for Cryostat CRD * Formatting, generate bundle * Enable conversion webhooks * add conversion webhook to bundle, fixes * Remove log message * Update spec descriptors patch and initialization resource --------- Signed-off-by: Elliott Baron --- Dockerfile | 1 + PROJECT | 32 +- api/v1beta1/clustercryostat_conversion.go | 62 + api/v1beta1/clustercryostat_types.go | 1 - api/v1beta1/cryostat_conversion.go | 590 ++ api/v1beta1/cryostat_conversion_test.go | 146 + api/v1beta1/cryostat_suite_test.go | 27 + api/v1beta1/cryostat_types.go | 1 - api/v1beta2/clustercryostat_conversion.go | 24 + api/v1beta2/clustercryostat_types.go | 70 + api/v1beta2/cryostat_conversion.go | 22 + api/v1beta2/cryostat_types.go | 559 ++ api/v1beta2/groupversion_info.go | 34 + api/v1beta2/zz_generated.deepcopy.go | 893 ++++ ...t-operator-webhook-service_v1_service.yaml | 21 + ...yostat-operator.clusterserviceversion.yaml | 983 +++- ...operator.cryostat.io_clustercryostats.yaml | 4726 +++++++++++++++++ .../operator.cryostat.io_cryostats.yaml | 4721 ++++++++++++++++ ...operator.cryostat.io_clustercryostats.yaml | 4715 ++++++++++++++++ .../bases/operator.cryostat.io_cryostats.yaml | 4710 ++++++++++++++++ config/crd/kustomization.yaml | 8 +- config/crd/patches/webhook_in_cryostats.yaml | 2 + config/default/kustomization.yaml | 55 +- config/default/manager_webhook_patch.yaml | 23 + config/default/webhookcainjection_patch.yaml | 29 + ...yostat-operator.clusterserviceversion.yaml | 833 ++- config/manifests/targetNamespaces_patch.yaml | 32 + config/rbac/role.yaml | 6 + config/samples/kustomization.yaml | 2 + .../operator_v1beta2_clustercryostat.yaml | 16 + config/samples/operator_v1beta2_cryostat.yaml | 16 + config/webhook/kustomization.yaml | 6 + config/webhook/kustomizeconfig.yaml | 25 + config/webhook/manifests.yaml | 54 + config/webhook/service.yaml | 20 + internal/controllers/certmanager.go | 29 +- .../controllers/clustercryostat_controller.go | 6 +- .../clustercryostat_controller_test.go | 106 - internal/controllers/common/common_utils.go | 13 +- .../resource_definitions/certificates.go | 10 +- internal/controllers/cryostat_controller.go | 6 +- internal/controllers/ingresses.go | 24 +- internal/controllers/model/instance.go | 16 +- internal/controllers/pvc.go | 10 +- internal/controllers/rbac.go | 30 +- internal/controllers/reconciler_test.go | 223 +- internal/controllers/routes.go | 20 +- internal/controllers/services.go | 24 +- internal/main.go | 23 + internal/test/conversion.go | 638 +++ internal/test/resources.go | 161 +- internal/webhooks/cryostat_webhook.go | 44 + internal/webhooks/defaulter.go | 46 + internal/webhooks/test/resources.go | 72 + internal/webhooks/validator.go | 128 + internal/webhooks/validator_test.go | 199 + internal/webhooks/webhook_suite_test.go | 137 + 57 files changed, 25033 insertions(+), 397 deletions(-) create mode 100644 api/v1beta1/clustercryostat_conversion.go create mode 100644 api/v1beta1/cryostat_conversion.go create mode 100644 api/v1beta1/cryostat_conversion_test.go create mode 100644 api/v1beta1/cryostat_suite_test.go create mode 100644 api/v1beta2/clustercryostat_conversion.go create mode 100644 api/v1beta2/clustercryostat_types.go create mode 100644 api/v1beta2/cryostat_conversion.go create mode 100644 api/v1beta2/cryostat_types.go create mode 100644 api/v1beta2/groupversion_info.go create mode 100644 api/v1beta2/zz_generated.deepcopy.go create mode 100644 bundle/manifests/cryostat-operator-webhook-service_v1_service.yaml create mode 100644 config/default/manager_webhook_patch.yaml create mode 100644 config/default/webhookcainjection_patch.yaml create mode 100644 config/samples/operator_v1beta2_clustercryostat.yaml create mode 100644 config/samples/operator_v1beta2_cryostat.yaml create mode 100644 config/webhook/kustomization.yaml create mode 100644 config/webhook/kustomizeconfig.yaml create mode 100644 config/webhook/manifests.yaml create mode 100644 config/webhook/service.yaml create mode 100644 internal/test/conversion.go create mode 100644 internal/webhooks/cryostat_webhook.go create mode 100644 internal/webhooks/defaulter.go create mode 100644 internal/webhooks/test/resources.go create mode 100644 internal/webhooks/validator.go create mode 100644 internal/webhooks/validator_test.go create mode 100644 internal/webhooks/webhook_suite_test.go diff --git a/Dockerfile b/Dockerfile index a50eb94d6..d62951b64 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,7 @@ RUN go mod download COPY internal/main.go internal/main.go COPY api/ api/ COPY internal/controllers/ internal/controllers/ +COPY internal/webhooks/ internal/webhooks/ # Build # the GOARCH has not a default value to allow the binary be built according to the host where the command diff --git a/PROJECT b/PROJECT index 79b5f32d3..9c30663a2 100644 --- a/PROJECT +++ b/PROJECT @@ -1,3 +1,7 @@ +# Code generated by tool. DO NOT EDIT. +# This file is used to track the info used to scaffold your project +# and allow the plugins properly work. +# More info: https://book.kubebuilder.io/reference/project-config.html domain: cryostat.io layout: - go.kubebuilder.io/v3 @@ -10,7 +14,6 @@ resources: - api: crdVersion: v1 namespaced: true - controller: true domain: cryostat.io group: operator kind: Cryostat @@ -19,10 +22,35 @@ resources: - api: crdVersion: v1 namespaced: false - controller: true domain: cryostat.io group: operator kind: ClusterCryostat path: github.com/cryostatio/cryostat-operator/api/v1beta1 version: v1beta1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: cryostat.io + group: operator + kind: Cryostat + path: github.com/cryostatio/cryostat-operator/api/v1beta2 + version: v1beta2 + webhooks: + conversion: true + defaulting: true + validation: true + webhookVersion: v1 +- api: + crdVersion: v1 + namespaced: false + controller: true + domain: cryostat.io + group: operator + kind: ClusterCryostat + path: github.com/cryostatio/cryostat-operator/api/v1beta2 + version: v1beta2 + webhooks: + conversion: true + webhookVersion: v1 version: "3" diff --git a/api/v1beta1/clustercryostat_conversion.go b/api/v1beta1/clustercryostat_conversion.go new file mode 100644 index 000000000..cb7cb194c --- /dev/null +++ b/api/v1beta1/clustercryostat_conversion.go @@ -0,0 +1,62 @@ +// 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 v1beta1 + +import ( + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +// TODO Remove this file with ClusterCryostat CRD + +var _ conversion.Convertible = &ClusterCryostat{} + +// ConvertTo converts this ClusterCryostat to the Hub version (v1beta2). +func (src *ClusterCryostat) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*operatorv1beta2.ClusterCryostat) + + // Copy ObjectMeta as-is + dst.ObjectMeta = src.ObjectMeta + + // Convert existing Spec fields + convertSpecTo(&src.Spec.CryostatSpec, &dst.Spec.CryostatSpec) + dst.Spec.InstallNamespace = src.Spec.InstallNamespace + dst.Spec.TargetNamespaces = src.Spec.TargetNamespaces + + // Convert existing Status fields + convertStatusTo(&src.Status.CryostatStatus, &dst.Status.CryostatStatus) + dst.Status.TargetNamespaces = src.Spec.TargetNamespaces + + return nil +} + +// ConvertFrom converts from the Hub version (v1beta2) to this version. +func (dst *ClusterCryostat) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*operatorv1beta2.ClusterCryostat) + + // Copy ObjectMeta as-is + dst.ObjectMeta = src.ObjectMeta + + // Convert existing Spec fields + convertSpecFrom(&src.Spec.CryostatSpec, &dst.Spec.CryostatSpec) + dst.Spec.InstallNamespace = src.Spec.InstallNamespace + dst.Spec.TargetNamespaces = src.Spec.TargetNamespaces + + // Convert existing Status fields + convertStatusFrom(&src.Status.CryostatStatus, &dst.Status.CryostatStatus) + dst.Status.TargetNamespaces = src.Spec.TargetNamespaces + + return nil +} diff --git a/api/v1beta1/clustercryostat_types.go b/api/v1beta1/clustercryostat_types.go index 39190d9b4..6628164a5 100644 --- a/api/v1beta1/clustercryostat_types.go +++ b/api/v1beta1/clustercryostat_types.go @@ -49,7 +49,6 @@ type ClusterCryostatStatus struct { // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:storageversion // +kubebuilder:resource:path=clustercryostats,scope=Cluster // ClusterCryostat allows you to install Cryostat for multiple namespaces or cluster-wide. diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go new file mode 100644 index 000000000..bf6a7d73d --- /dev/null +++ b/api/v1beta1/cryostat_conversion.go @@ -0,0 +1,590 @@ +// 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 v1beta1 + +import ( + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +var _ conversion.Convertible = &Cryostat{} + +// ConvertTo converts this Cryostat to the Hub version (v1beta2). +func (src *Cryostat) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*operatorv1beta2.Cryostat) + + // Copy ObjectMeta as-is + dst.ObjectMeta = src.ObjectMeta + + // Convert existing Spec fields + convertSpecTo(&src.Spec, &dst.Spec) + + // Convert existing Status fields + convertStatusTo(&src.Status, &dst.Status) + + // Maintain the previous behaviour by using the CR's namespace as the sole target namespace + dst.Spec.TargetNamespaces = []string{src.Namespace} + dst.Status.TargetNamespaces = []string{src.Namespace} + + return nil +} + +func convertSpecTo(src *CryostatSpec, dst *operatorv1beta2.CryostatSpec) { + dst.Minimal = src.Minimal + dst.EnableCertManager = src.EnableCertManager + dst.TrustedCertSecrets = convertCertSecretsTo(src.TrustedCertSecrets) + dst.EventTemplates = convertEventTemplatesTo(src.EventTemplates) + dst.StorageOptions = convertStorageOptionsTo(src.StorageOptions) + dst.ServiceOptions = convertServiceOptionsTo(src.ServiceOptions) + dst.NetworkOptions = convertNetworkOptionsTo(src.NetworkOptions) + dst.ReportOptions = convertReportOptionsTo(src.ReportOptions) + dst.MaxWsConnections = src.MaxWsConnections + dst.JmxCacheOptions = convertJmxCacheOptionsTo(src.JmxCacheOptions) + dst.Resources = convertResourceOptionsTo(src.Resources) + dst.AuthProperties = convertAuthPropertiesTo(src.AuthProperties) + dst.SecurityOptions = convertSecurityOptionsTo(src.SecurityOptions) + dst.SchedulingOptions = convertSchedulingOptionsTo(src.SchedulingOptions) + dst.TargetDiscoveryOptions = convertTargetDiscoveryTo(src.TargetDiscoveryOptions) + dst.JmxCredentialsDatabaseOptions = convertDatabaseOptionsTo(src.JmxCredentialsDatabaseOptions) + dst.OperandMetadata = convertOperandMetadataTo(src.OperandMetadata) +} + +func convertStatusTo(src *CryostatStatus, dst *operatorv1beta2.CryostatStatus) { + dst.ApplicationURL = src.ApplicationURL + dst.Conditions = src.Conditions + dst.GrafanaSecret = src.GrafanaSecret +} + +func convertCertSecretsTo(srcCerts []CertificateSecret) []operatorv1beta2.CertificateSecret { + var dstCerts []operatorv1beta2.CertificateSecret + if srcCerts != nil { + dstCerts = make([]operatorv1beta2.CertificateSecret, 0, len(srcCerts)) + for _, cert := range srcCerts { + dstCerts = append(dstCerts, operatorv1beta2.CertificateSecret{ + SecretName: cert.SecretName, + CertificateKey: cert.CertificateKey, + }) + } + } + return dstCerts +} + +func convertEventTemplatesTo(srcTemplates []TemplateConfigMap) []operatorv1beta2.TemplateConfigMap { + var dstTemplates []operatorv1beta2.TemplateConfigMap + if srcTemplates != nil { + dstTemplates = make([]operatorv1beta2.TemplateConfigMap, 0, len(srcTemplates)) + for _, template := range srcTemplates { + dstTemplates = append(dstTemplates, operatorv1beta2.TemplateConfigMap{ + ConfigMapName: template.ConfigMapName, + Filename: template.Filename, + }) + } + } + return dstTemplates +} + +func convertStorageOptionsTo(srcOpts *StorageConfiguration) *operatorv1beta2.StorageConfiguration { + var dstOpts *operatorv1beta2.StorageConfiguration + if srcOpts != nil { + dstOpts = &operatorv1beta2.StorageConfiguration{} + if srcOpts.PVC != nil { + dstOpts.PVC = &operatorv1beta2.PersistentVolumeClaimConfig{ + Annotations: srcOpts.PVC.Annotations, + Labels: srcOpts.PVC.Labels, + Spec: srcOpts.PVC.Spec, + } + } + if srcOpts.EmptyDir != nil { + dstOpts.EmptyDir = &operatorv1beta2.EmptyDirConfig{ + Enabled: srcOpts.EmptyDir.Enabled, + Medium: srcOpts.EmptyDir.Medium, + SizeLimit: srcOpts.EmptyDir.SizeLimit, + } + } + } + return dstOpts +} + +func convertServiceOptionsTo(srcOpts *ServiceConfigList) *operatorv1beta2.ServiceConfigList { + var dstOpts *operatorv1beta2.ServiceConfigList + if srcOpts != nil { + dstOpts = &operatorv1beta2.ServiceConfigList{} + if srcOpts.CoreConfig != nil { + dstOpts.CoreConfig = &operatorv1beta2.CoreServiceConfig{ + HTTPPort: srcOpts.CoreConfig.HTTPPort, + JMXPort: srcOpts.CoreConfig.JMXPort, + ServiceConfig: convertServiceConfigTo(srcOpts.CoreConfig.ServiceConfig), + } + } + if srcOpts.GrafanaConfig != nil { + dstOpts.GrafanaConfig = &operatorv1beta2.GrafanaServiceConfig{ + HTTPPort: srcOpts.GrafanaConfig.HTTPPort, + ServiceConfig: convertServiceConfigTo(srcOpts.GrafanaConfig.ServiceConfig), + } + } + if srcOpts.ReportsConfig != nil { + dstOpts.ReportsConfig = &operatorv1beta2.ReportsServiceConfig{ + HTTPPort: srcOpts.ReportsConfig.HTTPPort, + ServiceConfig: convertServiceConfigTo(srcOpts.ReportsConfig.ServiceConfig), + } + } + } + return dstOpts +} + +func convertServiceConfigTo(srcConfig ServiceConfig) operatorv1beta2.ServiceConfig { + return operatorv1beta2.ServiceConfig{ + ServiceType: srcConfig.ServiceType, + Annotations: srcConfig.Annotations, + Labels: srcConfig.Labels, + } +} + +func convertNetworkOptionsTo(srcOpts *NetworkConfigurationList) *operatorv1beta2.NetworkConfigurationList { + var dstOpts *operatorv1beta2.NetworkConfigurationList + if srcOpts != nil { + dstOpts = &operatorv1beta2.NetworkConfigurationList{ + CoreConfig: convertNetworkConfigTo(srcOpts.CoreConfig), + GrafanaConfig: convertNetworkConfigTo(srcOpts.GrafanaConfig), + CommandConfig: convertNetworkConfigTo(srcOpts.CommandConfig), // TODO Remove this from v1beta2 API + } + } + return dstOpts +} + +func convertNetworkConfigTo(srcConfig *NetworkConfiguration) *operatorv1beta2.NetworkConfiguration { + var dstConfig *operatorv1beta2.NetworkConfiguration + if srcConfig != nil { + dstConfig = &operatorv1beta2.NetworkConfiguration{ + IngressSpec: srcConfig.IngressSpec, + Annotations: srcConfig.Annotations, + Labels: srcConfig.Labels, + } + } + return dstConfig +} + +func convertReportOptionsTo(srcOpts *ReportConfiguration) *operatorv1beta2.ReportConfiguration { + var dstOpts *operatorv1beta2.ReportConfiguration + if srcOpts != nil { + var dstSecurityOpts *operatorv1beta2.ReportsSecurityOptions + if srcOpts.SecurityOptions != nil { + dstSecurityOpts = &operatorv1beta2.ReportsSecurityOptions{ + PodSecurityContext: srcOpts.SecurityOptions.PodSecurityContext, + ReportsSecurityContext: srcOpts.SecurityOptions.ReportsSecurityContext, + } + } + dstOpts = &operatorv1beta2.ReportConfiguration{ + Replicas: srcOpts.Replicas, + Resources: srcOpts.Resources, + SubProcessMaxHeapSize: srcOpts.SubProcessMaxHeapSize, + SecurityOptions: dstSecurityOpts, + SchedulingOptions: convertSchedulingOptionsTo(srcOpts.SchedulingOptions), + } + } + return dstOpts +} + +func convertSchedulingOptionsTo(srcOpts *SchedulingConfiguration) *operatorv1beta2.SchedulingConfiguration { + var dstOpts *operatorv1beta2.SchedulingConfiguration + if srcOpts != nil { + var dstAffinity *operatorv1beta2.Affinity + if srcOpts.Affinity != nil { + dstAffinity = &operatorv1beta2.Affinity{ + NodeAffinity: srcOpts.Affinity.NodeAffinity, + PodAffinity: srcOpts.Affinity.PodAffinity, + PodAntiAffinity: srcOpts.Affinity.PodAntiAffinity, + } + } + dstOpts = &operatorv1beta2.SchedulingConfiguration{ + NodeSelector: srcOpts.NodeSelector, + Affinity: dstAffinity, + Tolerations: srcOpts.Tolerations, + } + } + return dstOpts +} + +func convertJmxCacheOptionsTo(srcOpts *JmxCacheOptions) *operatorv1beta2.JmxCacheOptions { + var dstOpts *operatorv1beta2.JmxCacheOptions + if srcOpts != nil { + dstOpts = &operatorv1beta2.JmxCacheOptions{ + TargetCacheSize: srcOpts.TargetCacheSize, + TargetCacheTTL: srcOpts.TargetCacheTTL, + } + } + return dstOpts +} + +func convertResourceOptionsTo(srcOpts *ResourceConfigList) *operatorv1beta2.ResourceConfigList { + var dstOpts *operatorv1beta2.ResourceConfigList + if srcOpts != nil { + dstOpts = &operatorv1beta2.ResourceConfigList{ + CoreResources: srcOpts.CoreResources, + DataSourceResources: srcOpts.DataSourceResources, + GrafanaResources: srcOpts.GrafanaResources, + } + } + return dstOpts +} + +func convertAuthPropertiesTo(srcProps *AuthorizationProperties) *operatorv1beta2.AuthorizationProperties { + var dstProps *operatorv1beta2.AuthorizationProperties + if srcProps != nil { + dstProps = &operatorv1beta2.AuthorizationProperties{ + ClusterRoleName: srcProps.ClusterRoleName, + ConfigMapName: srcProps.ConfigMapName, + Filename: srcProps.Filename, + } + } + return dstProps +} + +func convertSecurityOptionsTo(srcOpts *SecurityOptions) *operatorv1beta2.SecurityOptions { + var dstOpts *operatorv1beta2.SecurityOptions + if srcOpts != nil { + dstOpts = &operatorv1beta2.SecurityOptions{ + PodSecurityContext: srcOpts.PodSecurityContext, + CoreSecurityContext: srcOpts.CoreSecurityContext, + DataSourceSecurityContext: srcOpts.DataSourceSecurityContext, + GrafanaSecurityContext: srcOpts.GrafanaSecurityContext, + } + } + return dstOpts +} + +func convertTargetDiscoveryTo(srcOpts *TargetDiscoveryOptions) *operatorv1beta2.TargetDiscoveryOptions { + var dstOpts *operatorv1beta2.TargetDiscoveryOptions + if srcOpts != nil { + dstOpts = &operatorv1beta2.TargetDiscoveryOptions{ + BuiltInDiscoveryDisabled: srcOpts.BuiltInDiscoveryDisabled, + } + } + return dstOpts +} + +func convertDatabaseOptionsTo(srcOpts *JmxCredentialsDatabaseOptions) *operatorv1beta2.JmxCredentialsDatabaseOptions { + var dstOpts *operatorv1beta2.JmxCredentialsDatabaseOptions + if srcOpts != nil { + dstOpts = &operatorv1beta2.JmxCredentialsDatabaseOptions{ + DatabaseSecretName: srcOpts.DatabaseSecretName, + } + } + return dstOpts +} + +func convertOperandMetadataTo(srcOpts *OperandMetadata) *operatorv1beta2.OperandMetadata { + var dstOpts *operatorv1beta2.OperandMetadata + if srcOpts != nil { + dstOpts = &operatorv1beta2.OperandMetadata{ + DeploymentMetadata: convertResourceMetadataTo(srcOpts.DeploymentMetadata), + PodMetadata: convertResourceMetadataTo(srcOpts.PodMetadata), + } + } + return dstOpts +} + +func convertResourceMetadataTo(srcMeta *ResourceMetadata) *operatorv1beta2.ResourceMetadata { + var dstMeta *operatorv1beta2.ResourceMetadata + if srcMeta != nil { + dstMeta = &operatorv1beta2.ResourceMetadata{ + Annotations: srcMeta.Annotations, + Labels: srcMeta.Labels, + } + } + return dstMeta +} + +// ConvertFrom converts from the Hub version (v1beta2) to this version. +func (dst *Cryostat) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*operatorv1beta2.Cryostat) + + // Copy ObjectMeta as-is + dst.ObjectMeta = src.ObjectMeta + + // Convert existing Spec fields + convertSpecFrom(&src.Spec, &dst.Spec) + + // Convert existing Status fields + convertStatusFrom(&src.Status, &dst.Status) + + return nil +} + +func convertSpecFrom(src *operatorv1beta2.CryostatSpec, dst *CryostatSpec) { + dst.Minimal = src.Minimal + dst.EnableCertManager = src.EnableCertManager + dst.TrustedCertSecrets = convertCertSecretsFrom(src.TrustedCertSecrets) + dst.EventTemplates = convertEventTemplatesFrom(src.EventTemplates) + dst.StorageOptions = convertStorageOptionsFrom(src.StorageOptions) + dst.ServiceOptions = convertServiceOptionsFrom(src.ServiceOptions) + dst.NetworkOptions = convertNetworkOptionsFrom(src.NetworkOptions) + dst.ReportOptions = convertReportOptionsFrom(src.ReportOptions) + dst.MaxWsConnections = src.MaxWsConnections + dst.JmxCacheOptions = convertJmxCacheOptionsFrom(src.JmxCacheOptions) + dst.Resources = convertResourceOptionsFrom(src.Resources) + dst.AuthProperties = convertAuthPropertiesFrom(src.AuthProperties) + dst.SecurityOptions = convertSecurityOptionsFrom(src.SecurityOptions) + dst.SchedulingOptions = convertSchedulingOptionsFrom(src.SchedulingOptions) + dst.TargetDiscoveryOptions = convertTargetDiscoveryFrom(src.TargetDiscoveryOptions) + dst.JmxCredentialsDatabaseOptions = convertDatabaseOptionsFrom(src.JmxCredentialsDatabaseOptions) + dst.OperandMetadata = convertOperandMetadataFrom(src.OperandMetadata) +} + +func convertStatusFrom(src *operatorv1beta2.CryostatStatus, dst *CryostatStatus) { + dst.ApplicationURL = src.ApplicationURL + dst.Conditions = src.Conditions + dst.GrafanaSecret = src.GrafanaSecret +} + +func convertCertSecretsFrom(srcCerts []operatorv1beta2.CertificateSecret) []CertificateSecret { + var dstCerts []CertificateSecret + if srcCerts != nil { + dstCerts = make([]CertificateSecret, 0, len(srcCerts)) + for _, cert := range srcCerts { + dstCerts = append(dstCerts, CertificateSecret{ + SecretName: cert.SecretName, + CertificateKey: cert.CertificateKey, + }) + } + } + return dstCerts +} + +func convertEventTemplatesFrom(srcTemplates []operatorv1beta2.TemplateConfigMap) []TemplateConfigMap { + var dstTemplates []TemplateConfigMap + if srcTemplates != nil { + dstTemplates = make([]TemplateConfigMap, 0, len(srcTemplates)) + for _, template := range srcTemplates { + dstTemplates = append(dstTemplates, TemplateConfigMap{ + ConfigMapName: template.ConfigMapName, + Filename: template.Filename, + }) + } + } + return dstTemplates +} + +func convertStorageOptionsFrom(srcOpts *operatorv1beta2.StorageConfiguration) *StorageConfiguration { + var dstOpts *StorageConfiguration + if srcOpts != nil { + dstOpts = &StorageConfiguration{} + if srcOpts.PVC != nil { + dstOpts.PVC = &PersistentVolumeClaimConfig{ + Annotations: srcOpts.PVC.Annotations, + Labels: srcOpts.PVC.Labels, + Spec: srcOpts.PVC.Spec, + } + } + if srcOpts.EmptyDir != nil { + dstOpts.EmptyDir = &EmptyDirConfig{ + Enabled: srcOpts.EmptyDir.Enabled, + Medium: srcOpts.EmptyDir.Medium, + SizeLimit: srcOpts.EmptyDir.SizeLimit, + } + } + } + return dstOpts +} + +func convertServiceOptionsFrom(srcOpts *operatorv1beta2.ServiceConfigList) *ServiceConfigList { + var dstOpts *ServiceConfigList + if srcOpts != nil { + dstOpts = &ServiceConfigList{} + if srcOpts.CoreConfig != nil { + dstOpts.CoreConfig = &CoreServiceConfig{ + HTTPPort: srcOpts.CoreConfig.HTTPPort, + JMXPort: srcOpts.CoreConfig.JMXPort, + ServiceConfig: convertServiceConfigFrom(srcOpts.CoreConfig.ServiceConfig), + } + } + if srcOpts.GrafanaConfig != nil { + dstOpts.GrafanaConfig = &GrafanaServiceConfig{ + HTTPPort: srcOpts.GrafanaConfig.HTTPPort, + ServiceConfig: convertServiceConfigFrom(srcOpts.GrafanaConfig.ServiceConfig), + } + } + if srcOpts.ReportsConfig != nil { + dstOpts.ReportsConfig = &ReportsServiceConfig{ + HTTPPort: srcOpts.ReportsConfig.HTTPPort, + ServiceConfig: convertServiceConfigFrom(srcOpts.ReportsConfig.ServiceConfig), + } + } + } + return dstOpts +} + +func convertServiceConfigFrom(srcConfig operatorv1beta2.ServiceConfig) ServiceConfig { + return ServiceConfig{ + ServiceType: srcConfig.ServiceType, + Annotations: srcConfig.Annotations, + Labels: srcConfig.Labels, + } +} + +func convertNetworkOptionsFrom(srcOpts *operatorv1beta2.NetworkConfigurationList) *NetworkConfigurationList { + var dstOpts *NetworkConfigurationList + if srcOpts != nil { + dstOpts = &NetworkConfigurationList{ + CoreConfig: convertNetworkConfigFrom(srcOpts.CoreConfig), + GrafanaConfig: convertNetworkConfigFrom(srcOpts.GrafanaConfig), + CommandConfig: convertNetworkConfigFrom(srcOpts.CommandConfig), // TODO Remove this from v1beta2 API + } + } + return dstOpts +} + +func convertNetworkConfigFrom(srcConfig *operatorv1beta2.NetworkConfiguration) *NetworkConfiguration { + var dstConfig *NetworkConfiguration + if srcConfig != nil { + dstConfig = &NetworkConfiguration{ + IngressSpec: srcConfig.IngressSpec, + Annotations: srcConfig.Annotations, + Labels: srcConfig.Labels, + } + } + return dstConfig +} + +func convertReportOptionsFrom(srcOpts *operatorv1beta2.ReportConfiguration) *ReportConfiguration { + var dstOpts *ReportConfiguration + if srcOpts != nil { + var dstSecurityOpts *ReportsSecurityOptions + if srcOpts.SecurityOptions != nil { + dstSecurityOpts = &ReportsSecurityOptions{ + PodSecurityContext: srcOpts.SecurityOptions.PodSecurityContext, + ReportsSecurityContext: srcOpts.SecurityOptions.ReportsSecurityContext, + } + } + dstOpts = &ReportConfiguration{ + Replicas: srcOpts.Replicas, + Resources: srcOpts.Resources, + SubProcessMaxHeapSize: srcOpts.SubProcessMaxHeapSize, + SecurityOptions: dstSecurityOpts, + SchedulingOptions: convertSchedulingOptionsFrom(srcOpts.SchedulingOptions), + } + } + return dstOpts +} + +func convertSchedulingOptionsFrom(srcOpts *operatorv1beta2.SchedulingConfiguration) *SchedulingConfiguration { + var dstOpts *SchedulingConfiguration + if srcOpts != nil { + var dstAffinity *Affinity + if srcOpts.Affinity != nil { + dstAffinity = &Affinity{ + NodeAffinity: srcOpts.Affinity.NodeAffinity, + PodAffinity: srcOpts.Affinity.PodAffinity, + PodAntiAffinity: srcOpts.Affinity.PodAntiAffinity, + } + } + dstOpts = &SchedulingConfiguration{ + NodeSelector: srcOpts.NodeSelector, + Affinity: dstAffinity, + Tolerations: srcOpts.Tolerations, + } + } + return dstOpts +} + +func convertJmxCacheOptionsFrom(srcOpts *operatorv1beta2.JmxCacheOptions) *JmxCacheOptions { + var dstOpts *JmxCacheOptions + if srcOpts != nil { + dstOpts = &JmxCacheOptions{ + TargetCacheSize: srcOpts.TargetCacheSize, + TargetCacheTTL: srcOpts.TargetCacheTTL, + } + } + return dstOpts +} + +func convertResourceOptionsFrom(srcOpts *operatorv1beta2.ResourceConfigList) *ResourceConfigList { + var dstOpts *ResourceConfigList + if srcOpts != nil { + dstOpts = &ResourceConfigList{ + CoreResources: srcOpts.CoreResources, + DataSourceResources: srcOpts.DataSourceResources, + GrafanaResources: srcOpts.GrafanaResources, + } + } + return dstOpts +} + +func convertAuthPropertiesFrom(srcProps *operatorv1beta2.AuthorizationProperties) *AuthorizationProperties { + var dstProps *AuthorizationProperties + if srcProps != nil { + dstProps = &AuthorizationProperties{ + ClusterRoleName: srcProps.ClusterRoleName, + ConfigMapName: srcProps.ConfigMapName, + Filename: srcProps.Filename, + } + } + return dstProps +} + +func convertSecurityOptionsFrom(srcOpts *operatorv1beta2.SecurityOptions) *SecurityOptions { + var dstOpts *SecurityOptions + if srcOpts != nil { + dstOpts = &SecurityOptions{ + PodSecurityContext: srcOpts.PodSecurityContext, + CoreSecurityContext: srcOpts.CoreSecurityContext, + DataSourceSecurityContext: srcOpts.DataSourceSecurityContext, + GrafanaSecurityContext: srcOpts.GrafanaSecurityContext, + } + } + return dstOpts +} + +func convertTargetDiscoveryFrom(srcOpts *operatorv1beta2.TargetDiscoveryOptions) *TargetDiscoveryOptions { + var dstOpts *TargetDiscoveryOptions + if srcOpts != nil { + dstOpts = &TargetDiscoveryOptions{ + BuiltInDiscoveryDisabled: srcOpts.BuiltInDiscoveryDisabled, + } + } + return dstOpts +} + +func convertDatabaseOptionsFrom(srcOpts *operatorv1beta2.JmxCredentialsDatabaseOptions) *JmxCredentialsDatabaseOptions { + var dstOpts *JmxCredentialsDatabaseOptions + if srcOpts != nil { + dstOpts = &JmxCredentialsDatabaseOptions{ + DatabaseSecretName: srcOpts.DatabaseSecretName, + } + } + return dstOpts +} + +func convertOperandMetadataFrom(srcOpts *operatorv1beta2.OperandMetadata) *OperandMetadata { + var dstOpts *OperandMetadata + if srcOpts != nil { + dstOpts = &OperandMetadata{ + DeploymentMetadata: convertResourceMetadataFrom(srcOpts.DeploymentMetadata), + PodMetadata: convertResourceMetadataFrom(srcOpts.PodMetadata), + } + } + return dstOpts +} + +func convertResourceMetadataFrom(srcMeta *operatorv1beta2.ResourceMetadata) *ResourceMetadata { + var dstMeta *ResourceMetadata + if srcMeta != nil { + dstMeta = &ResourceMetadata{ + Annotations: srcMeta.Annotations, + Labels: srcMeta.Labels, + } + } + return dstMeta +} diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go new file mode 100644 index 000000000..37b78304c --- /dev/null +++ b/api/v1beta1/cryostat_conversion_test.go @@ -0,0 +1,146 @@ +// 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 v1beta1_test + +import ( + operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "github.com/cryostatio/cryostat-operator/internal/controllers/model" + "github.com/cryostatio/cryostat-operator/internal/test" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +type conversionTestInput struct { + *test.TestResources +} + +var _ = Describe("Cryostat", func() { + var t *conversionTestInput + + BeforeEach(func() { + t = &conversionTestInput{ + TestResources: &test.TestResources{ + Name: "cryostat", + Namespace: "test", + TargetNamespaces: []string{"test"}, + }, + } + }) + + DescribeTable("converting from v1beta1 to v1beta2", + func(oldFunc func(*test.TestResources) *operatorv1beta1.Cryostat, newFunc func(*test.TestResources) *model.CryostatInstance) { + oldCR := oldFunc(t.TestResources) + newCRModel := newFunc(t.TestResources) + Expect(newCRModel.Object).To(BeAssignableToTypeOf(&operatorv1beta2.Cryostat{})) + newCR := newCRModel.Object.(*operatorv1beta2.Cryostat) + // Fill in Status.TargetNamespaces + newCR.Status.TargetNamespaces = newCR.Spec.TargetNamespaces + + converted := &operatorv1beta2.Cryostat{} + err := oldCR.ConvertTo(converted) + Expect(err).ToNot(HaveOccurred()) + + Expect(converted).To(Equal(newCR)) + }, + tableEntries(), + ) + + DescribeTable("converting from v1beta2 to v1beta1", + func(oldFunc func(*test.TestResources) *operatorv1beta1.Cryostat, newFunc func(*test.TestResources) *model.CryostatInstance) { + oldCR := oldFunc(t.TestResources) + newCRModel := newFunc(t.TestResources) + Expect(newCRModel.Object).To(BeAssignableToTypeOf(&operatorv1beta2.Cryostat{})) + newCR := newCRModel.Object.(*operatorv1beta2.Cryostat) + + converted := &operatorv1beta1.Cryostat{} + err := converted.ConvertFrom(newCR) + Expect(err).ToNot(HaveOccurred()) + + Expect(converted).To(Equal(oldCR)) + }, + tableEntries(), + ) + +}) + +func tableEntries() []TableEntry { + return []TableEntry{ + Entry("defaults", (*test.TestResources).NewCryostatV1Beta1, + (*test.TestResources).NewCryostat), + Entry("secrets", (*test.TestResources).NewCryostatWithSecretsV1Beta1, + (*test.TestResources).NewCryostatWithSecrets), + Entry("templates", (*test.TestResources).NewCryostatWithTemplatesV1Beta1, + (*test.TestResources).NewCryostatWithTemplates), + Entry("ingress", (*test.TestResources).NewCryostatWithIngressV1Beta1, + (*test.TestResources).NewCryostatWithIngress), + Entry("ingress with cert-manager disabled", (*test.TestResources).NewCryostatWithIngressCertManagerDisabledV1Beta1, + (*test.TestResources).NewCryostatWithIngressCertManagerDisabled), + Entry("PVC spec", (*test.TestResources).NewCryostatWithPVCSpecV1Beta1, + (*test.TestResources).NewCryostatWithPVCSpec), + Entry("PVC spec with some defaults", (*test.TestResources).NewCryostatWithPVCSpecSomeDefaultV1Beta1, + (*test.TestResources).NewCryostatWithPVCSpecSomeDefault), + Entry("PVC spec with labels only", (*test.TestResources).NewCryostatWithPVCLabelsOnlyV1Beta1, + (*test.TestResources).NewCryostatWithPVCLabelsOnly), + Entry("default emptyDir", (*test.TestResources).NewCryostatWithDefaultEmptyDirV1Beta1, + (*test.TestResources).NewCryostatWithDefaultEmptyDir), + Entry("custom emptyDir", (*test.TestResources).NewCryostatWithEmptyDirSpecV1Beta1, + (*test.TestResources).NewCryostatWithEmptyDirSpec), + Entry("core service", (*test.TestResources).NewCryostatWithCoreSvcV1Beta1, + (*test.TestResources).NewCryostatWithCoreSvc), + Entry("Grafana service", (*test.TestResources).NewCryostatWithGrafanaSvcV1Beta1, + (*test.TestResources).NewCryostatWithGrafanaSvc), + Entry("reports service", (*test.TestResources).NewCryostatWithReportsSvcV1Beta1, + (*test.TestResources).NewCryostatWithReportsSvc), + Entry("core ingress", (*test.TestResources).NewCryostatWithCoreNetworkOptionsV1Beta1, + (*test.TestResources).NewCryostatWithCoreNetworkOptions), + Entry("Grafana ingress", (*test.TestResources).NewCryostatWithGrafanaNetworkOptionsV1Beta1, + (*test.TestResources).NewCryostatWithGrafanaNetworkOptions), + Entry("reports resources", (*test.TestResources).NewCryostatWithReportsResourcesV1Beta1, + (*test.TestResources).NewCryostatWithReportsResources), + Entry("reports low resource limit", (*test.TestResources).NewCryostatWithReportLowResourceLimitV1Beta1, + (*test.TestResources).NewCryostatWithReportLowResourceLimit), + Entry("scheduling", (*test.TestResources).NewCryostatWithSchedulingV1Beta1, + (*test.TestResources).NewCryostatWithScheduling), + Entry("reports scheduling", (*test.TestResources).NewCryostatWithReportsSchedulingV1Beta1, + (*test.TestResources).NewCryostatWithReportsScheduling), + Entry("cert-manager disabled", (*test.TestResources).NewCryostatCertManagerDisabledV1Beta1, + (*test.TestResources).NewCryostatCertManagerDisabled), + Entry("cert-manager undefined", (*test.TestResources).NewCryostatCertManagerUndefinedV1Beta1, + (*test.TestResources).NewCryostatCertManagerUndefined), + Entry("resources", (*test.TestResources).NewCryostatWithResourcesV1Beta1, + (*test.TestResources).NewCryostatWithResources), + Entry("low resource limit", (*test.TestResources).NewCryostatWithLowResourceLimitV1Beta1, + (*test.TestResources).NewCryostatWithLowResourceLimit), + Entry("auth properties", (*test.TestResources).NewCryostatWithAuthPropertiesV1Beta1, + (*test.TestResources).NewCryostatWithAuthProperties), + Entry("built-in discovery disabled", (*test.TestResources).NewCryostatWithBuiltInDiscoveryDisabledV1Beta1, + (*test.TestResources).NewCryostatWithBuiltInDiscoveryDisabled), + Entry("JMX cache options", (*test.TestResources).NewCryostatWithJmxCacheOptionsSpecV1Beta1, + (*test.TestResources).NewCryostatWithJmxCacheOptionsSpec), + Entry("WS connections", (*test.TestResources).NewCryostatWithWsConnectionsSpecV1Beta1, + (*test.TestResources).NewCryostatWithWsConnectionsSpec), + Entry("subprocess heap", (*test.TestResources).NewCryostatWithReportSubprocessHeapSpecV1Beta1, + (*test.TestResources).NewCryostatWithReportSubprocessHeapSpec), + Entry("security", (*test.TestResources).NewCryostatWithSecurityOptionsV1Beta1, + (*test.TestResources).NewCryostatWithSecurityOptions), + Entry("reports security", (*test.TestResources).NewCryostatWithReportSecurityOptionsV1Beta1, + (*test.TestResources).NewCryostatWithReportSecurityOptions), + Entry("database secret", (*test.TestResources).NewCryostatWithDatabaseSecretProvidedV1Beta1, + (*test.TestResources).NewCryostatWithDatabaseSecretProvided), + Entry("metadata", (*test.TestResources).NewCryostatWithAdditionalMetadataV1Beta1, + (*test.TestResources).NewCryostatWithAdditionalMetadata), + } +} diff --git a/api/v1beta1/cryostat_suite_test.go b/api/v1beta1/cryostat_suite_test.go new file mode 100644 index 000000000..b16274daa --- /dev/null +++ b/api/v1beta1/cryostat_suite_test.go @@ -0,0 +1,27 @@ +// 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 v1beta1_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestBooks(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Cryostat Suite") +} diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 1270866a6..a480a28c6 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -414,7 +414,6 @@ type JmxCacheOptions struct { // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:storageversion // +kubebuilder:resource:path=cryostats,scope=Namespaced // Cryostat allows you to install Cryostat for a single namespace. diff --git a/api/v1beta2/clustercryostat_conversion.go b/api/v1beta2/clustercryostat_conversion.go new file mode 100644 index 000000000..2f1604627 --- /dev/null +++ b/api/v1beta2/clustercryostat_conversion.go @@ -0,0 +1,24 @@ +// 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 v1beta2 + +import "sigs.k8s.io/controller-runtime/pkg/conversion" + +// TODO Remove this file with ClusterCryostat CRD + +var _ conversion.Hub = &ClusterCryostat{} + +// Hub marks this type as a conversion hub. +func (*ClusterCryostat) Hub() {} diff --git a/api/v1beta2/clustercryostat_types.go b/api/v1beta2/clustercryostat_types.go new file mode 100644 index 000000000..686a970fa --- /dev/null +++ b/api/v1beta2/clustercryostat_types.go @@ -0,0 +1,70 @@ +// 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 v1beta2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ClusterCryostatSpec defines the desired state of ClusterCryostat. +type ClusterCryostatSpec struct { + // Namespace where Cryostat should be installed. + // On multi-tenant clusters, we strongly suggest installing Cryostat into + // its own namespace. + // +operator-sdk:csv:customresourcedefinitions:type=spec,order=1,xDescriptors={"urn:alm:descriptor:io.kubernetes:Namespace"} + InstallNamespace string `json:"installNamespace"` + // +operator-sdk:csv:customresourcedefinitions:type=spec + CryostatSpec `json:",inline"` +} + +// ClusterCryostatStatus defines the observed state of ClusterCryostat. +type ClusterCryostatStatus struct { + // +operator-sdk:csv:customresourcedefinitions:type=status + CryostatStatus `json:",inline"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:path=clustercryostats,scope=Cluster + +// ClusterCryostat allows you to install Cryostat for multiple namespaces or cluster-wide. +// It contains configuration options for controlling the Deployment of the Cryostat +// application and its related components. +// A ClusterCryostat or Cryostat instance must be created to instruct the operator +// to deploy the Cryostat application. +// +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} +// +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` +// +kubebuilder:printcolumn:name="Grafana Secret",type=string,JSONPath=`.status.grafanaSecret` +type ClusterCryostat struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterCryostatSpec `json:"spec,omitempty"` + Status ClusterCryostatStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ClusterCryostatList contains a list of ClusterCryostat +type ClusterCryostatList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterCryostat `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ClusterCryostat{}, &ClusterCryostatList{}) +} diff --git a/api/v1beta2/cryostat_conversion.go b/api/v1beta2/cryostat_conversion.go new file mode 100644 index 000000000..8086d775c --- /dev/null +++ b/api/v1beta2/cryostat_conversion.go @@ -0,0 +1,22 @@ +// 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 v1beta2 + +import "sigs.k8s.io/controller-runtime/pkg/conversion" + +var _ conversion.Hub = &Cryostat{} + +// Hub marks this type as a conversion hub. +func (*Cryostat) Hub() {} diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go new file mode 100644 index 000000000..1fc0d947d --- /dev/null +++ b/api/v1beta2/cryostat_types.go @@ -0,0 +1,559 @@ +// 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 v1beta2 + +import ( + corev1 "k8s.io/api/core/v1" + netv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +// CryostatSpec defines the desired state of Cryostat. +type CryostatSpec struct { + // List of namespaces whose workloads Cryostat should be + // permitted to access and profile. Defaults to this Cryostat's namespace. + // Warning: All Cryostat users will be able to create and manage + // recordings for workloads in the listed namespaces. + // More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,order=2 + TargetNamespaces []string `json:"targetNamespaces,omitempty"` + // Deploy a pared-down Cryostat instance with no Grafana Dashboard or JFR Data Source. + // +operator-sdk:csv:customresourcedefinitions:type=spec,order=4,displayName="Minimal Deployment",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Minimal bool `json:"minimal"` + // List of TLS certificates to trust when connecting to targets. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Trusted TLS Certificates" + TrustedCertSecrets []CertificateSecret `json:"trustedCertSecrets,omitempty"` + // List of Flight Recorder Event Templates to preconfigure in Cryostat. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Event Templates" + EventTemplates []TemplateConfigMap `json:"eventTemplates,omitempty"` + // Use cert-manager to secure in-cluster communication between Cryostat components. + // Requires cert-manager to be installed. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,order=3,displayName="Enable cert-manager Integration",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + EnableCertManager *bool `json:"enableCertManager"` + // Options to customize the storage for Flight Recordings and Templates. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + StorageOptions *StorageConfiguration `json:"storageOptions,omitempty"` + // Options to customize the services created for the Cryostat application and Grafana dashboard. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + ServiceOptions *ServiceConfigList `json:"serviceOptions,omitempty"` + // Options to control how the operator exposes the application outside of the cluster, + // such as using an Ingress or Route. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + NetworkOptions *NetworkConfigurationList `json:"networkOptions,omitempty"` + // Options to configure Cryostat Automated Report Analysis. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + ReportOptions *ReportConfiguration `json:"reportOptions,omitempty"` + // The maximum number of WebSocket client connections allowed (minimum 1, default unlimited). + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Max WebSocket Connections",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} + // +kubebuilder:validation:Minimum=1 + MaxWsConnections int32 `json:"maxWsConnections,omitempty"` + // Options to customize the JMX target connections cache for the Cryostat application. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="JMX Connections Cache Options" + JmxCacheOptions *JmxCacheOptions `json:"jmxCacheOptions,omitempty"` + // Resource requirements for the Cryostat deployment. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + Resources *ResourceConfigList `json:"resources,omitempty"` + // Override default authorization properties for Cryostat on OpenShift. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} + AuthProperties *AuthorizationProperties `json:"authProperties,omitempty"` + // Options to configure the Security Contexts for the Cryostat application. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} + SecurityOptions *SecurityOptions `json:"securityOptions,omitempty"` + // Options to configure scheduling for the Cryostat deployment + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + SchedulingOptions *SchedulingConfiguration `json:"schedulingOptions,omitempty"` + // Options to configure the Cryostat application's target discovery mechanisms. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + TargetDiscoveryOptions *TargetDiscoveryOptions `json:"targetDiscoveryOptions,omitempty"` + // Options to configure the Cryostat application's credentials database. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Credentials Database Options" + JmxCredentialsDatabaseOptions *JmxCredentialsDatabaseOptions `json:"jmxCredentialsDatabaseOptions,omitempty"` + // Options to configure the Cryostat deployments and pods metadata + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Operand metadata" + OperandMetadata *OperandMetadata `json:"operandMetadata,omitempty"` +} + +type OperandMetadata struct { + // Options to configure the Cryostat deployments metadata + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Deployments metadata" + DeploymentMetadata *ResourceMetadata `json:"deploymentMetadata,omitempty"` + // Options to configure the Cryostat pods metadata + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Pods metadata" + PodMetadata *ResourceMetadata `json:"podMetadata,omitempty"` +} + +type ResourceMetadata struct { + // Annotations to add to the resources during its creation. + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + // Labels to add to the resources during its creation. + // The labels with keys "app" and "component" are reserved + // for use by the operator. + // +optional + Labels map[string]string `json:"labels,omitempty"` +} + +type ResourceConfigList struct { + // Resource requirements for the Cryostat application. If specifying a memory limit, at least 768MiB is recommended. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + CoreResources corev1.ResourceRequirements `json:"coreResources,omitempty"` + // Resource requirements for the JFR Data Source container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + DataSourceResources corev1.ResourceRequirements `json:"dataSourceResources,omitempty"` + // Resource requirements for the Grafana container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + GrafanaResources corev1.ResourceRequirements `json:"grafanaResources,omitempty"` +} + +// CryostatStatus defines the observed state of Cryostat. +type CryostatStatus struct { + // List of namespaces that Cryostat has been configured + // and authorized to access and profile. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=status,order=3 + TargetNamespaces []string `json:"targetNamespaces,omitempty"` + // Conditions of the components managed by the Cryostat Operator. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Cryostat Conditions",xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"} + Conditions []metav1.Condition `json:"conditions,omitempty"` + // Name of the Secret containing the generated Grafana credentials. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=status,order=2,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} + GrafanaSecret string `json:"grafanaSecret,omitempty"` + // Address of the deployed Cryostat web application. + // +operator-sdk:csv:customresourcedefinitions:type=status,order=1,xDescriptors={"urn:alm:descriptor:org.w3:link"} + ApplicationURL string `json:"applicationUrl"` +} + +// CryostatConditionType refers to a Condition type that may be used in status.conditions +type CryostatConditionType string + +const ( + // Whether the main Cryostat deployment is available. + ConditionTypeMainDeploymentAvailable CryostatConditionType = "MainDeploymentAvailable" + // Whether the main Cryostat deployment is progressing. + ConditionTypeMainDeploymentProgressing CryostatConditionType = "MainDeploymentProgressing" + // If pods within the main Cryostat deployment failed to be created or destroyed. + ConditionTypeMainDeploymentReplicaFailure CryostatConditionType = "MainDeploymentReplicaFailure" + // If enabled, whether the reports deployment is available. + ConditionTypeReportsDeploymentAvailable CryostatConditionType = "ReportsDeploymentAvailable" + // If enabled, whether the reports deployment is progressing. + ConditionTypeReportsDeploymentProgressing CryostatConditionType = "ReportsDeploymentProgressing" + // If enabled, whether pods in the reports deployment failed to be created or destroyed. + ConditionTypeReportsDeploymentReplicaFailure CryostatConditionType = "ReportsDeploymentReplicaFailure" + // If enabled, whether TLS setup is complete for the Cryostat components. + ConditionTypeTLSSetupComplete CryostatConditionType = "TLSSetupComplete" +) + +// StorageConfiguration provides customization to the storage created by +// the operator to hold Flight Recordings and Recording Templates. If no +// configurations are specified, a PVC will be created by default. +type StorageConfiguration struct { + // Configuration for the Persistent Volume Claim to be created + // by the operator. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + PVC *PersistentVolumeClaimConfig `json:"pvc,omitempty"` + // Configuration for an EmptyDir to be created + // by the operator instead of a PVC. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + EmptyDir *EmptyDirConfig `json:"emptyDir,omitempty"` +} + +// ReportConfiguration is used to determine how many replicas of cryostat-reports +// the operator should create and what the resource limits of those containers +// should be. If no replicas are created then Cryostat is configured to use basic +// subprocess report generation. If at least one replica is created then Cryostat +// is configured to use remote report generation, pointed at a load balancer service +// in front of the cryostat-reports replicas. +type ReportConfiguration struct { + // The number of report sidecar replica containers to deploy. + // Each replica can service one report generation request at a time. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"} + Replicas int32 `json:"replicas,omitempty"` + // The resources allocated to each sidecar replica. + // A replica with more resources can handle larger input recordings and will process them faster. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + Resources corev1.ResourceRequirements `json:"resources,omitempty"` + // When zero report sidecar replicas are requested, SubProcessMaxHeapSize configures + // the maximum heap size of the basic subprocess report generator in MiB. + // The default heap size is `200` (MiB). + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} + SubProcessMaxHeapSize int32 `json:"subProcessMaxHeapSize,omitempty"` + // Options to configure the Security Contexts for the Cryostat report generator. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} + SecurityOptions *ReportsSecurityOptions `json:"securityOptions,omitempty"` + // Options to configure scheduling for the reports deployment + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + SchedulingOptions *SchedulingConfiguration `json:"schedulingOptions,omitempty"` +} + +// SchedulingConfiguration contains multiple choices to control scheduling of Cryostat pods +type SchedulingConfiguration struct { + // Label selector used to schedule a Cryostat pod to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node"} + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // Affinity rules for scheduling Cryostat pods. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + Affinity *Affinity `json:"affinity,omitempty"` + // Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` +} + +// Affinity groups different kinds of affinity configurations for Cryostat pods +type Affinity struct { + // Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:nodeAffinity"} + NodeAffinity *corev1.NodeAffinity `json:"nodeAffinity,omitempty"` + // Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podAffinity"} + PodAffinity *corev1.PodAffinity `json:"podAffinity,omitempty"` + // Pod anti-affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podAntiAffinity"} + PodAntiAffinity *corev1.PodAntiAffinity `json:"podAntiAffinity,omitempty"` +} + +// ServiceConfig provides customization for a service created +// by the operator. +type ServiceConfig struct { + // Type of service to create. Defaults to "ClusterIP". + // +optional + ServiceType *corev1.ServiceType `json:"serviceType,omitempty"` + // Annotations to add to the service during its creation. + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + // Labels to add to the service during its creation. + // The labels with keys "app" and "component" are reserved + // for use by the operator. + // +optional + Labels map[string]string `json:"labels,omitempty"` +} + +// CoreServiceConfig provides customization for the service handling +// traffic for the Cryostat application. +type CoreServiceConfig struct { + // HTTP port number for the Cryostat application service. + // Defaults to 8181. + // +optional + HTTPPort *int32 `json:"httpPort,omitempty"` + // Remote JMX port number for the Cryostat application service. + // Defaults to 9091. + // +optional + JMXPort *int32 `json:"jmxPort,omitempty"` + ServiceConfig `json:",inline"` +} + +// GrafanaServiceConfig provides customization for the service handling +// traffic for the Grafana dashboard. +type GrafanaServiceConfig struct { + // HTTP port number for the Grafana dashboard service. + // Defaults to 3000. + // +optional + HTTPPort *int32 `json:"httpPort,omitempty"` + ServiceConfig `json:",inline"` +} + +// ReportsServiceConfig provides customization for the service handling +// traffic for the cryostat-reports sidecars. +type ReportsServiceConfig struct { + // HTTP port number for the cryostat-reports service. + // Defaults to 10000. + // +optional + HTTPPort *int32 `json:"httpPort,omitempty"` + ServiceConfig `json:",inline"` +} + +// ServiceConfigList holds the service configuration for each +// service created by the operator. +type ServiceConfigList struct { + // Specification for the service responsible for the Cryostat application. + // +optional + CoreConfig *CoreServiceConfig `json:"coreConfig,omitempty"` + // Specification for the service responsible for the Cryostat Grafana dashboard. + // +optional + GrafanaConfig *GrafanaServiceConfig `json:"grafanaConfig,omitempty"` + // Specification for the service responsible for the cryostat-reports sidecars. + // +optional + ReportsConfig *ReportsServiceConfig `json:"reportsConfig,omitempty"` +} + +// NetworkConfiguration provides customization for how to expose a Cryostat +// service, so that it can be reached from outside the cluster. +// On OpenShift, a Route is created by default. On Kubernetes, an Ingress will +// be created if the IngressSpec is defined within this NetworkConfiguration. +type NetworkConfiguration struct { + // Configuration for an Ingress object. + // Currently subpaths are not supported, so unique hosts must be specified + // (if a single external IP is being used) to differentiate between ingresses/services. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + IngressSpec *netv1.IngressSpec `json:"ingressSpec,omitempty"` + // Annotations to add to the Ingress or Route during its creation. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + Annotations map[string]string `json:"annotations,omitempty"` + // Labels to add to the Ingress or Route during its creation. + // The label with key "app" is reserved for use by the operator. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + Labels map[string]string `json:"labels,omitempty"` +} + +// NetworkConfigurationList holds NetworkConfiguration objects that specify +// how to expose the services created by the operator for the main Cryostat +// deployment. +type NetworkConfigurationList struct { + // Specifications for how to expose the Cryostat service, + // which serves the Cryostat application. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + CoreConfig *NetworkConfiguration `json:"coreConfig,omitempty"` + // Specifications for how to expose the Cryostat command service, + // which serves the WebSocket command channel. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:hidden"} + // + // Deprecated: CommandConfig is no longer used. + CommandConfig *NetworkConfiguration `json:"commandConfig,omitempty"` + // Specifications for how to expose Cryostat's Grafana service, + // which serves the Grafana dashboard. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + GrafanaConfig *NetworkConfiguration `json:"grafanaConfig,omitempty"` +} + +// PersistentVolumeClaimConfig holds all customization options to +// configure a Persistent Volume Claim to be created and managed +// by the operator. +type PersistentVolumeClaimConfig struct { + // Annotations to add to the Persistent Volume Claim during its creation. + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + // Labels to add to the Persistent Volume Claim during its creation. + // The label with key "app" is reserved for use by the operator. + // +optional + Labels map[string]string `json:"labels,omitempty"` + // Spec for a Persistent Volume Claim, whose options will override the + // defaults used by the operator. Unless overriden, the PVC will be + // created with the default Storage Class and 500MiB of storage. + // Once the operator has created the PVC, changes to this field have + // no effect. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + Spec *corev1.PersistentVolumeClaimSpec `json:"spec,omitempty"` +} + +// EmptyDirConfig holds all customization options to +// configure an EmptyDir to be created and managed +// by the operator. +type EmptyDirConfig struct { + // When enabled, Cryostat will use EmptyDir volumes instead of a Persistent Volume Claim. Any PVC configurations will be ignored. + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Enabled bool `json:"enabled,omitempty"` + // Unless specified, the emptyDir volume will be mounted on + // the same storage medium backing the node. Setting this field to + // "Memory" will mount the emptyDir on a tmpfs (RAM-backed filesystem). + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true"} + Medium corev1.StorageMedium `json:"medium,omitempty"` + // The maximum memory limit for the emptyDir. Default is unbounded. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true"} + // +kubebuilder:validation:Pattern=^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + SizeLimit string `json:"sizeLimit,omitempty"` +} + +// JmxCacheConfig provides customization for the JMX target connections +// cache for the Cryostat application. +type JmxCacheOptions struct { + // The maximum number of JMX connections to cache. Use `-1` for an unlimited cache size (TTL expiration only). Defaults to `-1`. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} + // +kubebuilder:validation:Minimum=-1 + TargetCacheSize int32 `json:"targetCacheSize,omitempty"` + // The time to live (in seconds) for cached JMX connections. Defaults to `10`. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} + // +kubebuilder:validation:Minimum=1 + TargetCacheTTL int32 `json:"targetCacheTTL,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:path=cryostats,scope=Namespaced + +// Cryostat allows you to install Cryostat for a single namespace. +// It contains configuration options for controlling the Deployment of the Cryostat +// application and its related components. +// A ClusterCryostat or Cryostat instance must be created to instruct the operator +// to deploy the Cryostat application. +// +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} +// +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` +// +kubebuilder:printcolumn:name="Grafana Secret",type=string,JSONPath=`.status.grafanaSecret` +type Cryostat struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CryostatSpec `json:"spec,omitempty"` + Status CryostatStatus `json:"status,omitempty"` +} + +// ConvertFrom implements conversion.Convertible. +func (*Cryostat) ConvertFrom(src conversion.Hub) error { + panic("unimplemented") +} + +// ConvertTo implements conversion.Convertible. +func (*Cryostat) ConvertTo(dst conversion.Hub) error { + panic("unimplemented") +} + +// +kubebuilder:object:root=true + +// CryostatList contains a list of Cryostat +type CryostatList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Cryostat `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Cryostat{}, &CryostatList{}) +} + +// DefaultCertificateKey will be used when looking up the certificate within a secret, +// if a key is not manually specified. +const DefaultCertificateKey = corev1.TLSCertKey + +type CertificateSecret struct { + // Name of secret in the local namespace. + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} + SecretName string `json:"secretName"` + // Key within secret containing the certificate. + // +optional + CertificateKey *string `json:"certificateKey,omitempty"` +} + +// A ConfigMap containing a .jfc template file. +type TemplateConfigMap struct { + // Name of config map in the local namespace. + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ConfigMap"} + ConfigMapName string `json:"configMapName"` + // Filename within config map containing the template file. + Filename string `json:"filename"` +} + +// Authorization properties provide custom permission mapping between Cryostat resources to Kubernetes resources. +// If the mapping is updated, Cryostat must be manually restarted. +type AuthorizationProperties struct { + // Name of the ClusterRole to use when Cryostat requests a role-scoped OAuth token. + // This ClusterRole should contain permissions for all Kubernetes objects listed in custom permission mapping. + // More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="ClusterRole Name",xDescriptors={"urn:alm:descriptor:io.kubernetes:ClusterRole"} + ClusterRoleName string `json:"clusterRoleName"` + // Name of config map in the local namespace. + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="ConfigMap Name",xDescriptors={"urn:alm:descriptor:io.kubernetes:ConfigMap"} + ConfigMapName string `json:"configMapName"` + // Filename within config map containing the resource mapping. + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + Filename string `json:"filename"` +} + +// SecurityOptions contains Security Context customizations for the +// main Cryostat application at both the pod and container level. +type SecurityOptions struct { + // Security Context to apply to the Cryostat pod. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` + // Security Context to apply to the Cryostat application container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + CoreSecurityContext *corev1.SecurityContext `json:"coreSecurityContext,omitempty"` + // Security Context to apply to the JFR Data Source container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + DataSourceSecurityContext *corev1.SecurityContext `json:"dataSourceSecurityContext,omitempty"` + // Security Context to apply to the Grafana container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + GrafanaSecurityContext *corev1.SecurityContext `json:"grafanaSecurityContext,omitempty"` +} + +// ReportsSecurityOptions contains Security Context customizations for the +// Cryostat report generator at both the pod and container level. +type ReportsSecurityOptions struct { + // Security Context to apply to the Cryostat report generator pod. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` + // Security Context to apply to the Cryostat report generator container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + ReportsSecurityContext *corev1.SecurityContext `json:"reportsSecurityContext,omitempty"` +} + +// TargetDiscoveryOptions provides configuration options to the Cryostat application's target discovery mechanisms. +type TargetDiscoveryOptions struct { + // When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable Built-in Discovery",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + BuiltInDiscoveryDisabled bool `json:"builtInDiscoveryDisabled,omitempty"` +} + +// JmxCredentialsDatabaseOptions provides configuration options to the Cryostat application's credentials database. +type JmxCredentialsDatabaseOptions struct { + // Name of the secret containing the password to encrypt credentials database. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} + DatabaseSecretName *string `json:"databaseSecretName,omitempty"` +} diff --git a/api/v1beta2/groupversion_info.go b/api/v1beta2/groupversion_info.go new file mode 100644 index 000000000..79f19b264 --- /dev/null +++ b/api/v1beta2/groupversion_info.go @@ -0,0 +1,34 @@ +// 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 v1beta2 contains API Schema definitions for the operator v1beta2 API group +// +kubebuilder:object:generate=true +// +groupName=operator.cryostat.io +package v1beta2 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "operator.cryostat.io", Version: "v1beta2"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go new file mode 100644 index 000000000..c1850c2d1 --- /dev/null +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -0,0 +1,893 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// 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. + +// Code generated by controller-gen. DO NOT EDIT. + +package v1beta2 + +import ( + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Affinity) DeepCopyInto(out *Affinity) { + *out = *in + if in.NodeAffinity != nil { + in, out := &in.NodeAffinity, &out.NodeAffinity + *out = new(corev1.NodeAffinity) + (*in).DeepCopyInto(*out) + } + if in.PodAffinity != nil { + in, out := &in.PodAffinity, &out.PodAffinity + *out = new(corev1.PodAffinity) + (*in).DeepCopyInto(*out) + } + if in.PodAntiAffinity != nil { + in, out := &in.PodAntiAffinity, &out.PodAntiAffinity + *out = new(corev1.PodAntiAffinity) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Affinity. +func (in *Affinity) DeepCopy() *Affinity { + if in == nil { + return nil + } + out := new(Affinity) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthorizationProperties) DeepCopyInto(out *AuthorizationProperties) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizationProperties. +func (in *AuthorizationProperties) DeepCopy() *AuthorizationProperties { + if in == nil { + return nil + } + out := new(AuthorizationProperties) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CertificateSecret) DeepCopyInto(out *CertificateSecret) { + *out = *in + if in.CertificateKey != nil { + in, out := &in.CertificateKey, &out.CertificateKey + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CertificateSecret. +func (in *CertificateSecret) DeepCopy() *CertificateSecret { + if in == nil { + return nil + } + out := new(CertificateSecret) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCryostat) DeepCopyInto(out *ClusterCryostat) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostat. +func (in *ClusterCryostat) DeepCopy() *ClusterCryostat { + if in == nil { + return nil + } + out := new(ClusterCryostat) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCryostat) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCryostatList) DeepCopyInto(out *ClusterCryostatList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterCryostat, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatList. +func (in *ClusterCryostatList) DeepCopy() *ClusterCryostatList { + if in == nil { + return nil + } + out := new(ClusterCryostatList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCryostatList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCryostatSpec) DeepCopyInto(out *ClusterCryostatSpec) { + *out = *in + in.CryostatSpec.DeepCopyInto(&out.CryostatSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatSpec. +func (in *ClusterCryostatSpec) DeepCopy() *ClusterCryostatSpec { + if in == nil { + return nil + } + out := new(ClusterCryostatSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCryostatStatus) DeepCopyInto(out *ClusterCryostatStatus) { + *out = *in + in.CryostatStatus.DeepCopyInto(&out.CryostatStatus) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatStatus. +func (in *ClusterCryostatStatus) DeepCopy() *ClusterCryostatStatus { + if in == nil { + return nil + } + out := new(ClusterCryostatStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CoreServiceConfig) DeepCopyInto(out *CoreServiceConfig) { + *out = *in + if in.HTTPPort != nil { + in, out := &in.HTTPPort, &out.HTTPPort + *out = new(int32) + **out = **in + } + if in.JMXPort != nil { + in, out := &in.JMXPort, &out.JMXPort + *out = new(int32) + **out = **in + } + in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CoreServiceConfig. +func (in *CoreServiceConfig) DeepCopy() *CoreServiceConfig { + if in == nil { + return nil + } + out := new(CoreServiceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Cryostat) DeepCopyInto(out *Cryostat) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cryostat. +func (in *Cryostat) DeepCopy() *Cryostat { + if in == nil { + return nil + } + out := new(Cryostat) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Cryostat) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CryostatList) DeepCopyInto(out *CryostatList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Cryostat, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CryostatList. +func (in *CryostatList) DeepCopy() *CryostatList { + if in == nil { + return nil + } + out := new(CryostatList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CryostatList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { + *out = *in + if in.TargetNamespaces != nil { + in, out := &in.TargetNamespaces, &out.TargetNamespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.TrustedCertSecrets != nil { + in, out := &in.TrustedCertSecrets, &out.TrustedCertSecrets + *out = make([]CertificateSecret, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EventTemplates != nil { + in, out := &in.EventTemplates, &out.EventTemplates + *out = make([]TemplateConfigMap, len(*in)) + copy(*out, *in) + } + if in.EnableCertManager != nil { + in, out := &in.EnableCertManager, &out.EnableCertManager + *out = new(bool) + **out = **in + } + if in.StorageOptions != nil { + in, out := &in.StorageOptions, &out.StorageOptions + *out = new(StorageConfiguration) + (*in).DeepCopyInto(*out) + } + if in.ServiceOptions != nil { + in, out := &in.ServiceOptions, &out.ServiceOptions + *out = new(ServiceConfigList) + (*in).DeepCopyInto(*out) + } + if in.NetworkOptions != nil { + in, out := &in.NetworkOptions, &out.NetworkOptions + *out = new(NetworkConfigurationList) + (*in).DeepCopyInto(*out) + } + if in.ReportOptions != nil { + in, out := &in.ReportOptions, &out.ReportOptions + *out = new(ReportConfiguration) + (*in).DeepCopyInto(*out) + } + if in.JmxCacheOptions != nil { + in, out := &in.JmxCacheOptions, &out.JmxCacheOptions + *out = new(JmxCacheOptions) + **out = **in + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(ResourceConfigList) + (*in).DeepCopyInto(*out) + } + if in.AuthProperties != nil { + in, out := &in.AuthProperties, &out.AuthProperties + *out = new(AuthorizationProperties) + **out = **in + } + if in.SecurityOptions != nil { + in, out := &in.SecurityOptions, &out.SecurityOptions + *out = new(SecurityOptions) + (*in).DeepCopyInto(*out) + } + if in.SchedulingOptions != nil { + in, out := &in.SchedulingOptions, &out.SchedulingOptions + *out = new(SchedulingConfiguration) + (*in).DeepCopyInto(*out) + } + if in.TargetDiscoveryOptions != nil { + in, out := &in.TargetDiscoveryOptions, &out.TargetDiscoveryOptions + *out = new(TargetDiscoveryOptions) + **out = **in + } + if in.JmxCredentialsDatabaseOptions != nil { + in, out := &in.JmxCredentialsDatabaseOptions, &out.JmxCredentialsDatabaseOptions + *out = new(JmxCredentialsDatabaseOptions) + (*in).DeepCopyInto(*out) + } + if in.OperandMetadata != nil { + in, out := &in.OperandMetadata, &out.OperandMetadata + *out = new(OperandMetadata) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CryostatSpec. +func (in *CryostatSpec) DeepCopy() *CryostatSpec { + if in == nil { + return nil + } + out := new(CryostatSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CryostatStatus) DeepCopyInto(out *CryostatStatus) { + *out = *in + if in.TargetNamespaces != nil { + in, out := &in.TargetNamespaces, &out.TargetNamespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CryostatStatus. +func (in *CryostatStatus) DeepCopy() *CryostatStatus { + if in == nil { + return nil + } + out := new(CryostatStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EmptyDirConfig) DeepCopyInto(out *EmptyDirConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmptyDirConfig. +func (in *EmptyDirConfig) DeepCopy() *EmptyDirConfig { + if in == nil { + return nil + } + out := new(EmptyDirConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GrafanaServiceConfig) DeepCopyInto(out *GrafanaServiceConfig) { + *out = *in + if in.HTTPPort != nil { + in, out := &in.HTTPPort, &out.HTTPPort + *out = new(int32) + **out = **in + } + in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaServiceConfig. +func (in *GrafanaServiceConfig) DeepCopy() *GrafanaServiceConfig { + if in == nil { + return nil + } + out := new(GrafanaServiceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JmxCacheOptions) DeepCopyInto(out *JmxCacheOptions) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JmxCacheOptions. +func (in *JmxCacheOptions) DeepCopy() *JmxCacheOptions { + if in == nil { + return nil + } + out := new(JmxCacheOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JmxCredentialsDatabaseOptions) DeepCopyInto(out *JmxCredentialsDatabaseOptions) { + *out = *in + if in.DatabaseSecretName != nil { + in, out := &in.DatabaseSecretName, &out.DatabaseSecretName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JmxCredentialsDatabaseOptions. +func (in *JmxCredentialsDatabaseOptions) DeepCopy() *JmxCredentialsDatabaseOptions { + if in == nil { + return nil + } + out := new(JmxCredentialsDatabaseOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkConfiguration) DeepCopyInto(out *NetworkConfiguration) { + *out = *in + if in.IngressSpec != nil { + in, out := &in.IngressSpec, &out.IngressSpec + *out = new(networkingv1.IngressSpec) + (*in).DeepCopyInto(*out) + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkConfiguration. +func (in *NetworkConfiguration) DeepCopy() *NetworkConfiguration { + if in == nil { + return nil + } + out := new(NetworkConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkConfigurationList) DeepCopyInto(out *NetworkConfigurationList) { + *out = *in + if in.CoreConfig != nil { + in, out := &in.CoreConfig, &out.CoreConfig + *out = new(NetworkConfiguration) + (*in).DeepCopyInto(*out) + } + if in.CommandConfig != nil { + in, out := &in.CommandConfig, &out.CommandConfig + *out = new(NetworkConfiguration) + (*in).DeepCopyInto(*out) + } + if in.GrafanaConfig != nil { + in, out := &in.GrafanaConfig, &out.GrafanaConfig + *out = new(NetworkConfiguration) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkConfigurationList. +func (in *NetworkConfigurationList) DeepCopy() *NetworkConfigurationList { + if in == nil { + return nil + } + out := new(NetworkConfigurationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperandMetadata) DeepCopyInto(out *OperandMetadata) { + *out = *in + if in.DeploymentMetadata != nil { + in, out := &in.DeploymentMetadata, &out.DeploymentMetadata + *out = new(ResourceMetadata) + (*in).DeepCopyInto(*out) + } + if in.PodMetadata != nil { + in, out := &in.PodMetadata, &out.PodMetadata + *out = new(ResourceMetadata) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperandMetadata. +func (in *OperandMetadata) DeepCopy() *OperandMetadata { + if in == nil { + return nil + } + out := new(OperandMetadata) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PersistentVolumeClaimConfig) DeepCopyInto(out *PersistentVolumeClaimConfig) { + *out = *in + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Spec != nil { + in, out := &in.Spec, &out.Spec + *out = new(corev1.PersistentVolumeClaimSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PersistentVolumeClaimConfig. +func (in *PersistentVolumeClaimConfig) DeepCopy() *PersistentVolumeClaimConfig { + if in == nil { + return nil + } + out := new(PersistentVolumeClaimConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReportConfiguration) DeepCopyInto(out *ReportConfiguration) { + *out = *in + in.Resources.DeepCopyInto(&out.Resources) + if in.SecurityOptions != nil { + in, out := &in.SecurityOptions, &out.SecurityOptions + *out = new(ReportsSecurityOptions) + (*in).DeepCopyInto(*out) + } + if in.SchedulingOptions != nil { + in, out := &in.SchedulingOptions, &out.SchedulingOptions + *out = new(SchedulingConfiguration) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportConfiguration. +func (in *ReportConfiguration) DeepCopy() *ReportConfiguration { + if in == nil { + return nil + } + out := new(ReportConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReportsSecurityOptions) DeepCopyInto(out *ReportsSecurityOptions) { + *out = *in + if in.PodSecurityContext != nil { + in, out := &in.PodSecurityContext, &out.PodSecurityContext + *out = new(corev1.PodSecurityContext) + (*in).DeepCopyInto(*out) + } + if in.ReportsSecurityContext != nil { + in, out := &in.ReportsSecurityContext, &out.ReportsSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportsSecurityOptions. +func (in *ReportsSecurityOptions) DeepCopy() *ReportsSecurityOptions { + if in == nil { + return nil + } + out := new(ReportsSecurityOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReportsServiceConfig) DeepCopyInto(out *ReportsServiceConfig) { + *out = *in + if in.HTTPPort != nil { + in, out := &in.HTTPPort, &out.HTTPPort + *out = new(int32) + **out = **in + } + in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportsServiceConfig. +func (in *ReportsServiceConfig) DeepCopy() *ReportsServiceConfig { + if in == nil { + return nil + } + out := new(ReportsServiceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceConfigList) DeepCopyInto(out *ResourceConfigList) { + *out = *in + in.CoreResources.DeepCopyInto(&out.CoreResources) + in.DataSourceResources.DeepCopyInto(&out.DataSourceResources) + in.GrafanaResources.DeepCopyInto(&out.GrafanaResources) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceConfigList. +func (in *ResourceConfigList) DeepCopy() *ResourceConfigList { + if in == nil { + return nil + } + out := new(ResourceConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceMetadata) DeepCopyInto(out *ResourceMetadata) { + *out = *in + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceMetadata. +func (in *ResourceMetadata) DeepCopy() *ResourceMetadata { + if in == nil { + return nil + } + out := new(ResourceMetadata) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SchedulingConfiguration) DeepCopyInto(out *SchedulingConfiguration) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SchedulingConfiguration. +func (in *SchedulingConfiguration) DeepCopy() *SchedulingConfiguration { + if in == nil { + return nil + } + out := new(SchedulingConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityOptions) DeepCopyInto(out *SecurityOptions) { + *out = *in + if in.PodSecurityContext != nil { + in, out := &in.PodSecurityContext, &out.PodSecurityContext + *out = new(corev1.PodSecurityContext) + (*in).DeepCopyInto(*out) + } + if in.CoreSecurityContext != nil { + in, out := &in.CoreSecurityContext, &out.CoreSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } + if in.DataSourceSecurityContext != nil { + in, out := &in.DataSourceSecurityContext, &out.DataSourceSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } + if in.GrafanaSecurityContext != nil { + in, out := &in.GrafanaSecurityContext, &out.GrafanaSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityOptions. +func (in *SecurityOptions) DeepCopy() *SecurityOptions { + if in == nil { + return nil + } + out := new(SecurityOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceConfig) DeepCopyInto(out *ServiceConfig) { + *out = *in + if in.ServiceType != nil { + in, out := &in.ServiceType, &out.ServiceType + *out = new(corev1.ServiceType) + **out = **in + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceConfig. +func (in *ServiceConfig) DeepCopy() *ServiceConfig { + if in == nil { + return nil + } + out := new(ServiceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceConfigList) DeepCopyInto(out *ServiceConfigList) { + *out = *in + if in.CoreConfig != nil { + in, out := &in.CoreConfig, &out.CoreConfig + *out = new(CoreServiceConfig) + (*in).DeepCopyInto(*out) + } + if in.GrafanaConfig != nil { + in, out := &in.GrafanaConfig, &out.GrafanaConfig + *out = new(GrafanaServiceConfig) + (*in).DeepCopyInto(*out) + } + if in.ReportsConfig != nil { + in, out := &in.ReportsConfig, &out.ReportsConfig + *out = new(ReportsServiceConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceConfigList. +func (in *ServiceConfigList) DeepCopy() *ServiceConfigList { + if in == nil { + return nil + } + out := new(ServiceConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StorageConfiguration) DeepCopyInto(out *StorageConfiguration) { + *out = *in + if in.PVC != nil { + in, out := &in.PVC, &out.PVC + *out = new(PersistentVolumeClaimConfig) + (*in).DeepCopyInto(*out) + } + if in.EmptyDir != nil { + in, out := &in.EmptyDir, &out.EmptyDir + *out = new(EmptyDirConfig) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageConfiguration. +func (in *StorageConfiguration) DeepCopy() *StorageConfiguration { + if in == nil { + return nil + } + out := new(StorageConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TargetDiscoveryOptions) DeepCopyInto(out *TargetDiscoveryOptions) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetDiscoveryOptions. +func (in *TargetDiscoveryOptions) DeepCopy() *TargetDiscoveryOptions { + if in == nil { + return nil + } + out := new(TargetDiscoveryOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateConfigMap) DeepCopyInto(out *TemplateConfigMap) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateConfigMap. +func (in *TemplateConfigMap) DeepCopy() *TemplateConfigMap { + if in == nil { + return nil + } + out := new(TemplateConfigMap) + in.DeepCopyInto(out) + return out +} diff --git a/bundle/manifests/cryostat-operator-webhook-service_v1_service.yaml b/bundle/manifests/cryostat-operator-webhook-service_v1_service.yaml new file mode 100644 index 000000000..0e7a3b06a --- /dev/null +++ b/bundle/manifests/cryostat-operator-webhook-service_v1_service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: cryostat-operator + app.kubernetes.io/instance: webhook-service + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: service + app.kubernetes.io/part-of: cryostat-operator + name: cryostat-operator-webhook-service +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager +status: + loadBalancer: {} diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 6cfe13ae4..83d78572a 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -49,16 +49,62 @@ metadata: }, "trustedCertSecrets": [] } + }, + { + "apiVersion": "operator.cryostat.io/v1beta2", + "kind": "ClusterCryostat", + "metadata": { + "name": "clustercryostat-sample" + }, + "spec": { + "enableCertManager": true, + "eventTemplates": [], + "minimal": false, + "reportOptions": { + "replicas": 0 + }, + "storageOptions": { + "pvc": { + "annotations": {}, + "labels": {}, + "spec": {} + } + }, + "trustedCertSecrets": [] + } + }, + { + "apiVersion": "operator.cryostat.io/v1beta2", + "kind": "Cryostat", + "metadata": { + "name": "cryostat-sample" + }, + "spec": { + "enableCertManager": true, + "eventTemplates": [], + "minimal": false, + "reportOptions": { + "replicas": 0 + }, + "storageOptions": { + "pvc": { + "annotations": {}, + "labels": {}, + "spec": {} + } + }, + "trustedCertSecrets": [] + } } ] capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-02-12T21:32:06Z" + createdAt: "2024-02-12T22:09:00Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { - "apiVersion": "operator.cryostat.io/v1beta1", + "apiVersion": "operator.cryostat.io/v1beta2", "kind": "Cryostat", "metadata": { "name": "cryostat-sample" @@ -116,18 +162,815 @@ spec: name: "" version: v1 specDescriptors: - - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - displayName: Install Namespace - path: installNamespace - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - - description: 'List of namespaces whose workloads Cryostat should be permitted - to access and profile. Warning: All Cryostat users will be able to create - and manage recordings for workloads in the listed namespaces. More details: - https://github.com/cryostatio/cryostat-operator/blob/v2.3.0/docs/multi-namespace.md#data-isolation' - displayName: Target Namespaces - path: targetNamespaces + - description: Namespace where Cryostat should be installed. On multi-tenant + clusters, we strongly suggest installing Cryostat into its own namespace. + displayName: Install Namespace + path: installNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - description: 'List of namespaces whose workloads Cryostat should be permitted + to access and profile. Warning: All Cryostat users will be able to create + and manage recordings for workloads in the listed namespaces. More details: + https://github.com/cryostatio/cryostat-operator/blob/v2.3.0/docs/multi-namespace.md#data-isolation' + displayName: Target Namespaces + path: targetNamespaces + - description: Use cert-manager to secure in-cluster communication between Cryostat + components. Requires cert-manager to be installed. + displayName: Enable cert-manager Integration + path: enableCertManager + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard + or JFR Data Source. + displayName: Minimal Deployment + path: minimal + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Override default authorization properties for Cryostat on OpenShift. + displayName: Authorization Properties + path: authProperties + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped + OAuth token. This ClusterRole should contain permissions for all Kubernetes + objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + displayName: ClusterRole Name + path: authProperties.clusterRoleName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ClusterRole + - description: Name of config map in the local namespace. + displayName: ConfigMap Name + path: authProperties.configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Filename within config map containing the resource mapping. + displayName: Filename + path: authProperties.filename + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. + displayName: Event Templates + path: eventTemplates + - description: Name of config map in the local namespace. + displayName: Config Map Name + path: eventTemplates[0].configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Options to customize the JMX target connections cache for the + Cryostat application. + displayName: JMX Connections Cache Options + path: jmxCacheOptions + - description: The maximum number of JMX connections to cache. Use `-1` for + an unlimited cache size (TTL expiration only). Defaults to `-1`. + displayName: Target Cache Size + path: jmxCacheOptions.targetCacheSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: The time to live (in seconds) for cached JMX connections. Defaults + to `10`. + displayName: Target Cache TTL + path: jmxCacheOptions.targetCacheTTL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Options to configure the Cryostat application's credentials database. + displayName: Credentials Database Options + path: jmxCredentialsDatabaseOptions + - description: Name of the secret containing the password to encrypt credentials + database. + displayName: Database Secret Name + path: jmxCredentialsDatabaseOptions.databaseSecretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: The maximum number of WebSocket client connections allowed (minimum + 1, default unlimited). + displayName: Max WebSocket Connections + path: maxWsConnections + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Options to control how the operator exposes the application outside + of the cluster, such as using an Ingress or Route. + displayName: Network Options + path: networkOptions + - description: "Specifications for how to expose the Cryostat command service, + which serves the WebSocket command channel. \n Deprecated: CommandConfig + is no longer used." + displayName: Command Config + path: networkOptions.commandConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.commandConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.commandConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.commandConfig.labels + - description: Specifications for how to expose the Cryostat service, which + serves the Cryostat application. + displayName: Core Config + path: networkOptions.coreConfig + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.coreConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.coreConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.coreConfig.labels + - description: Specifications for how to expose Cryostat's Grafana service, + which serves the Grafana dashboard. + displayName: Grafana Config + path: networkOptions.grafanaConfig + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.grafanaConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.grafanaConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.grafanaConfig.labels + - description: Options to configure the Cryostat deployments and pods metadata + displayName: Operand metadata + path: operandMetadata + - description: Options to configure the Cryostat deployments metadata + displayName: Deployments metadata + path: operandMetadata.deploymentMetadata + - description: Options to configure the Cryostat pods metadata + displayName: Pods metadata + path: operandMetadata.podMetadata + - description: Options to configure Cryostat Automated Report Analysis. + displayName: Report Options + path: reportOptions + - description: The number of report sidecar replica containers to deploy. Each + replica can service one report generation request at a time. + displayName: Replicas + path: reportOptions.replicas + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: The resources allocated to each sidecar replica. A replica with + more resources can handle larger input recordings and will process them + faster. + displayName: Resources + path: reportOptions.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Options to configure scheduling for the reports deployment + displayName: Scheduling Options + path: reportOptions.schedulingOptions + - description: Affinity rules for scheduling Cryostat pods. + displayName: Affinity + path: reportOptions.schedulingOptions.affinity + - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + displayName: Node Affinity + path: reportOptions.schedulingOptions.affinity.nodeAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:nodeAffinity + - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + displayName: Pod Affinity + path: reportOptions.schedulingOptions.affinity.podAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAffinity + - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + displayName: Pod Anti Affinity + path: reportOptions.schedulingOptions.affinity.podAntiAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity + - description: 'Label selector used to schedule a Cryostat pod to a node. See: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + displayName: Node Selector + path: reportOptions.schedulingOptions.nodeSelector + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node + - description: 'Tolerations to allow scheduling of Cryostat pods to tainted + nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + displayName: Tolerations + path: reportOptions.schedulingOptions.tolerations + - description: Options to configure the Security Contexts for the Cryostat report + generator. + displayName: Security Options + path: reportOptions.securityOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the Cryostat report generator pod. + displayName: Pod Security Context + path: reportOptions.securityOptions.podSecurityContext + - description: Security Context to apply to the Cryostat report generator container. + displayName: Reports Security Context + path: reportOptions.securityOptions.reportsSecurityContext + - description: When zero report sidecar replicas are requested, SubProcessMaxHeapSize + configures the maximum heap size of the basic subprocess report generator + in MiB. The default heap size is `200` (MiB). + displayName: Sub Process Max Heap Size + path: reportOptions.subProcessMaxHeapSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resource requirements for the Cryostat deployment. + displayName: Resources + path: resources + - description: Resource requirements for the Cryostat application. If specifying + a memory limit, at least 768MiB is recommended. + displayName: Core Resources + path: resources.coreResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the JFR Data Source container. + displayName: Data Source Resources + path: resources.dataSourceResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the Grafana container. + displayName: Grafana Resources + path: resources.grafanaResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Options to configure scheduling for the Cryostat deployment + displayName: Scheduling Options + path: schedulingOptions + - description: Affinity rules for scheduling Cryostat pods. + displayName: Affinity + path: schedulingOptions.affinity + - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + displayName: Node Affinity + path: schedulingOptions.affinity.nodeAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:nodeAffinity + - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + displayName: Pod Affinity + path: schedulingOptions.affinity.podAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAffinity + - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + displayName: Pod Anti Affinity + path: schedulingOptions.affinity.podAntiAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity + - description: 'Label selector used to schedule a Cryostat pod to a node. See: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + displayName: Node Selector + path: schedulingOptions.nodeSelector + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node + - description: 'Tolerations to allow scheduling of Cryostat pods to tainted + nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + displayName: Tolerations + path: schedulingOptions.tolerations + - description: Options to configure the Security Contexts for the Cryostat application. + displayName: Security Options + path: securityOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the Cryostat application container. + displayName: Core Security Context + path: securityOptions.coreSecurityContext + - description: Security Context to apply to the JFR Data Source container. + displayName: Data Source Security Context + path: securityOptions.dataSourceSecurityContext + - description: Security Context to apply to the Grafana container. + displayName: Grafana Security Context + path: securityOptions.grafanaSecurityContext + - description: Security Context to apply to the Cryostat pod. + displayName: Pod Security Context + path: securityOptions.podSecurityContext + - description: Options to customize the services created for the Cryostat application + and Grafana dashboard. + displayName: Service Options + path: serviceOptions + - description: Options to customize the storage for Flight Recordings and Templates. + displayName: Storage Options + path: storageOptions + - description: Configuration for an EmptyDir to be created by the operator instead + of a PVC. + displayName: Empty Dir + path: storageOptions.emptyDir + - description: When enabled, Cryostat will use EmptyDir volumes instead of a + Persistent Volume Claim. Any PVC configurations will be ignored. + displayName: Enabled + path: storageOptions.emptyDir.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Unless specified, the emptyDir volume will be mounted on the + same storage medium backing the node. Setting this field to "Memory" will + mount the emptyDir on a tmpfs (RAM-backed filesystem). + displayName: Medium + path: storageOptions.emptyDir.medium + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true + - description: The maximum memory limit for the emptyDir. Default is unbounded. + displayName: Size Limit + path: storageOptions.emptyDir.sizeLimit + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true + - description: Configuration for the Persistent Volume Claim to be created by + the operator. + displayName: PVC + path: storageOptions.pvc + - description: Spec for a Persistent Volume Claim, whose options will override + the defaults used by the operator. Unless overriden, the PVC will be created + with the default Storage Class and 500MiB of storage. Once the operator + has created the PVC, changes to this field have no effect. + displayName: Spec + path: storageOptions.pvc.spec + - description: Options to configure the Cryostat application's target discovery + mechanisms. + displayName: Target Discovery Options + path: targetDiscoveryOptions + - description: When true, the Cryostat application will disable the built-in + discovery mechanisms. Defaults to false + displayName: Disable Built-in Discovery + path: targetDiscoveryOptions.builtInDiscoveryDisabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: List of TLS certificates to trust when connecting to targets. + displayName: Trusted TLS Certificates + path: trustedCertSecrets + - description: Name of secret in the local namespace. + displayName: Secret Name + path: trustedCertSecrets[0].secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: A namespace whose workloads Cryostat should be able to connect + and record + displayName: Target Namespace + path: targetNamespaces[0] + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + statusDescriptors: + - description: Address of the deployed Cryostat web application. + displayName: Application URL + path: applicationUrl + x-descriptors: + - urn:alm:descriptor:org.w3:link + - description: Name of the Secret containing the generated Grafana credentials. + displayName: Grafana Secret + path: grafanaSecret + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: List of namespaces that Cryostat has been configured and authorized + to access and profile. + displayName: Target Namespaces + path: targetNamespaces + - description: Conditions of the components managed by the Cryostat Operator. + displayName: Cryostat Conditions + path: conditions + x-descriptors: + - urn:alm:descriptor:io.kubernetes.conditions + - description: A namespace whose workloads Cryostat should be able to connect + and record + displayName: Target Namespace + path: targetNamespaces[0] + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + version: v1beta1 + - description: ClusterCryostat allows you to install Cryostat for multiple namespaces + or cluster-wide. It contains configuration options for controlling the Deployment + of the Cryostat application and its related components. A ClusterCryostat + or Cryostat instance must be created to instruct the operator to deploy the + Cryostat application. + displayName: Cluster Cryostat + kind: ClusterCryostat + name: clustercryostats.operator.cryostat.io + resources: + - kind: ConsoleLink + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + specDescriptors: + - description: Namespace where Cryostat should be installed. On multi-tenant + clusters, we strongly suggest installing Cryostat into its own namespace. + displayName: Install Namespace + path: installNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - description: 'List of namespaces whose workloads Cryostat should be permitted + to access and profile. Defaults to this Cryostat''s namespace. Warning: + All Cryostat users will be able to create and manage recordings for workloads + in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + displayName: Target Namespaces + path: targetNamespaces + - description: Use cert-manager to secure in-cluster communication between Cryostat + components. Requires cert-manager to be installed. + displayName: Enable cert-manager Integration + path: enableCertManager + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard + or JFR Data Source. + displayName: Minimal Deployment + path: minimal + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Override default authorization properties for Cryostat on OpenShift. + displayName: Authorization Properties + path: authProperties + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped + OAuth token. This ClusterRole should contain permissions for all Kubernetes + objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + displayName: ClusterRole Name + path: authProperties.clusterRoleName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ClusterRole + - description: Name of config map in the local namespace. + displayName: ConfigMap Name + path: authProperties.configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Filename within config map containing the resource mapping. + displayName: Filename + path: authProperties.filename + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. + displayName: Event Templates + path: eventTemplates + - description: Name of config map in the local namespace. + displayName: Config Map Name + path: eventTemplates[0].configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Options to customize the JMX target connections cache for the + Cryostat application. + displayName: JMX Connections Cache Options + path: jmxCacheOptions + - description: The maximum number of JMX connections to cache. Use `-1` for + an unlimited cache size (TTL expiration only). Defaults to `-1`. + displayName: Target Cache Size + path: jmxCacheOptions.targetCacheSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: The time to live (in seconds) for cached JMX connections. Defaults + to `10`. + displayName: Target Cache TTL + path: jmxCacheOptions.targetCacheTTL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Options to configure the Cryostat application's credentials database. + displayName: Credentials Database Options + path: jmxCredentialsDatabaseOptions + - description: Name of the secret containing the password to encrypt credentials + database. + displayName: Database Secret Name + path: jmxCredentialsDatabaseOptions.databaseSecretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: The maximum number of WebSocket client connections allowed (minimum + 1, default unlimited). + displayName: Max WebSocket Connections + path: maxWsConnections + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Options to control how the operator exposes the application outside + of the cluster, such as using an Ingress or Route. + displayName: Network Options + path: networkOptions + - description: "Specifications for how to expose the Cryostat command service, + which serves the WebSocket command channel. \n Deprecated: CommandConfig + is no longer used." + displayName: Command Config + path: networkOptions.commandConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.commandConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.commandConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.commandConfig.labels + - description: Specifications for how to expose the Cryostat service, which + serves the Cryostat application. + displayName: Core Config + path: networkOptions.coreConfig + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.coreConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.coreConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.coreConfig.labels + - description: Specifications for how to expose Cryostat's Grafana service, + which serves the Grafana dashboard. + displayName: Grafana Config + path: networkOptions.grafanaConfig + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.grafanaConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.grafanaConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.grafanaConfig.labels + - description: Options to configure the Cryostat deployments and pods metadata + displayName: Operand metadata + path: operandMetadata + - description: Options to configure the Cryostat deployments metadata + displayName: Deployments metadata + path: operandMetadata.deploymentMetadata + - description: Options to configure the Cryostat pods metadata + displayName: Pods metadata + path: operandMetadata.podMetadata + - description: Options to configure Cryostat Automated Report Analysis. + displayName: Report Options + path: reportOptions + - description: The number of report sidecar replica containers to deploy. Each + replica can service one report generation request at a time. + displayName: Replicas + path: reportOptions.replicas + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: The resources allocated to each sidecar replica. A replica with + more resources can handle larger input recordings and will process them + faster. + displayName: Resources + path: reportOptions.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Options to configure scheduling for the reports deployment + displayName: Scheduling Options + path: reportOptions.schedulingOptions + - description: Affinity rules for scheduling Cryostat pods. + displayName: Affinity + path: reportOptions.schedulingOptions.affinity + - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + displayName: Node Affinity + path: reportOptions.schedulingOptions.affinity.nodeAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:nodeAffinity + - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + displayName: Pod Affinity + path: reportOptions.schedulingOptions.affinity.podAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAffinity + - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + displayName: Pod Anti Affinity + path: reportOptions.schedulingOptions.affinity.podAntiAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity + - description: 'Label selector used to schedule a Cryostat pod to a node. See: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + displayName: Node Selector + path: reportOptions.schedulingOptions.nodeSelector + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node + - description: 'Tolerations to allow scheduling of Cryostat pods to tainted + nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + displayName: Tolerations + path: reportOptions.schedulingOptions.tolerations + - description: Options to configure the Security Contexts for the Cryostat report + generator. + displayName: Security Options + path: reportOptions.securityOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the Cryostat report generator pod. + displayName: Pod Security Context + path: reportOptions.securityOptions.podSecurityContext + - description: Security Context to apply to the Cryostat report generator container. + displayName: Reports Security Context + path: reportOptions.securityOptions.reportsSecurityContext + - description: When zero report sidecar replicas are requested, SubProcessMaxHeapSize + configures the maximum heap size of the basic subprocess report generator + in MiB. The default heap size is `200` (MiB). + displayName: Sub Process Max Heap Size + path: reportOptions.subProcessMaxHeapSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resource requirements for the Cryostat deployment. + displayName: Resources + path: resources + - description: Resource requirements for the Cryostat application. If specifying + a memory limit, at least 768MiB is recommended. + displayName: Core Resources + path: resources.coreResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the JFR Data Source container. + displayName: Data Source Resources + path: resources.dataSourceResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the Grafana container. + displayName: Grafana Resources + path: resources.grafanaResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Options to configure scheduling for the Cryostat deployment + displayName: Scheduling Options + path: schedulingOptions + - description: Affinity rules for scheduling Cryostat pods. + displayName: Affinity + path: schedulingOptions.affinity + - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + displayName: Node Affinity + path: schedulingOptions.affinity.nodeAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:nodeAffinity + - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + displayName: Pod Affinity + path: schedulingOptions.affinity.podAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAffinity + - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + displayName: Pod Anti Affinity + path: schedulingOptions.affinity.podAntiAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity + - description: 'Label selector used to schedule a Cryostat pod to a node. See: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + displayName: Node Selector + path: schedulingOptions.nodeSelector + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node + - description: 'Tolerations to allow scheduling of Cryostat pods to tainted + nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + displayName: Tolerations + path: schedulingOptions.tolerations + - description: Options to configure the Security Contexts for the Cryostat application. + displayName: Security Options + path: securityOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the Cryostat application container. + displayName: Core Security Context + path: securityOptions.coreSecurityContext + - description: Security Context to apply to the JFR Data Source container. + displayName: Data Source Security Context + path: securityOptions.dataSourceSecurityContext + - description: Security Context to apply to the Grafana container. + displayName: Grafana Security Context + path: securityOptions.grafanaSecurityContext + - description: Security Context to apply to the Cryostat pod. + displayName: Pod Security Context + path: securityOptions.podSecurityContext + - description: Options to customize the services created for the Cryostat application + and Grafana dashboard. + displayName: Service Options + path: serviceOptions + - description: Options to customize the storage for Flight Recordings and Templates. + displayName: Storage Options + path: storageOptions + - description: Configuration for an EmptyDir to be created by the operator instead + of a PVC. + displayName: Empty Dir + path: storageOptions.emptyDir + - description: When enabled, Cryostat will use EmptyDir volumes instead of a + Persistent Volume Claim. Any PVC configurations will be ignored. + displayName: Enabled + path: storageOptions.emptyDir.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Unless specified, the emptyDir volume will be mounted on the + same storage medium backing the node. Setting this field to "Memory" will + mount the emptyDir on a tmpfs (RAM-backed filesystem). + displayName: Medium + path: storageOptions.emptyDir.medium + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true + - description: The maximum memory limit for the emptyDir. Default is unbounded. + displayName: Size Limit + path: storageOptions.emptyDir.sizeLimit + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true + - description: Configuration for the Persistent Volume Claim to be created by + the operator. + displayName: PVC + path: storageOptions.pvc + - description: Spec for a Persistent Volume Claim, whose options will override + the defaults used by the operator. Unless overriden, the PVC will be created + with the default Storage Class and 500MiB of storage. Once the operator + has created the PVC, changes to this field have no effect. + displayName: Spec + path: storageOptions.pvc.spec + - description: Options to configure the Cryostat application's target discovery + mechanisms. + displayName: Target Discovery Options + path: targetDiscoveryOptions + - description: When true, the Cryostat application will disable the built-in + discovery mechanisms. Defaults to false + displayName: Disable Built-in Discovery + path: targetDiscoveryOptions.builtInDiscoveryDisabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: List of TLS certificates to trust when connecting to targets. + displayName: Trusted TLS Certificates + path: trustedCertSecrets + - description: Name of secret in the local namespace. + displayName: Secret Name + path: trustedCertSecrets[0].secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: A namespace whose workloads Cryostat should be able to connect + and record + displayName: Target Namespace + path: targetNamespaces[0] + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + statusDescriptors: + - description: Address of the deployed Cryostat web application. + displayName: Application URL + path: applicationUrl + x-descriptors: + - urn:alm:descriptor:org.w3:link + - description: Name of the Secret containing the generated Grafana credentials. + displayName: Grafana Secret + path: grafanaSecret + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: List of namespaces that Cryostat has been configured and authorized + to access and profile. + displayName: Target Namespaces + path: targetNamespaces + - description: Conditions of the components managed by the Cryostat Operator. + displayName: Cryostat Conditions + path: conditions + x-descriptors: + - urn:alm:descriptor:io.kubernetes.conditions + - description: A namespace whose workloads Cryostat should be able to connect + and record + displayName: Target Namespace + path: targetNamespaces[0] + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + version: v1beta2 + - description: Cryostat allows you to install Cryostat for a single namespace. + It contains configuration options for controlling the Deployment of the Cryostat + application and its related components. A ClusterCryostat or Cryostat instance + must be created to instruct the operator to deploy the Cryostat application. + displayName: Cryostat + kind: Cryostat + name: cryostats.operator.cryostat.io + resources: + - kind: ConsoleLink + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + specDescriptors: - description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. displayName: Enable cert-manager Integration @@ -481,12 +1324,6 @@ spec: path: trustedCertSecrets[0].secretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret - - description: A namespace whose workloads Cryostat should be able to connect - and record - displayName: Target Namespace - path: targetNamespaces[0] - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace statusDescriptors: - description: Address of the deployed Cryostat web application. displayName: Application URL @@ -498,21 +1335,11 @@ spec: path: grafanaSecret x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret - - description: List of namespaces that Cryostat has been configured and authorized - to access and profile. - displayName: Target Namespaces - path: targetNamespaces - description: Conditions of the components managed by the Cryostat Operator. displayName: Cryostat Conditions path: conditions x-descriptors: - urn:alm:descriptor:io.kubernetes.conditions - - description: A namespace whose workloads Cryostat should be able to connect - and record - displayName: Target Namespace - path: targetNamespaces[0] - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace version: v1beta1 - description: Cryostat allows you to install Cryostat for a single namespace. It contains configuration options for controlling the Deployment of the Cryostat @@ -544,6 +1371,12 @@ spec: name: "" version: v1 specDescriptors: + - description: 'List of namespaces whose workloads Cryostat should be permitted + to access and profile. Defaults to this Cryostat''s namespace. Warning: + All Cryostat users will be able to create and manage recordings for workloads + in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + displayName: Target Namespaces + path: targetNamespaces - description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. displayName: Enable cert-manager Integration @@ -897,6 +1730,12 @@ spec: path: trustedCertSecrets[0].secretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret + - description: A namespace whose workloads Cryostat should be able to connect + and record + displayName: Target Namespace + path: targetNamespaces[0] + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace statusDescriptors: - description: Address of the deployed Cryostat web application. displayName: Application URL @@ -908,12 +1747,22 @@ spec: path: grafanaSecret x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret + - description: List of namespaces that Cryostat has been configured and authorized + to access and profile. + displayName: Target Namespaces + path: targetNamespaces - description: Conditions of the components managed by the Cryostat Operator. displayName: Cryostat Conditions path: conditions x-descriptors: - urn:alm:descriptor:io.kubernetes.conditions - version: v1beta1 + - description: A namespace whose workloads Cryostat should be able to connect + and record + displayName: Target Namespace + path: targetNamespaces[0] + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + version: v1beta2 description: | Cryostat provides a cloud-based solution for interacting with the JDK Flight Recorder already present in OpenJDK 11+ JVMs. With Cryostat, users can remotely start, stop, retrieve, and even analyze JFR event data, providing the capability to easily take advantage of Flight Recorder's extremely low runtime cost and overhead and the flexibility to monitor applications and analyze recording data without transferring data outside of the cluster the application runs within. ##Prerequisites @@ -998,6 +1847,12 @@ spec: - selfsubjectaccessreviews verbs: - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create - apiGroups: - cert-manager.io resources: @@ -1169,6 +2024,10 @@ spec: initialDelaySeconds: 15 periodSeconds: 20 name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP readinessProbe: httpGet: path: /readyz @@ -1187,12 +2046,21 @@ spec: capabilities: drop: - ALL + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault serviceAccountName: cryostat-operator-service-account terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert permissions: - rules: - apiGroups: @@ -1276,3 +2144,56 @@ spec: - image: quay.io/cryostat/cryostat-reports:latest name: reports version: 2.5.0-dev + webhookdefinitions: + - admissionReviewVersions: + - v1 + containerPort: 443 + conversionCRDs: + - clustercryostats.operator.cryostat.io + - cryostats.operator.cryostat.io + deploymentName: cryostat-operator-controller-manager + generateName: cclustercryostatscryostats.kb.io + sideEffects: None + targetPort: 9443 + type: ConversionWebhook + webhookPath: /convert + - admissionReviewVersions: + - v1 + containerPort: 443 + deploymentName: cryostat-operator-controller-manager + failurePolicy: Fail + generateName: mcryostat.kb.io + rules: + - apiGroups: + - operator.cryostat.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cryostats + sideEffects: None + targetPort: 9443 + type: MutatingAdmissionWebhook + webhookPath: /mutate-operator-cryostat-io-v1beta2-cryostat + - admissionReviewVersions: + - v1 + containerPort: 443 + deploymentName: cryostat-operator-controller-manager + failurePolicy: Fail + generateName: vcryostat.kb.io + rules: + - apiGroups: + - operator.cryostat.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cryostats + sideEffects: None + targetPort: 9443 + type: ValidatingAdmissionWebhook + webhookPath: /validate-operator-cryostat-io-v1beta2-cryostat diff --git a/bundle/manifests/operator.cryostat.io_clustercryostats.yaml b/bundle/manifests/operator.cryostat.io_clustercryostats.yaml index 383979ab7..b117234a9 100644 --- a/bundle/manifests/operator.cryostat.io_clustercryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_clustercryostats.yaml @@ -2,10 +2,21 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: + cert-manager.io/inject-ca-from: cryostat-operator-system/cryostat-operator-serving-cert controller-gen.kubebuilder.io/version: v0.11.1 creationTimestamp: null name: clustercryostats.operator.cryostat.io spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: cryostat-operator-webhook-service + namespace: cryostat-operator-system + path: /convert + conversionReviewVersions: + - v1 group: operator.cryostat.io names: kind: ClusterCryostat @@ -4747,6 +4758,4721 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.applicationUrl + name: Application URL + type: string + - jsonPath: .status.grafanaSecret + name: Grafana Secret + type: string + name: v1beta2 + schema: + openAPIV3Schema: + description: ClusterCryostat allows you to install Cryostat for multiple namespaces + or cluster-wide. It contains configuration options for controlling the Deployment + of the Cryostat application and its related components. A ClusterCryostat + or Cryostat instance must be created to instruct the operator to deploy + the Cryostat application. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ClusterCryostatSpec defines the desired state of ClusterCryostat. + properties: + authProperties: + description: Override default authorization properties for Cryostat + on OpenShift. + properties: + clusterRoleName: + description: 'Name of the ClusterRole to use when Cryostat requests + a role-scoped OAuth token. This ClusterRole should contain permissions + for all Kubernetes objects listed in custom permission mapping. + More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + type: string + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the resource + mapping. + type: string + required: + - clusterRoleName + - configMapName + - filename + type: object + enableCertManager: + description: Use cert-manager to secure in-cluster communication between + Cryostat components. Requires cert-manager to be installed. + type: boolean + eventTemplates: + description: List of Flight Recorder Event Templates to preconfigure + in Cryostat. + items: + description: A ConfigMap containing a .jfc template file. + properties: + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the template + file. + type: string + required: + - configMapName + - filename + type: object + type: array + installNamespace: + description: Namespace where Cryostat should be installed. On multi-tenant + clusters, we strongly suggest installing Cryostat into its own namespace. + type: string + jmxCacheOptions: + description: Options to customize the JMX target connections cache + for the Cryostat application. + properties: + targetCacheSize: + description: The maximum number of JMX connections to cache. Use + `-1` for an unlimited cache size (TTL expiration only). Defaults + to `-1`. + format: int32 + minimum: -1 + type: integer + targetCacheTTL: + description: The time to live (in seconds) for cached JMX connections. + Defaults to `10`. + format: int32 + minimum: 1 + type: integer + type: object + jmxCredentialsDatabaseOptions: + description: Options to configure the Cryostat application's credentials + database. + properties: + databaseSecretName: + description: Name of the secret containing the password to encrypt + credentials database. + type: string + type: object + maxWsConnections: + description: The maximum number of WebSocket client connections allowed + (minimum 1, default unlimited). + format: int32 + minimum: 1 + type: integer + minimal: + description: Deploy a pared-down Cryostat instance with no Grafana + Dashboard or JFR Data Source. + type: boolean + networkOptions: + description: Options to control how the operator exposes the application + outside of the cluster, such as using an Ingress or Route. + properties: + commandConfig: + description: "Specifications for how to expose the Cryostat command + service, which serves the WebSocket command channel. \n Deprecated: + CommandConfig is no longer used." + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + coreConfig: + description: Specifications for how to expose the Cryostat service, + which serves the Cryostat application. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + grafanaConfig: + description: Specifications for how to expose Cryostat's Grafana + service, which serves the Grafana dashboard. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + type: object + operandMetadata: + description: Options to configure the Cryostat deployments and pods + metadata + properties: + deploymentMetadata: + description: Options to configure the Cryostat deployments metadata + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the resources during its + creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the resources during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + type: object + podMetadata: + description: Options to configure the Cryostat pods metadata + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the resources during its + creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the resources during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + type: object + type: object + reportOptions: + description: Options to configure Cryostat Automated Report Analysis. + properties: + replicas: + description: The number of report sidecar replica containers to + deploy. Each replica can service one report generation request + at a time. + format: int32 + type: integer + resources: + description: The resources allocated to each sidecar replica. + A replica with more resources can handle larger input recordings + and will process them faster. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + schedulingOptions: + description: Options to configure scheduling for the reports deployment + properties: + affinity: + description: Affinity rules for scheduling Cryostat pods. + properties: + nodeAffinity: + description: 'Node affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: 'Pod affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: 'Pod anti-affinity scheduling rules for a + Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod + to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat + pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the + Cryostat report generator. + properties: + podSecurityContext: + description: Security Context to apply to the Cryostat report + generator pod. + properties: + fsGroup: + description: "A special supplemental group that applies + to all containers in a pod. Some volume types allow + the Kubelet to change the ownership of that volume to + be owned by the pod: \n 1. The owning GID will be the + FSGroup 2. The setgid bit is set (new files created + in the volume will be owned by FSGroup) 3. The permission + bits are OR'd with rw-rw---- \n If unset, the Kubelet + will not modify the ownership and permissions of any + volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of + changing ownership and permission of the volume before + being exposed inside Pod. This field will only apply + to volume types which support fsGroup based ownership(and + permissions). It will have no effect on ephemeral volume + types such as: secret, configmaps and emptydir. Valid + values are "OnRootMismatch" and "Always". If not specified, + "Always" is used. Note that this field cannot be set + when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all + containers. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp 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 + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's + primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container + process. If unspecified, no additional groups are added + to any container. Note that group memberships defined + in the container image for the uid of the container + process are still effective, even if they are not included + in this list. Note that this field cannot be set when + spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls + used for the pod. Pods with unsupported sysctls (by + the container runtime) might fail to launch. Note that + this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options within a + container's SecurityContext will be used. If set in + both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored by + components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the Pod. + All of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + reportsSecurityContext: + description: Security Context to apply to the Cryostat report + generator container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag + will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name + is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored by + components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the Pod. + All of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + type: object + subProcessMaxHeapSize: + description: When zero report sidecar replicas are requested, + SubProcessMaxHeapSize configures the maximum heap size of the + basic subprocess report generator in MiB. The default heap size + is `200` (MiB). + format: int32 + type: integer + type: object + resources: + description: Resource requirements for the Cryostat deployment. + properties: + coreResources: + description: Resource requirements for the Cryostat application. + If specifying a memory limit, at least 768MiB is recommended. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + dataSourceResources: + description: Resource requirements for the JFR Data Source container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + grafanaResources: + description: Resource requirements for the Grafana container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + schedulingOptions: + description: Options to configure scheduling for the Cryostat deployment + properties: + affinity: + description: Affinity rules for scheduling Cryostat pods. + properties: + nodeAffinity: + description: 'Node affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: 'Pod affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: 'Pod anti-affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod to + a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat pods + to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the Cryostat + application. + properties: + coreSecurityContext: + description: Security Context to apply to the Cryostat application + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + dataSourceSecurityContext: + description: Security Context to apply to the JFR Data Source + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + grafanaSecurityContext: + description: Security Context to apply to the Grafana container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + podSecurityContext: + description: Security Context to apply to the Cryostat pod. + properties: + fsGroup: + description: "A special supplemental group that applies to + all containers in a pod. Some volume types allow the Kubelet + to change the ownership of that volume to be owned by the + pod: \n 1. The owning GID will be the FSGroup 2. The setgid + bit is set (new files created in the volume will be owned + by FSGroup) 3. The permission bits are OR'd with rw-rw---- + \n If unset, the Kubelet will not modify the ownership and + permissions of any volume. Note that this field cannot be + set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will + have no effect on ephemeral volume types such as: secret, + configmaps and emptydir. Valid values are "OnRootMismatch" + and "Always". If not specified, "Always" is used. Note that + this field cannot be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field + cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is + windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + SecurityContext. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp 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 defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's primary + GID, the fsGroup (if specified), and group memberships defined + in the container image for the uid of the container process. + If unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image + for the uid of the container process are still effective, + even if they are not included in this list. Note that this + field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used + for the pod. Pods with unsupported sysctls (by the container + runtime) might fail to launch. Note that this field cannot + be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options within a container's + SecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + type: object + serviceOptions: + description: Options to customize the services created for the Cryostat + application and Grafana dashboard. + properties: + coreConfig: + description: Specification for the service responsible for the + Cryostat application. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the Cryostat application + service. Defaults to 8181. + format: int32 + type: integer + jmxPort: + description: Remote JMX port number for the Cryostat application + service. Defaults to 9091. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + grafanaConfig: + description: Specification for the service responsible for the + Cryostat Grafana dashboard. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the Grafana dashboard service. + Defaults to 3000. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + reportsConfig: + description: Specification for the service responsible for the + cryostat-reports sidecars. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the cryostat-reports service. + Defaults to 10000. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + type: object + storageOptions: + description: Options to customize the storage for Flight Recordings + and Templates. + properties: + emptyDir: + description: Configuration for an EmptyDir to be created by the + operator instead of a PVC. + properties: + enabled: + description: When enabled, Cryostat will use EmptyDir volumes + instead of a Persistent Volume Claim. Any PVC configurations + will be ignored. + type: boolean + medium: + description: Unless specified, the emptyDir volume will be + mounted on the same storage medium backing the node. Setting + this field to "Memory" will mount the emptyDir on a tmpfs + (RAM-backed filesystem). + type: string + sizeLimit: + description: The maximum memory limit for the emptyDir. Default + is unbounded. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + type: object + pvc: + description: Configuration for the Persistent Volume Claim to + be created by the operator. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Persistent Volume Claim + during its creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Persistent Volume Claim + during its creation. The label with key "app" is reserved + for use by the operator. + type: object + spec: + description: Spec for a Persistent Volume Claim, whose options + will override the defaults used by the operator. Unless + overriden, the PVC will be created with the default Storage + Class and 500MiB of storage. Once the operator has created + the PVC, changes to this field have no effect. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the 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. \n This is an alpha field and requires + enabling the DynamicResourceAllocation feature gate. + \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: '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 + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + type: object + type: object + targetDiscoveryOptions: + description: Options to configure the Cryostat application's target + discovery mechanisms. + properties: + builtInDiscoveryDisabled: + description: When true, the Cryostat application will disable + the built-in discovery mechanisms. Defaults to false + type: boolean + type: object + targetNamespaces: + description: 'List of namespaces whose workloads Cryostat should be + permitted to access and profile. Defaults to this Cryostat''s namespace. + Warning: All Cryostat users will be able to create and manage recordings + for workloads in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + items: + type: string + type: array + trustedCertSecrets: + description: List of TLS certificates to trust when connecting to + targets. + items: + properties: + certificateKey: + description: Key within secret containing the certificate. + type: string + secretName: + description: Name of secret in the local namespace. + type: string + required: + - secretName + type: object + type: array + required: + - installNamespace + - minimal + type: object + status: + description: ClusterCryostatStatus defines the observed state of ClusterCryostat. + properties: + applicationUrl: + description: Address of the deployed Cryostat web application. + type: string + conditions: + description: Conditions of the components managed by the Cryostat + Operator. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + grafanaSecret: + description: Name of the Secret containing the generated Grafana credentials. + type: string + targetNamespaces: + description: List of namespaces that Cryostat has been configured + and authorized to access and profile. + items: + type: string + type: array + required: + - applicationUrl + type: object + type: object + served: true storage: true subresources: status: {} diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index b465c8459..25ebf2503 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -2,10 +2,21 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: + cert-manager.io/inject-ca-from: cryostat-operator-system/cryostat-operator-serving-cert controller-gen.kubebuilder.io/version: v0.11.1 creationTimestamp: null name: cryostats.operator.cryostat.io spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: cryostat-operator-webhook-service + namespace: cryostat-operator-system + path: /convert + conversionReviewVersions: + - v1 group: operator.cryostat.io names: kind: Cryostat @@ -4728,6 +4739,4716 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.applicationUrl + name: Application URL + type: string + - jsonPath: .status.grafanaSecret + name: Grafana Secret + type: string + name: v1beta2 + schema: + openAPIV3Schema: + description: Cryostat allows you to install Cryostat for a single namespace. + It contains configuration options for controlling the Deployment of the + Cryostat application and its related components. A ClusterCryostat or Cryostat + instance must be created to instruct the operator to deploy the Cryostat + application. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CryostatSpec defines the desired state of Cryostat. + properties: + authProperties: + description: Override default authorization properties for Cryostat + on OpenShift. + properties: + clusterRoleName: + description: 'Name of the ClusterRole to use when Cryostat requests + a role-scoped OAuth token. This ClusterRole should contain permissions + for all Kubernetes objects listed in custom permission mapping. + More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + type: string + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the resource + mapping. + type: string + required: + - clusterRoleName + - configMapName + - filename + type: object + enableCertManager: + description: Use cert-manager to secure in-cluster communication between + Cryostat components. Requires cert-manager to be installed. + type: boolean + eventTemplates: + description: List of Flight Recorder Event Templates to preconfigure + in Cryostat. + items: + description: A ConfigMap containing a .jfc template file. + properties: + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the template + file. + type: string + required: + - configMapName + - filename + type: object + type: array + jmxCacheOptions: + description: Options to customize the JMX target connections cache + for the Cryostat application. + properties: + targetCacheSize: + description: The maximum number of JMX connections to cache. Use + `-1` for an unlimited cache size (TTL expiration only). Defaults + to `-1`. + format: int32 + minimum: -1 + type: integer + targetCacheTTL: + description: The time to live (in seconds) for cached JMX connections. + Defaults to `10`. + format: int32 + minimum: 1 + type: integer + type: object + jmxCredentialsDatabaseOptions: + description: Options to configure the Cryostat application's credentials + database. + properties: + databaseSecretName: + description: Name of the secret containing the password to encrypt + credentials database. + type: string + type: object + maxWsConnections: + description: The maximum number of WebSocket client connections allowed + (minimum 1, default unlimited). + format: int32 + minimum: 1 + type: integer + minimal: + description: Deploy a pared-down Cryostat instance with no Grafana + Dashboard or JFR Data Source. + type: boolean + networkOptions: + description: Options to control how the operator exposes the application + outside of the cluster, such as using an Ingress or Route. + properties: + commandConfig: + description: "Specifications for how to expose the Cryostat command + service, which serves the WebSocket command channel. \n Deprecated: + CommandConfig is no longer used." + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + coreConfig: + description: Specifications for how to expose the Cryostat service, + which serves the Cryostat application. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + grafanaConfig: + description: Specifications for how to expose Cryostat's Grafana + service, which serves the Grafana dashboard. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + type: object + operandMetadata: + description: Options to configure the Cryostat deployments and pods + metadata + properties: + deploymentMetadata: + description: Options to configure the Cryostat deployments metadata + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the resources during its + creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the resources during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + type: object + podMetadata: + description: Options to configure the Cryostat pods metadata + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the resources during its + creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the resources during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + type: object + type: object + reportOptions: + description: Options to configure Cryostat Automated Report Analysis. + properties: + replicas: + description: The number of report sidecar replica containers to + deploy. Each replica can service one report generation request + at a time. + format: int32 + type: integer + resources: + description: The resources allocated to each sidecar replica. + A replica with more resources can handle larger input recordings + and will process them faster. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + schedulingOptions: + description: Options to configure scheduling for the reports deployment + properties: + affinity: + description: Affinity rules for scheduling Cryostat pods. + properties: + nodeAffinity: + description: 'Node affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: 'Pod affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: 'Pod anti-affinity scheduling rules for a + Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod + to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat + pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the + Cryostat report generator. + properties: + podSecurityContext: + description: Security Context to apply to the Cryostat report + generator pod. + properties: + fsGroup: + description: "A special supplemental group that applies + to all containers in a pod. Some volume types allow + the Kubelet to change the ownership of that volume to + be owned by the pod: \n 1. The owning GID will be the + FSGroup 2. The setgid bit is set (new files created + in the volume will be owned by FSGroup) 3. The permission + bits are OR'd with rw-rw---- \n If unset, the Kubelet + will not modify the ownership and permissions of any + volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of + changing ownership and permission of the volume before + being exposed inside Pod. This field will only apply + to volume types which support fsGroup based ownership(and + permissions). It will have no effect on ephemeral volume + types such as: secret, configmaps and emptydir. Valid + values are "OnRootMismatch" and "Always". If not specified, + "Always" is used. Note that this field cannot be set + when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all + containers. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp 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 + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's + primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container + process. If unspecified, no additional groups are added + to any container. Note that group memberships defined + in the container image for the uid of the container + process are still effective, even if they are not included + in this list. Note that this field cannot be set when + spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls + used for the pod. Pods with unsupported sysctls (by + the container runtime) might fail to launch. Note that + this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options within a + container's SecurityContext will be used. If set in + both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored by + components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the Pod. + All of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + reportsSecurityContext: + description: Security Context to apply to the Cryostat report + generator container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag + will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name + is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored by + components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the Pod. + All of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + type: object + subProcessMaxHeapSize: + description: When zero report sidecar replicas are requested, + SubProcessMaxHeapSize configures the maximum heap size of the + basic subprocess report generator in MiB. The default heap size + is `200` (MiB). + format: int32 + type: integer + type: object + resources: + description: Resource requirements for the Cryostat deployment. + properties: + coreResources: + description: Resource requirements for the Cryostat application. + If specifying a memory limit, at least 768MiB is recommended. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + dataSourceResources: + description: Resource requirements for the JFR Data Source container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + grafanaResources: + description: Resource requirements for the Grafana container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + schedulingOptions: + description: Options to configure scheduling for the Cryostat deployment + properties: + affinity: + description: Affinity rules for scheduling Cryostat pods. + properties: + nodeAffinity: + description: 'Node affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: 'Pod affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: 'Pod anti-affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod to + a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat pods + to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the Cryostat + application. + properties: + coreSecurityContext: + description: Security Context to apply to the Cryostat application + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + dataSourceSecurityContext: + description: Security Context to apply to the JFR Data Source + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + grafanaSecurityContext: + description: Security Context to apply to the Grafana container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + podSecurityContext: + description: Security Context to apply to the Cryostat pod. + properties: + fsGroup: + description: "A special supplemental group that applies to + all containers in a pod. Some volume types allow the Kubelet + to change the ownership of that volume to be owned by the + pod: \n 1. The owning GID will be the FSGroup 2. The setgid + bit is set (new files created in the volume will be owned + by FSGroup) 3. The permission bits are OR'd with rw-rw---- + \n If unset, the Kubelet will not modify the ownership and + permissions of any volume. Note that this field cannot be + set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will + have no effect on ephemeral volume types such as: secret, + configmaps and emptydir. Valid values are "OnRootMismatch" + and "Always". If not specified, "Always" is used. Note that + this field cannot be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field + cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is + windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + SecurityContext. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp 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 defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's primary + GID, the fsGroup (if specified), and group memberships defined + in the container image for the uid of the container process. + If unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image + for the uid of the container process are still effective, + even if they are not included in this list. Note that this + field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used + for the pod. Pods with unsupported sysctls (by the container + runtime) might fail to launch. Note that this field cannot + be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options within a container's + SecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + type: object + serviceOptions: + description: Options to customize the services created for the Cryostat + application and Grafana dashboard. + properties: + coreConfig: + description: Specification for the service responsible for the + Cryostat application. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the Cryostat application + service. Defaults to 8181. + format: int32 + type: integer + jmxPort: + description: Remote JMX port number for the Cryostat application + service. Defaults to 9091. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + grafanaConfig: + description: Specification for the service responsible for the + Cryostat Grafana dashboard. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the Grafana dashboard service. + Defaults to 3000. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + reportsConfig: + description: Specification for the service responsible for the + cryostat-reports sidecars. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the cryostat-reports service. + Defaults to 10000. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + type: object + storageOptions: + description: Options to customize the storage for Flight Recordings + and Templates. + properties: + emptyDir: + description: Configuration for an EmptyDir to be created by the + operator instead of a PVC. + properties: + enabled: + description: When enabled, Cryostat will use EmptyDir volumes + instead of a Persistent Volume Claim. Any PVC configurations + will be ignored. + type: boolean + medium: + description: Unless specified, the emptyDir volume will be + mounted on the same storage medium backing the node. Setting + this field to "Memory" will mount the emptyDir on a tmpfs + (RAM-backed filesystem). + type: string + sizeLimit: + description: The maximum memory limit for the emptyDir. Default + is unbounded. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + type: object + pvc: + description: Configuration for the Persistent Volume Claim to + be created by the operator. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Persistent Volume Claim + during its creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Persistent Volume Claim + during its creation. The label with key "app" is reserved + for use by the operator. + type: object + spec: + description: Spec for a Persistent Volume Claim, whose options + will override the defaults used by the operator. Unless + overriden, the PVC will be created with the default Storage + Class and 500MiB of storage. Once the operator has created + the PVC, changes to this field have no effect. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the 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. \n This is an alpha field and requires + enabling the DynamicResourceAllocation feature gate. + \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: '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 + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + type: object + type: object + targetDiscoveryOptions: + description: Options to configure the Cryostat application's target + discovery mechanisms. + properties: + builtInDiscoveryDisabled: + description: When true, the Cryostat application will disable + the built-in discovery mechanisms. Defaults to false + type: boolean + type: object + targetNamespaces: + description: 'List of namespaces whose workloads Cryostat should be + permitted to access and profile. Defaults to this Cryostat''s namespace. + Warning: All Cryostat users will be able to create and manage recordings + for workloads in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + items: + type: string + type: array + trustedCertSecrets: + description: List of TLS certificates to trust when connecting to + targets. + items: + properties: + certificateKey: + description: Key within secret containing the certificate. + type: string + secretName: + description: Name of secret in the local namespace. + type: string + required: + - secretName + type: object + type: array + required: + - minimal + type: object + status: + description: CryostatStatus defines the observed state of Cryostat. + properties: + applicationUrl: + description: Address of the deployed Cryostat web application. + type: string + conditions: + description: Conditions of the components managed by the Cryostat + Operator. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + grafanaSecret: + description: Name of the Secret containing the generated Grafana credentials. + type: string + targetNamespaces: + description: List of namespaces that Cryostat has been configured + and authorized to access and profile. + items: + type: string + type: array + required: + - applicationUrl + type: object + type: object + served: true storage: true subresources: status: {} diff --git a/config/crd/bases/operator.cryostat.io_clustercryostats.yaml b/config/crd/bases/operator.cryostat.io_clustercryostats.yaml index 9d606b91f..d92d831dc 100644 --- a/config/crd/bases/operator.cryostat.io_clustercryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_clustercryostats.yaml @@ -4748,6 +4748,4721 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.applicationUrl + name: Application URL + type: string + - jsonPath: .status.grafanaSecret + name: Grafana Secret + type: string + name: v1beta2 + schema: + openAPIV3Schema: + description: ClusterCryostat allows you to install Cryostat for multiple namespaces + or cluster-wide. It contains configuration options for controlling the Deployment + of the Cryostat application and its related components. A ClusterCryostat + or Cryostat instance must be created to instruct the operator to deploy + the Cryostat application. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ClusterCryostatSpec defines the desired state of ClusterCryostat. + properties: + authProperties: + description: Override default authorization properties for Cryostat + on OpenShift. + properties: + clusterRoleName: + description: 'Name of the ClusterRole to use when Cryostat requests + a role-scoped OAuth token. This ClusterRole should contain permissions + for all Kubernetes objects listed in custom permission mapping. + More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + type: string + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the resource + mapping. + type: string + required: + - clusterRoleName + - configMapName + - filename + type: object + enableCertManager: + description: Use cert-manager to secure in-cluster communication between + Cryostat components. Requires cert-manager to be installed. + type: boolean + eventTemplates: + description: List of Flight Recorder Event Templates to preconfigure + in Cryostat. + items: + description: A ConfigMap containing a .jfc template file. + properties: + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the template + file. + type: string + required: + - configMapName + - filename + type: object + type: array + installNamespace: + description: Namespace where Cryostat should be installed. On multi-tenant + clusters, we strongly suggest installing Cryostat into its own namespace. + type: string + jmxCacheOptions: + description: Options to customize the JMX target connections cache + for the Cryostat application. + properties: + targetCacheSize: + description: The maximum number of JMX connections to cache. Use + `-1` for an unlimited cache size (TTL expiration only). Defaults + to `-1`. + format: int32 + minimum: -1 + type: integer + targetCacheTTL: + description: The time to live (in seconds) for cached JMX connections. + Defaults to `10`. + format: int32 + minimum: 1 + type: integer + type: object + jmxCredentialsDatabaseOptions: + description: Options to configure the Cryostat application's credentials + database. + properties: + databaseSecretName: + description: Name of the secret containing the password to encrypt + credentials database. + type: string + type: object + maxWsConnections: + description: The maximum number of WebSocket client connections allowed + (minimum 1, default unlimited). + format: int32 + minimum: 1 + type: integer + minimal: + description: Deploy a pared-down Cryostat instance with no Grafana + Dashboard or JFR Data Source. + type: boolean + networkOptions: + description: Options to control how the operator exposes the application + outside of the cluster, such as using an Ingress or Route. + properties: + commandConfig: + description: "Specifications for how to expose the Cryostat command + service, which serves the WebSocket command channel. \n Deprecated: + CommandConfig is no longer used." + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + coreConfig: + description: Specifications for how to expose the Cryostat service, + which serves the Cryostat application. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + grafanaConfig: + description: Specifications for how to expose Cryostat's Grafana + service, which serves the Grafana dashboard. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + type: object + operandMetadata: + description: Options to configure the Cryostat deployments and pods + metadata + properties: + deploymentMetadata: + description: Options to configure the Cryostat deployments metadata + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the resources during its + creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the resources during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + type: object + podMetadata: + description: Options to configure the Cryostat pods metadata + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the resources during its + creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the resources during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + type: object + type: object + reportOptions: + description: Options to configure Cryostat Automated Report Analysis. + properties: + replicas: + description: The number of report sidecar replica containers to + deploy. Each replica can service one report generation request + at a time. + format: int32 + type: integer + resources: + description: The resources allocated to each sidecar replica. + A replica with more resources can handle larger input recordings + and will process them faster. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + schedulingOptions: + description: Options to configure scheduling for the reports deployment + properties: + affinity: + description: Affinity rules for scheduling Cryostat pods. + properties: + nodeAffinity: + description: 'Node affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: 'Pod affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: 'Pod anti-affinity scheduling rules for a + Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod + to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat + pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the + Cryostat report generator. + properties: + podSecurityContext: + description: Security Context to apply to the Cryostat report + generator pod. + properties: + fsGroup: + description: "A special supplemental group that applies + to all containers in a pod. Some volume types allow + the Kubelet to change the ownership of that volume to + be owned by the pod: \n 1. The owning GID will be the + FSGroup 2. The setgid bit is set (new files created + in the volume will be owned by FSGroup) 3. The permission + bits are OR'd with rw-rw---- \n If unset, the Kubelet + will not modify the ownership and permissions of any + volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of + changing ownership and permission of the volume before + being exposed inside Pod. This field will only apply + to volume types which support fsGroup based ownership(and + permissions). It will have no effect on ephemeral volume + types such as: secret, configmaps and emptydir. Valid + values are "OnRootMismatch" and "Always". If not specified, + "Always" is used. Note that this field cannot be set + when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all + containers. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp 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 + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's + primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container + process. If unspecified, no additional groups are added + to any container. Note that group memberships defined + in the container image for the uid of the container + process are still effective, even if they are not included + in this list. Note that this field cannot be set when + spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls + used for the pod. Pods with unsupported sysctls (by + the container runtime) might fail to launch. Note that + this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options within a + container's SecurityContext will be used. If set in + both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored by + components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the Pod. + All of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + reportsSecurityContext: + description: Security Context to apply to the Cryostat report + generator container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag + will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name + is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored by + components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the Pod. + All of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + type: object + subProcessMaxHeapSize: + description: When zero report sidecar replicas are requested, + SubProcessMaxHeapSize configures the maximum heap size of the + basic subprocess report generator in MiB. The default heap size + is `200` (MiB). + format: int32 + type: integer + type: object + resources: + description: Resource requirements for the Cryostat deployment. + properties: + coreResources: + description: Resource requirements for the Cryostat application. + If specifying a memory limit, at least 768MiB is recommended. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + dataSourceResources: + description: Resource requirements for the JFR Data Source container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + grafanaResources: + description: Resource requirements for the Grafana container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + schedulingOptions: + description: Options to configure scheduling for the Cryostat deployment + properties: + affinity: + description: Affinity rules for scheduling Cryostat pods. + properties: + nodeAffinity: + description: 'Node affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: 'Pod affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: 'Pod anti-affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod to + a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat pods + to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the Cryostat + application. + properties: + coreSecurityContext: + description: Security Context to apply to the Cryostat application + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + dataSourceSecurityContext: + description: Security Context to apply to the JFR Data Source + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + grafanaSecurityContext: + description: Security Context to apply to the Grafana container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + podSecurityContext: + description: Security Context to apply to the Cryostat pod. + properties: + fsGroup: + description: "A special supplemental group that applies to + all containers in a pod. Some volume types allow the Kubelet + to change the ownership of that volume to be owned by the + pod: \n 1. The owning GID will be the FSGroup 2. The setgid + bit is set (new files created in the volume will be owned + by FSGroup) 3. The permission bits are OR'd with rw-rw---- + \n If unset, the Kubelet will not modify the ownership and + permissions of any volume. Note that this field cannot be + set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will + have no effect on ephemeral volume types such as: secret, + configmaps and emptydir. Valid values are "OnRootMismatch" + and "Always". If not specified, "Always" is used. Note that + this field cannot be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field + cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is + windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + SecurityContext. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp 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 defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's primary + GID, the fsGroup (if specified), and group memberships defined + in the container image for the uid of the container process. + If unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image + for the uid of the container process are still effective, + even if they are not included in this list. Note that this + field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used + for the pod. Pods with unsupported sysctls (by the container + runtime) might fail to launch. Note that this field cannot + be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options within a container's + SecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + type: object + serviceOptions: + description: Options to customize the services created for the Cryostat + application and Grafana dashboard. + properties: + coreConfig: + description: Specification for the service responsible for the + Cryostat application. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the Cryostat application + service. Defaults to 8181. + format: int32 + type: integer + jmxPort: + description: Remote JMX port number for the Cryostat application + service. Defaults to 9091. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + grafanaConfig: + description: Specification for the service responsible for the + Cryostat Grafana dashboard. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the Grafana dashboard service. + Defaults to 3000. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + reportsConfig: + description: Specification for the service responsible for the + cryostat-reports sidecars. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the cryostat-reports service. + Defaults to 10000. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + type: object + storageOptions: + description: Options to customize the storage for Flight Recordings + and Templates. + properties: + emptyDir: + description: Configuration for an EmptyDir to be created by the + operator instead of a PVC. + properties: + enabled: + description: When enabled, Cryostat will use EmptyDir volumes + instead of a Persistent Volume Claim. Any PVC configurations + will be ignored. + type: boolean + medium: + description: Unless specified, the emptyDir volume will be + mounted on the same storage medium backing the node. Setting + this field to "Memory" will mount the emptyDir on a tmpfs + (RAM-backed filesystem). + type: string + sizeLimit: + description: The maximum memory limit for the emptyDir. Default + is unbounded. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + type: object + pvc: + description: Configuration for the Persistent Volume Claim to + be created by the operator. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Persistent Volume Claim + during its creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Persistent Volume Claim + during its creation. The label with key "app" is reserved + for use by the operator. + type: object + spec: + description: Spec for a Persistent Volume Claim, whose options + will override the defaults used by the operator. Unless + overriden, the PVC will be created with the default Storage + Class and 500MiB of storage. Once the operator has created + the PVC, changes to this field have no effect. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the 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. \n This is an alpha field and requires + enabling the DynamicResourceAllocation feature gate. + \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: '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 + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + type: object + type: object + targetDiscoveryOptions: + description: Options to configure the Cryostat application's target + discovery mechanisms. + properties: + builtInDiscoveryDisabled: + description: When true, the Cryostat application will disable + the built-in discovery mechanisms. Defaults to false + type: boolean + type: object + targetNamespaces: + description: 'List of namespaces whose workloads Cryostat should be + permitted to access and profile. Defaults to this Cryostat''s namespace. + Warning: All Cryostat users will be able to create and manage recordings + for workloads in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + items: + type: string + type: array + trustedCertSecrets: + description: List of TLS certificates to trust when connecting to + targets. + items: + properties: + certificateKey: + description: Key within secret containing the certificate. + type: string + secretName: + description: Name of secret in the local namespace. + type: string + required: + - secretName + type: object + type: array + required: + - installNamespace + - minimal + type: object + status: + description: ClusterCryostatStatus defines the observed state of ClusterCryostat. + properties: + applicationUrl: + description: Address of the deployed Cryostat web application. + type: string + conditions: + description: Conditions of the components managed by the Cryostat + Operator. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + grafanaSecret: + description: Name of the Secret containing the generated Grafana credentials. + type: string + targetNamespaces: + description: List of namespaces that Cryostat has been configured + and authorized to access and profile. + items: + type: string + type: array + required: + - applicationUrl + type: object + type: object + served: true storage: true subresources: status: {} diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 6cce048fb..5de7ef336 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -4729,6 +4729,4716 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.applicationUrl + name: Application URL + type: string + - jsonPath: .status.grafanaSecret + name: Grafana Secret + type: string + name: v1beta2 + schema: + openAPIV3Schema: + description: Cryostat allows you to install Cryostat for a single namespace. + It contains configuration options for controlling the Deployment of the + Cryostat application and its related components. A ClusterCryostat or Cryostat + instance must be created to instruct the operator to deploy the Cryostat + application. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CryostatSpec defines the desired state of Cryostat. + properties: + authProperties: + description: Override default authorization properties for Cryostat + on OpenShift. + properties: + clusterRoleName: + description: 'Name of the ClusterRole to use when Cryostat requests + a role-scoped OAuth token. This ClusterRole should contain permissions + for all Kubernetes objects listed in custom permission mapping. + More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + type: string + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the resource + mapping. + type: string + required: + - clusterRoleName + - configMapName + - filename + type: object + enableCertManager: + description: Use cert-manager to secure in-cluster communication between + Cryostat components. Requires cert-manager to be installed. + type: boolean + eventTemplates: + description: List of Flight Recorder Event Templates to preconfigure + in Cryostat. + items: + description: A ConfigMap containing a .jfc template file. + properties: + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the template + file. + type: string + required: + - configMapName + - filename + type: object + type: array + jmxCacheOptions: + description: Options to customize the JMX target connections cache + for the Cryostat application. + properties: + targetCacheSize: + description: The maximum number of JMX connections to cache. Use + `-1` for an unlimited cache size (TTL expiration only). Defaults + to `-1`. + format: int32 + minimum: -1 + type: integer + targetCacheTTL: + description: The time to live (in seconds) for cached JMX connections. + Defaults to `10`. + format: int32 + minimum: 1 + type: integer + type: object + jmxCredentialsDatabaseOptions: + description: Options to configure the Cryostat application's credentials + database. + properties: + databaseSecretName: + description: Name of the secret containing the password to encrypt + credentials database. + type: string + type: object + maxWsConnections: + description: The maximum number of WebSocket client connections allowed + (minimum 1, default unlimited). + format: int32 + minimum: 1 + type: integer + minimal: + description: Deploy a pared-down Cryostat instance with no Grafana + Dashboard or JFR Data Source. + type: boolean + networkOptions: + description: Options to control how the operator exposes the application + outside of the cluster, such as using an Ingress or Route. + properties: + commandConfig: + description: "Specifications for how to expose the Cryostat command + service, which serves the WebSocket command channel. \n Deprecated: + CommandConfig is no longer used." + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + coreConfig: + description: Specifications for how to expose the Cryostat service, + which serves the Cryostat application. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + grafanaConfig: + description: Specifications for how to expose Cryostat's Grafana + service, which serves the Grafana dashboard. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Ingress or Route during + its creation. + type: object + ingressSpec: + description: Configuration for an Ingress object. Currently + subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate + between ingresses/services. + properties: + defaultBackend: + description: DefaultBackend is the backend that should + handle requests that don't match any rule. If Rules + are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests + that do not match any of the rules will be up to the + Ingress controller. + properties: + resource: + description: Resource is an ObjectRef to another Kubernetes + resource in the namespace of the Ingress object. + If resource is specified, a service.Name and service.Port + must not be specified. This is a mutually exclusive + setting with "Service". + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a Service as a Backend. + This is a mutually exclusive setting with "Resource". + properties: + name: + description: Name is the referenced service. The + service must exist in the same namespace as + the Ingress object. + type: string + port: + description: Port of the referenced service. A + port name or port number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name of the port + on the Service. This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the numerical port + number (e.g. 80) on the Service. This is + a mutually exclusive setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + ingressClassName: + description: IngressClassName is the name of an IngressClass + cluster resource. Ingress controller implementations + use this field to know whether they should be serving + this Ingress resource, by a transitive connection (controller + -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` + annotation (simple constant name) was never formally + defined, it was widely supported by Ingress controllers + to create a direct binding between Ingress controller + and Ingress resources. Newly created Ingress resources + should prefer using the field. However, even though + the annotation is officially deprecated, for backwards + compatibility reasons, ingress controllers should still + honor that annotation if present. + type: string + rules: + description: A list of host rules used to configure the + Ingress. If unspecified, or no rule matches, all traffic + is sent to the default backend. + items: + description: IngressRule represents the rules mapping + the paths under a specified host to the related backend + services. Incoming requests are first evaluated for + a host match, then routed to the backend associated + with the matching IngressRuleValue. + properties: + host: + description: "Host is the fully qualified domain + name of a network host, as defined by RFC 3986. + Note the following deviations from the \"host\" + part of the URI as defined in RFC 3986: 1. IPs + are not allowed. Currently an IngressRuleValue + can only apply to the IP in the Spec of the parent + Ingress. 2. The `:` delimiter is not respected + because ports are not allowed. Currently the port + of an Ingress is implicitly :80 for http and :443 + for https. Both these may change in the future. + Incoming requests are matched against the host + before the IngressRuleValue. If the host is unspecified, + the Ingress routes all traffic based on the specified + IngressRuleValue. \n Host can be \"precise\" which + is a domain name without the terminating dot of + a network host (e.g. \"foo.bar.com\") or \"wildcard\", + which is a domain name prefixed with a single + wildcard label (e.g. \"*.foo.com\"). The wildcard + character '*' must appear by itself as the first + DNS label and matches only a single label. You + cannot have a wildcard label by itself (e.g. Host + == \"*\"). Requests will be matched against the + Host field in the following way: 1. If Host is + precise, the request matches this rule if the + http host header is equal to Host. 2. If Host + is a wildcard, then the request matches this rule + if the http host header is to equal to the suffix + (removing the first label) of the wildcard rule." + type: string + http: + description: 'HTTPIngressRuleValue is a list of + http selectors pointing to backends. In the example: + http:///? -> backend where + where parts of the url correspond to RFC 3986, + this resource will be used to match against everything + after the last ''/'' and before the first ''?'' + or ''#''.' + properties: + paths: + description: A collection of paths that map + requests to backends. + items: + description: HTTPIngressPath associates a + path with a backend. Incoming urls matching + the path are forwarded to the backend. + properties: + backend: + description: Backend defines the referenced + service endpoint to which the traffic + will be forwarded to. + properties: + resource: + description: Resource is an ObjectRef + to another Kubernetes resource in + the namespace of the Ingress object. + If resource is specified, a service.Name + and service.Port must not be specified. + This is a mutually exclusive setting + with "Service". + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any + other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + service: + description: Service references a + Service as a Backend. This is a + mutually exclusive setting with + "Resource". + properties: + name: + description: Name is the referenced + service. The service must exist + in the same namespace as the + Ingress object. + type: string + port: + description: Port of the referenced + service. A port name or port + number is required for a IngressServiceBackend. + properties: + name: + description: Name is the name + of the port on the Service. + This is a mutually exclusive + setting with "Number". + type: string + number: + description: Number is the + numerical port number (e.g. + 80) on the Service. This + is a mutually exclusive + setting with "Name". + format: int32 + type: integer + type: object + required: + - name + type: object + type: object + path: + description: Path is matched against the + path of an incoming request. Currently + it can contain characters disallowed + from the conventional "path" part of + a URL as defined by RFC 3986. Paths + must begin with a '/' and must be present + when using PathType with value "Exact" + or "Prefix". + type: string + pathType: + description: 'PathType determines the + interpretation of the Path matching. + PathType can be one of the following + values: * Exact: Matches the URL path + exactly. * Prefix: Matches based on + a URL path prefix split by ''/''. Matching + is done on a path element by element + basis. A path element refers is the + list of labels in the path split by + the ''/'' separator. A request is a + match for path p if every p is an element-wise + prefix of p of the request path. Note + that if the last element of the path + is a substring of the last element in + request path, it is not a match (e.g. + /foo/bar matches /foo/bar/baz, but does + not match /foo/barbaz). * ImplementationSpecific: + Interpretation of the Path matching + is up to the IngressClass. Implementations + can treat this as a separate PathType + or treat it identically to Prefix or + Exact path types. Implementations are + required to support all path types.' + type: string + required: + - backend + - pathType + type: object + type: array + x-kubernetes-list-type: atomic + required: + - paths + type: object + type: object + type: array + x-kubernetes-list-type: atomic + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Ingress or Route during + its creation. The label with key "app" is reserved for use + by the operator. + type: object + type: object + type: object + operandMetadata: + description: Options to configure the Cryostat deployments and pods + metadata + properties: + deploymentMetadata: + description: Options to configure the Cryostat deployments metadata + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the resources during its + creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the resources during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + type: object + podMetadata: + description: Options to configure the Cryostat pods metadata + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the resources during its + creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the resources during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + type: object + type: object + reportOptions: + description: Options to configure Cryostat Automated Report Analysis. + properties: + replicas: + description: The number of report sidecar replica containers to + deploy. Each replica can service one report generation request + at a time. + format: int32 + type: integer + resources: + description: The resources allocated to each sidecar replica. + A replica with more resources can handle larger input recordings + and will process them faster. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + schedulingOptions: + description: Options to configure scheduling for the reports deployment + properties: + affinity: + description: Affinity rules for scheduling Cryostat pods. + properties: + nodeAffinity: + description: 'Node affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: 'Pod affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: 'Pod anti-affinity scheduling rules for a + Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod + to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat + pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the + Cryostat report generator. + properties: + podSecurityContext: + description: Security Context to apply to the Cryostat report + generator pod. + properties: + fsGroup: + description: "A special supplemental group that applies + to all containers in a pod. Some volume types allow + the Kubelet to change the ownership of that volume to + be owned by the pod: \n 1. The owning GID will be the + FSGroup 2. The setgid bit is set (new files created + in the volume will be owned by FSGroup) 3. The permission + bits are OR'd with rw-rw---- \n If unset, the Kubelet + will not modify the ownership and permissions of any + volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of + changing ownership and permission of the volume before + being exposed inside Pod. This field will only apply + to volume types which support fsGroup based ownership(and + permissions). It will have no effect on ephemeral volume + types such as: secret, configmaps and emptydir. Valid + values are "OnRootMismatch" and "Always". If not specified, + "Always" is used. Note that this field cannot be set + when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all + containers. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp 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 + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's + primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container + process. If unspecified, no additional groups are added + to any container. Note that group memberships defined + in the container image for the uid of the container + process are still effective, even if they are not included + in this list. Note that this field cannot be set when + spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls + used for the pod. Pods with unsupported sysctls (by + the container runtime) might fail to launch. Note that + this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options within a + container's SecurityContext will be used. If set in + both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored by + components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the Pod. + All of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + reportsSecurityContext: + description: Security Context to apply to the Cryostat report + generator container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag + will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name + is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored by + components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the Pod. + All of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + type: object + subProcessMaxHeapSize: + description: When zero report sidecar replicas are requested, + SubProcessMaxHeapSize configures the maximum heap size of the + basic subprocess report generator in MiB. The default heap size + is `200` (MiB). + format: int32 + type: integer + type: object + resources: + description: Resource requirements for the Cryostat deployment. + properties: + coreResources: + description: Resource requirements for the Cryostat application. + If specifying a memory limit, at least 768MiB is recommended. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + dataSourceResources: + description: Resource requirements for the JFR Data Source container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + grafanaResources: + description: Resource requirements for the Grafana container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + schedulingOptions: + description: Options to configure scheduling for the Cryostat deployment + properties: + affinity: + description: Affinity rules for scheduling Cryostat pods. + properties: + nodeAffinity: + description: 'Node affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: 'Pod affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: 'Pod anti-affinity scheduling rules for a Cryostat + pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-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. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod to + a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat pods + to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the Cryostat + application. + properties: + coreSecurityContext: + description: Security Context to apply to the Cryostat application + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + dataSourceSecurityContext: + description: Security Context to apply to the JFR Data Source + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + grafanaSecurityContext: + description: Security Context to apply to the Grafana container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + podSecurityContext: + description: Security Context to apply to the Cryostat pod. + properties: + fsGroup: + description: "A special supplemental group that applies to + all containers in a pod. Some volume types allow the Kubelet + to change the ownership of that volume to be owned by the + pod: \n 1. The owning GID will be the FSGroup 2. The setgid + bit is set (new files created in the volume will be owned + by FSGroup) 3. The permission bits are OR'd with rw-rw---- + \n If unset, the Kubelet will not modify the ownership and + permissions of any volume. Note that this field cannot be + set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will + have no effect on ephemeral volume types such as: secret, + configmaps and emptydir. Valid values are "OnRootMismatch" + and "Always". If not specified, "Always" is used. Note that + this field cannot be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field + cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is + windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + SecurityContext. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp 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 defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's primary + GID, the fsGroup (if specified), and group memberships defined + in the container image for the uid of the container process. + If unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image + for the uid of the container process are still effective, + even if they are not included in this list. Note that this + field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used + for the pod. Pods with unsupported sysctls (by the container + runtime) might fail to launch. Note that this field cannot + be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options within a container's + SecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + type: object + serviceOptions: + description: Options to customize the services created for the Cryostat + application and Grafana dashboard. + properties: + coreConfig: + description: Specification for the service responsible for the + Cryostat application. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the Cryostat application + service. Defaults to 8181. + format: int32 + type: integer + jmxPort: + description: Remote JMX port number for the Cryostat application + service. Defaults to 9091. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + grafanaConfig: + description: Specification for the service responsible for the + Cryostat Grafana dashboard. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the Grafana dashboard service. + Defaults to 3000. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + reportsConfig: + description: Specification for the service responsible for the + cryostat-reports sidecars. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the cryostat-reports service. + Defaults to 10000. + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object + type: object + storageOptions: + description: Options to customize the storage for Flight Recordings + and Templates. + properties: + emptyDir: + description: Configuration for an EmptyDir to be created by the + operator instead of a PVC. + properties: + enabled: + description: When enabled, Cryostat will use EmptyDir volumes + instead of a Persistent Volume Claim. Any PVC configurations + will be ignored. + type: boolean + medium: + description: Unless specified, the emptyDir volume will be + mounted on the same storage medium backing the node. Setting + this field to "Memory" will mount the emptyDir on a tmpfs + (RAM-backed filesystem). + type: string + sizeLimit: + description: The maximum memory limit for the emptyDir. Default + is unbounded. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + type: object + pvc: + description: Configuration for the Persistent Volume Claim to + be created by the operator. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Persistent Volume Claim + during its creation. + type: object + labels: + additionalProperties: + type: string + description: Labels to add to the Persistent Volume Claim + during its creation. The label with key "app" is reserved + for use by the operator. + type: object + spec: + description: Spec for a Persistent Volume Claim, whose options + will override the defaults used by the operator. Unless + overriden, the PVC will be created with the default Storage + Class and 500MiB of storage. Once the operator has created + the PVC, changes to this field have no effect. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the 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. \n This is an alpha field and requires + enabling the DynamicResourceAllocation feature gate. + \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: '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 + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + type: object + type: object + targetDiscoveryOptions: + description: Options to configure the Cryostat application's target + discovery mechanisms. + properties: + builtInDiscoveryDisabled: + description: When true, the Cryostat application will disable + the built-in discovery mechanisms. Defaults to false + type: boolean + type: object + targetNamespaces: + description: 'List of namespaces whose workloads Cryostat should be + permitted to access and profile. Defaults to this Cryostat''s namespace. + Warning: All Cryostat users will be able to create and manage recordings + for workloads in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + items: + type: string + type: array + trustedCertSecrets: + description: List of TLS certificates to trust when connecting to + targets. + items: + properties: + certificateKey: + description: Key within secret containing the certificate. + type: string + secretName: + description: Name of secret in the local namespace. + type: string + required: + - secretName + type: object + type: array + required: + - minimal + type: object + status: + description: CryostatStatus defines the observed state of Cryostat. + properties: + applicationUrl: + description: Address of the deployed Cryostat web application. + type: string + conditions: + description: Conditions of the components managed by the Cryostat + Operator. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + grafanaSecret: + description: Name of the Secret containing the generated Grafana credentials. + type: string + targetNamespaces: + description: List of namespaces that Cryostat has been configured + and authorized to access and profile. + items: + type: string + type: array + required: + - applicationUrl + type: object + type: object + served: true storage: true subresources: status: {} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 153a06d7c..bd3981702 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -9,14 +9,14 @@ resources: patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD -#- patches/webhook_in_cryostats.yaml -#- patches/webhook_in_clustercryostats.yaml +- patches/webhook_in_cryostats.yaml +- patches/webhook_in_clustercryostats.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD -#- patches/cainjection_in_cryostats.yaml -#- patches/cainjection_in_clustercryostats.yaml +- patches/cainjection_in_cryostats.yaml +- patches/cainjection_in_clustercryostats.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/webhook_in_cryostats.yaml b/config/crd/patches/webhook_in_cryostats.yaml index d8bd2b812..f90b447e8 100644 --- a/config/crd/patches/webhook_in_cryostats.yaml +++ b/config/crd/patches/webhook_in_cryostats.yaml @@ -12,3 +12,5 @@ spec: namespace: system name: webhook-service path: /convert + conversionReviewVersions: + - v1 diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index e50ac282b..6f4957f46 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -12,17 +12,6 @@ namePrefix: cryostat-operator- #commonLabels: # someName: someValue -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -#- ../webhook -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus - -patchesStrategicMerge: -- image_tag_patch.yaml -- image_pull_patch.yaml # Protect the /metrics endpoint by putting it behind auth. # If you want your controller-manager to expose the /metrics # endpoint w/o any authn/z, please comment the following line. @@ -37,17 +26,57 @@ patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -#- manager_webhook_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. # 'CERTMANAGER' needs to be enabled to use ca injection -#- webhookcainjection_patch.yaml +patchesStrategicMerge: +- image_tag_patch.yaml +- image_pull_patch.yaml +- manager_webhook_patch.yaml +- webhookcainjection_patch.yaml # the following config is for teaching kustomize how to do var substitution apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. resources: - ../crd - ../rbac - ../manager +- ../webhook +- ../certmanager + +# the following config is for teaching kustomize how to do var substitution +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +vars: +- fieldref: + fieldPath: metadata.namespace + name: CERTIFICATE_NAMESPACE + objref: + group: cert-manager.io + kind: Certificate + name: serving-cert + version: v1 +- fieldref: {} + name: CERTIFICATE_NAME + objref: + group: cert-manager.io + kind: Certificate + name: serving-cert + version: v1 +- fieldref: + fieldPath: metadata.namespace + name: SERVICE_NAMESPACE + objref: + kind: Service + name: webhook-service + version: v1 +- fieldref: {} + name: SERVICE_NAME + objref: + kind: Service + name: webhook-service + version: v1 diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml new file mode 100644 index 000000000..738de350b --- /dev/null +++ b/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml new file mode 100644 index 000000000..fc7a98333 --- /dev/null +++ b/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,29 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/name: mutatingwebhookconfiguration + app.kubernetes.io/instance: mutating-webhook-configuration + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: cryostat-operator + app.kubernetes.io/part-of: cryostat-operator + app.kubernetes.io/managed-by: kustomize + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/name: validatingwebhookconfiguration + app.kubernetes.io/instance: validating-webhook-configuration + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: cryostat-operator + app.kubernetes.io/part-of: cryostat-operator + app.kubernetes.io/managed-by: kustomize + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 760d31451..3c3207178 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -8,7 +8,7 @@ metadata: description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { - "apiVersion": "operator.cryostat.io/v1beta1", + "apiVersion": "operator.cryostat.io/v1beta2", "kind": "Cryostat", "metadata": { "name": "cryostat-sample" @@ -35,6 +35,399 @@ spec: apiservicedefinitions: {} customresourcedefinitions: owned: + - description: ClusterCryostat allows you to install Cryostat for multiple namespaces + or cluster-wide. It contains configuration options for controlling the Deployment + of the Cryostat application and its related components. A ClusterCryostat + or Cryostat instance must be created to instruct the operator to deploy the + Cryostat application. + displayName: Cluster Cryostat + kind: ClusterCryostat + name: clustercryostats.operator.cryostat.io + resources: + - kind: ConsoleLink + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + specDescriptors: + - description: Namespace where Cryostat should be installed. On multi-tenant + clusters, we strongly suggest installing Cryostat into its own namespace. + displayName: Install Namespace + path: installNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - description: 'List of namespaces whose workloads Cryostat should be permitted + to access and profile. Defaults to this Cryostat''s namespace. Warning: + All Cryostat users will be able to create and manage recordings for workloads + in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + displayName: Target Namespaces + path: targetNamespaces + - description: Use cert-manager to secure in-cluster communication between Cryostat + components. Requires cert-manager to be installed. + displayName: Enable cert-manager Integration + path: enableCertManager + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard + or JFR Data Source. + displayName: Minimal Deployment + path: minimal + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Override default authorization properties for Cryostat on OpenShift. + displayName: Authorization Properties + path: authProperties + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped + OAuth token. This ClusterRole should contain permissions for all Kubernetes + objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + displayName: ClusterRole Name + path: authProperties.clusterRoleName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ClusterRole + - description: Name of config map in the local namespace. + displayName: ConfigMap Name + path: authProperties.configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Filename within config map containing the resource mapping. + displayName: Filename + path: authProperties.filename + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. + displayName: Event Templates + path: eventTemplates + - description: Name of config map in the local namespace. + displayName: Config Map Name + path: eventTemplates[0].configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Options to customize the JMX target connections cache for the + Cryostat application. + displayName: JMX Connections Cache Options + path: jmxCacheOptions + - description: The maximum number of JMX connections to cache. Use `-1` for + an unlimited cache size (TTL expiration only). Defaults to `-1`. + displayName: Target Cache Size + path: jmxCacheOptions.targetCacheSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: The time to live (in seconds) for cached JMX connections. Defaults + to `10`. + displayName: Target Cache TTL + path: jmxCacheOptions.targetCacheTTL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Options to configure the Cryostat application's credentials database. + displayName: Credentials Database Options + path: jmxCredentialsDatabaseOptions + - description: Name of the secret containing the password to encrypt credentials + database. + displayName: Database Secret Name + path: jmxCredentialsDatabaseOptions.databaseSecretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: The maximum number of WebSocket client connections allowed (minimum + 1, default unlimited). + displayName: Max WebSocket Connections + path: maxWsConnections + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Options to control how the operator exposes the application outside + of the cluster, such as using an Ingress or Route. + displayName: Network Options + path: networkOptions + - description: "Specifications for how to expose the Cryostat command service, + which serves the WebSocket command channel. \n Deprecated: CommandConfig + is no longer used." + displayName: Command Config + path: networkOptions.commandConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.commandConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.commandConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.commandConfig.labels + - description: Specifications for how to expose the Cryostat service, which + serves the Cryostat application. + displayName: Core Config + path: networkOptions.coreConfig + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.coreConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.coreConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.coreConfig.labels + - description: Specifications for how to expose Cryostat's Grafana service, + which serves the Grafana dashboard. + displayName: Grafana Config + path: networkOptions.grafanaConfig + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.grafanaConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.grafanaConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.grafanaConfig.labels + - description: Options to configure the Cryostat deployments and pods metadata + displayName: Operand metadata + path: operandMetadata + - description: Options to configure the Cryostat deployments metadata + displayName: Deployments metadata + path: operandMetadata.deploymentMetadata + - description: Options to configure the Cryostat pods metadata + displayName: Pods metadata + path: operandMetadata.podMetadata + - description: Options to configure Cryostat Automated Report Analysis. + displayName: Report Options + path: reportOptions + - description: The number of report sidecar replica containers to deploy. Each + replica can service one report generation request at a time. + displayName: Replicas + path: reportOptions.replicas + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: The resources allocated to each sidecar replica. A replica with + more resources can handle larger input recordings and will process them + faster. + displayName: Resources + path: reportOptions.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Options to configure scheduling for the reports deployment + displayName: Scheduling Options + path: reportOptions.schedulingOptions + - description: Affinity rules for scheduling Cryostat pods. + displayName: Affinity + path: reportOptions.schedulingOptions.affinity + - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + displayName: Node Affinity + path: reportOptions.schedulingOptions.affinity.nodeAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:nodeAffinity + - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + displayName: Pod Affinity + path: reportOptions.schedulingOptions.affinity.podAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAffinity + - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + displayName: Pod Anti Affinity + path: reportOptions.schedulingOptions.affinity.podAntiAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity + - description: 'Label selector used to schedule a Cryostat pod to a node. See: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + displayName: Node Selector + path: reportOptions.schedulingOptions.nodeSelector + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node + - description: 'Tolerations to allow scheduling of Cryostat pods to tainted + nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + displayName: Tolerations + path: reportOptions.schedulingOptions.tolerations + - description: Options to configure the Security Contexts for the Cryostat report + generator. + displayName: Security Options + path: reportOptions.securityOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the Cryostat report generator pod. + displayName: Pod Security Context + path: reportOptions.securityOptions.podSecurityContext + - description: Security Context to apply to the Cryostat report generator container. + displayName: Reports Security Context + path: reportOptions.securityOptions.reportsSecurityContext + - description: When zero report sidecar replicas are requested, SubProcessMaxHeapSize + configures the maximum heap size of the basic subprocess report generator + in MiB. The default heap size is `200` (MiB). + displayName: Sub Process Max Heap Size + path: reportOptions.subProcessMaxHeapSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resource requirements for the Cryostat deployment. + displayName: Resources + path: resources + - description: Resource requirements for the Cryostat application. If specifying + a memory limit, at least 768MiB is recommended. + displayName: Core Resources + path: resources.coreResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the JFR Data Source container. + displayName: Data Source Resources + path: resources.dataSourceResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the Grafana container. + displayName: Grafana Resources + path: resources.grafanaResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Options to configure scheduling for the Cryostat deployment + displayName: Scheduling Options + path: schedulingOptions + - description: Affinity rules for scheduling Cryostat pods. + displayName: Affinity + path: schedulingOptions.affinity + - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + displayName: Node Affinity + path: schedulingOptions.affinity.nodeAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:nodeAffinity + - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + displayName: Pod Affinity + path: schedulingOptions.affinity.podAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAffinity + - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + displayName: Pod Anti Affinity + path: schedulingOptions.affinity.podAntiAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity + - description: 'Label selector used to schedule a Cryostat pod to a node. See: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + displayName: Node Selector + path: schedulingOptions.nodeSelector + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node + - description: 'Tolerations to allow scheduling of Cryostat pods to tainted + nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + displayName: Tolerations + path: schedulingOptions.tolerations + - description: Options to configure the Security Contexts for the Cryostat application. + displayName: Security Options + path: securityOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the Cryostat application container. + displayName: Core Security Context + path: securityOptions.coreSecurityContext + - description: Security Context to apply to the JFR Data Source container. + displayName: Data Source Security Context + path: securityOptions.dataSourceSecurityContext + - description: Security Context to apply to the Grafana container. + displayName: Grafana Security Context + path: securityOptions.grafanaSecurityContext + - description: Security Context to apply to the Cryostat pod. + displayName: Pod Security Context + path: securityOptions.podSecurityContext + - description: Options to customize the services created for the Cryostat application + and Grafana dashboard. + displayName: Service Options + path: serviceOptions + - description: Options to customize the storage for Flight Recordings and Templates. + displayName: Storage Options + path: storageOptions + - description: Configuration for an EmptyDir to be created by the operator instead + of a PVC. + displayName: Empty Dir + path: storageOptions.emptyDir + - description: When enabled, Cryostat will use EmptyDir volumes instead of a + Persistent Volume Claim. Any PVC configurations will be ignored. + displayName: Enabled + path: storageOptions.emptyDir.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Unless specified, the emptyDir volume will be mounted on the + same storage medium backing the node. Setting this field to "Memory" will + mount the emptyDir on a tmpfs (RAM-backed filesystem). + displayName: Medium + path: storageOptions.emptyDir.medium + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true + - description: The maximum memory limit for the emptyDir. Default is unbounded. + displayName: Size Limit + path: storageOptions.emptyDir.sizeLimit + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true + - description: Configuration for the Persistent Volume Claim to be created by + the operator. + displayName: PVC + path: storageOptions.pvc + - description: Spec for a Persistent Volume Claim, whose options will override + the defaults used by the operator. Unless overriden, the PVC will be created + with the default Storage Class and 500MiB of storage. Once the operator + has created the PVC, changes to this field have no effect. + displayName: Spec + path: storageOptions.pvc.spec + - description: Options to configure the Cryostat application's target discovery + mechanisms. + displayName: Target Discovery Options + path: targetDiscoveryOptions + - description: When true, the Cryostat application will disable the built-in + discovery mechanisms. Defaults to false + displayName: Disable Built-in Discovery + path: targetDiscoveryOptions.builtInDiscoveryDisabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: List of TLS certificates to trust when connecting to targets. + displayName: Trusted TLS Certificates + path: trustedCertSecrets + - description: Name of secret in the local namespace. + displayName: Secret Name + path: trustedCertSecrets[0].secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + statusDescriptors: + - description: Address of the deployed Cryostat web application. + displayName: Application URL + path: applicationUrl + x-descriptors: + - urn:alm:descriptor:org.w3:link + - description: Name of the Secret containing the generated Grafana credentials. + displayName: Grafana Secret + path: grafanaSecret + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: List of namespaces that Cryostat has been configured and authorized + to access and profile. + displayName: Target Namespaces + path: targetNamespaces + - description: Conditions of the components managed by the Cryostat Operator. + displayName: Cryostat Conditions + path: conditions + x-descriptors: + - urn:alm:descriptor:io.kubernetes.conditions + version: v1beta2 - description: ClusterCryostat allows you to install Cryostat for multiple namespaces or cluster-wide. It contains configuration options for controlling the Deployment of the Cryostat application and its related components. A ClusterCryostat @@ -394,35 +787,421 @@ spec: displayName: Target Discovery Options path: targetDiscoveryOptions - description: When true, the Cryostat application will disable the built-in - discovery mechanisms. Defaults to false. + discovery mechanisms. Defaults to false. + displayName: Disable Built-in Discovery + path: targetDiscoveryOptions.builtInDiscoveryDisabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + name jfr-jmx to look for JMX connectable targets. + displayName: Disable Built-in Port Names + path: targetDiscoveryOptions.disableBuiltInPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + number 9091 to look for JMX connectable targets. + displayName: Disable Built-in Port Numbers + path: targetDiscoveryOptions.disableBuiltInPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: List of port names that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Names + path: targetDiscoveryOptions.discoveryPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true + - description: List of port numbers that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Numbers + path: targetDiscoveryOptions.discoveryPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true + - description: List of TLS certificates to trust when connecting to targets. + displayName: Trusted TLS Certificates + path: trustedCertSecrets + - description: Name of secret in the local namespace. + displayName: Secret Name + path: trustedCertSecrets[0].secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + statusDescriptors: + - description: Address of the deployed Cryostat web application. + displayName: Application URL + path: applicationUrl + x-descriptors: + - urn:alm:descriptor:org.w3:link + - description: Name of the Secret containing the generated Grafana credentials. + displayName: Grafana Secret + path: grafanaSecret + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: List of namespaces that Cryostat has been configured and authorized + to access and profile. + displayName: Target Namespaces + path: targetNamespaces + - description: Conditions of the components managed by the Cryostat Operator. + displayName: Cryostat Conditions + path: conditions + x-descriptors: + - urn:alm:descriptor:io.kubernetes.conditions + version: v1beta1 + - description: Cryostat allows you to install Cryostat for a single namespace. + It contains configuration options for controlling the Deployment of the Cryostat + application and its related components. A ClusterCryostat or Cryostat instance + must be created to instruct the operator to deploy the Cryostat application. + displayName: Cryostat + kind: Cryostat + name: cryostats.operator.cryostat.io + resources: + - kind: ConsoleLink + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + specDescriptors: + - description: 'List of namespaces whose workloads Cryostat should be permitted + to access and profile. Defaults to this Cryostat''s namespace. Warning: + All Cryostat users will be able to create and manage recordings for workloads + in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + displayName: Target Namespaces + path: targetNamespaces + - description: Use cert-manager to secure in-cluster communication between Cryostat + components. Requires cert-manager to be installed. + displayName: Enable cert-manager Integration + path: enableCertManager + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard + or JFR Data Source. + displayName: Minimal Deployment + path: minimal + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Override default authorization properties for Cryostat on OpenShift. + displayName: Authorization Properties + path: authProperties + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped + OAuth token. This ClusterRole should contain permissions for all Kubernetes + objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + displayName: ClusterRole Name + path: authProperties.clusterRoleName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ClusterRole + - description: Name of config map in the local namespace. + displayName: ConfigMap Name + path: authProperties.configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Filename within config map containing the resource mapping. + displayName: Filename + path: authProperties.filename + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. + displayName: Event Templates + path: eventTemplates + - description: Name of config map in the local namespace. + displayName: Config Map Name + path: eventTemplates[0].configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Options to customize the JMX target connections cache for the + Cryostat application. + displayName: JMX Connections Cache Options + path: jmxCacheOptions + - description: The maximum number of JMX connections to cache. Use `-1` for + an unlimited cache size (TTL expiration only). Defaults to `-1`. + displayName: Target Cache Size + path: jmxCacheOptions.targetCacheSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: The time to live (in seconds) for cached JMX connections. Defaults + to `10`. + displayName: Target Cache TTL + path: jmxCacheOptions.targetCacheTTL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Options to configure the Cryostat application's credentials database. + displayName: Credentials Database Options + path: jmxCredentialsDatabaseOptions + - description: Name of the secret containing the password to encrypt credentials + database. + displayName: Database Secret Name + path: jmxCredentialsDatabaseOptions.databaseSecretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: The maximum number of WebSocket client connections allowed (minimum + 1, default unlimited). + displayName: Max WebSocket Connections + path: maxWsConnections + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Options to control how the operator exposes the application outside + of the cluster, such as using an Ingress or Route. + displayName: Network Options + path: networkOptions + - description: "Specifications for how to expose the Cryostat command service, + which serves the WebSocket command channel. \n Deprecated: CommandConfig + is no longer used." + displayName: Command Config + path: networkOptions.commandConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.commandConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.commandConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.commandConfig.labels + - description: Specifications for how to expose the Cryostat service, which + serves the Cryostat application. + displayName: Core Config + path: networkOptions.coreConfig + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.coreConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.coreConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.coreConfig.labels + - description: Specifications for how to expose Cryostat's Grafana service, + which serves the Grafana dashboard. + displayName: Grafana Config + path: networkOptions.grafanaConfig + - description: Annotations to add to the Ingress or Route during its creation. + displayName: Annotations + path: networkOptions.grafanaConfig.annotations + - description: Configuration for an Ingress object. Currently subpaths are not + supported, so unique hosts must be specified (if a single external IP is + being used) to differentiate between ingresses/services. + displayName: Ingress Spec + path: networkOptions.grafanaConfig.ingressSpec + - description: Labels to add to the Ingress or Route during its creation. The + label with key "app" is reserved for use by the operator. + displayName: Labels + path: networkOptions.grafanaConfig.labels + - description: Options to configure the Cryostat deployments and pods metadata + displayName: Operand metadata + path: operandMetadata + - description: Options to configure the Cryostat deployments metadata + displayName: Deployments metadata + path: operandMetadata.deploymentMetadata + - description: Options to configure the Cryostat pods metadata + displayName: Pods metadata + path: operandMetadata.podMetadata + - description: Options to configure Cryostat Automated Report Analysis. + displayName: Report Options + path: reportOptions + - description: The number of report sidecar replica containers to deploy. Each + replica can service one report generation request at a time. + displayName: Replicas + path: reportOptions.replicas + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: The resources allocated to each sidecar replica. A replica with + more resources can handle larger input recordings and will process them + faster. + displayName: Resources + path: reportOptions.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Options to configure scheduling for the reports deployment + displayName: Scheduling Options + path: reportOptions.schedulingOptions + - description: Affinity rules for scheduling Cryostat pods. + displayName: Affinity + path: reportOptions.schedulingOptions.affinity + - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + displayName: Node Affinity + path: reportOptions.schedulingOptions.affinity.nodeAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:nodeAffinity + - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + displayName: Pod Affinity + path: reportOptions.schedulingOptions.affinity.podAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAffinity + - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + displayName: Pod Anti Affinity + path: reportOptions.schedulingOptions.affinity.podAntiAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity + - description: 'Label selector used to schedule a Cryostat pod to a node. See: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + displayName: Node Selector + path: reportOptions.schedulingOptions.nodeSelector + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node + - description: 'Tolerations to allow scheduling of Cryostat pods to tainted + nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + displayName: Tolerations + path: reportOptions.schedulingOptions.tolerations + - description: Options to configure the Security Contexts for the Cryostat report + generator. + displayName: Security Options + path: reportOptions.securityOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the Cryostat report generator pod. + displayName: Pod Security Context + path: reportOptions.securityOptions.podSecurityContext + - description: Security Context to apply to the Cryostat report generator container. + displayName: Reports Security Context + path: reportOptions.securityOptions.reportsSecurityContext + - description: When zero report sidecar replicas are requested, SubProcessMaxHeapSize + configures the maximum heap size of the basic subprocess report generator + in MiB. The default heap size is `200` (MiB). + displayName: Sub Process Max Heap Size + path: reportOptions.subProcessMaxHeapSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resource requirements for the Cryostat deployment. + displayName: Resources + path: resources + - description: Resource requirements for the Cryostat application. If specifying + a memory limit, at least 768MiB is recommended. + displayName: Core Resources + path: resources.coreResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the JFR Data Source container. + displayName: Data Source Resources + path: resources.dataSourceResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the Grafana container. + displayName: Grafana Resources + path: resources.grafanaResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Options to configure scheduling for the Cryostat deployment + displayName: Scheduling Options + path: schedulingOptions + - description: Affinity rules for scheduling Cryostat pods. + displayName: Affinity + path: schedulingOptions.affinity + - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' + displayName: Node Affinity + path: schedulingOptions.affinity.nodeAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:nodeAffinity + - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' + displayName: Pod Affinity + path: schedulingOptions.affinity.podAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAffinity + - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' + displayName: Pod Anti Affinity + path: schedulingOptions.affinity.podAntiAffinity + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity + - description: 'Label selector used to schedule a Cryostat pod to a node. See: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + displayName: Node Selector + path: schedulingOptions.nodeSelector + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node + - description: 'Tolerations to allow scheduling of Cryostat pods to tainted + nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + displayName: Tolerations + path: schedulingOptions.tolerations + - description: Options to configure the Security Contexts for the Cryostat application. + displayName: Security Options + path: securityOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the Cryostat application container. + displayName: Core Security Context + path: securityOptions.coreSecurityContext + - description: Security Context to apply to the JFR Data Source container. + displayName: Data Source Security Context + path: securityOptions.dataSourceSecurityContext + - description: Security Context to apply to the Grafana container. + displayName: Grafana Security Context + path: securityOptions.grafanaSecurityContext + - description: Security Context to apply to the Cryostat pod. + displayName: Pod Security Context + path: securityOptions.podSecurityContext + - description: Options to customize the services created for the Cryostat application + and Grafana dashboard. + displayName: Service Options + path: serviceOptions + - description: Options to customize the storage for Flight Recordings and Templates. + displayName: Storage Options + path: storageOptions + - description: Configuration for an EmptyDir to be created by the operator instead + of a PVC. + displayName: Empty Dir + path: storageOptions.emptyDir + - description: When enabled, Cryostat will use EmptyDir volumes instead of a + Persistent Volume Claim. Any PVC configurations will be ignored. + displayName: Enabled + path: storageOptions.emptyDir.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Unless specified, the emptyDir volume will be mounted on the + same storage medium backing the node. Setting this field to "Memory" will + mount the emptyDir on a tmpfs (RAM-backed filesystem). + displayName: Medium + path: storageOptions.emptyDir.medium + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true + - description: The maximum memory limit for the emptyDir. Default is unbounded. + displayName: Size Limit + path: storageOptions.emptyDir.sizeLimit + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true + - description: Configuration for the Persistent Volume Claim to be created by + the operator. + displayName: PVC + path: storageOptions.pvc + - description: Spec for a Persistent Volume Claim, whose options will override + the defaults used by the operator. Unless overriden, the PVC will be created + with the default Storage Class and 500MiB of storage. Once the operator + has created the PVC, changes to this field have no effect. + displayName: Spec + path: storageOptions.pvc.spec + - description: Options to configure the Cryostat application's target discovery + mechanisms. + displayName: Target Discovery Options + path: targetDiscoveryOptions + - description: When true, the Cryostat application will disable the built-in + discovery mechanisms. Defaults to false displayName: Disable Built-in Discovery path: targetDiscoveryOptions.builtInDiscoveryDisabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - name jfr-jmx to look for JMX connectable targets. - displayName: Disable Built-in Port Names - path: targetDiscoveryOptions.disableBuiltInPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - number 9091 to look for JMX connectable targets. - displayName: Disable Built-in Port Numbers - path: targetDiscoveryOptions.disableBuiltInPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: List of port names that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Names - path: targetDiscoveryOptions.discoveryPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true - - description: List of port numbers that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Numbers - path: targetDiscoveryOptions.discoveryPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - description: List of TLS certificates to trust when connecting to targets. displayName: Trusted TLS Certificates path: trustedCertSecrets @@ -451,7 +1230,7 @@ spec: path: conditions x-descriptors: - urn:alm:descriptor:io.kubernetes.conditions - version: v1beta1 + version: v1beta2 - description: Cryostat allows you to install Cryostat for a single namespace. It contains configuration options for controlling the Deployment of the Cryostat application and its related components. A ClusterCryostat or Cryostat instance diff --git a/config/manifests/targetNamespaces_patch.yaml b/config/manifests/targetNamespaces_patch.yaml index b669249d4..640710b6a 100644 --- a/config/manifests/targetNamespaces_patch.yaml +++ b/config/manifests/targetNamespaces_patch.yaml @@ -15,3 +15,35 @@ path: targetNamespaces[0] x-descriptors: - "urn:alm:descriptor:io.kubernetes:Namespace" +- op: add + path: /spec/customresourcedefinitions/owned/1/specDescriptors/- + value: + description: "A namespace whose workloads Cryostat should be able to connect and record" + displayName: "Target Namespace" + path: targetNamespaces[0] + x-descriptors: + - "urn:alm:descriptor:io.kubernetes:Namespace" +- op: add + path: /spec/customresourcedefinitions/owned/1/statusDescriptors/- + value: + description: "A namespace whose workloads Cryostat should be able to connect and record" + displayName: "Target Namespace" + path: targetNamespaces[0] + x-descriptors: + - "urn:alm:descriptor:io.kubernetes:Namespace" +- op: add + path: /spec/customresourcedefinitions/owned/2/specDescriptors/- + value: + description: "A namespace whose workloads Cryostat should be able to connect and record" + displayName: "Target Namespace" + path: targetNamespaces[0] + x-descriptors: + - "urn:alm:descriptor:io.kubernetes:Namespace" +- op: add + path: /spec/customresourcedefinitions/owned/2/statusDescriptors/- + value: + description: "A namespace whose workloads Cryostat should be able to connect and record" + displayName: "Target Namespace" + path: targetNamespaces[0] + x-descriptors: + - "urn:alm:descriptor:io.kubernetes:Namespace" diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 534e4c3c2..0ca288fce 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -76,6 +76,12 @@ rules: - selfsubjectaccessreviews verbs: - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create - apiGroups: - cert-manager.io resources: diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 3e9e735a7..08a69bad7 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -2,4 +2,6 @@ resources: - operator_v1beta1_cryostat.yaml - operator_v1beta1_clustercryostat.yaml +- operator_v1beta2_cryostat.yaml +- operator_v1beta2_clustercryostat.yaml # +kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/operator_v1beta2_clustercryostat.yaml b/config/samples/operator_v1beta2_clustercryostat.yaml new file mode 100644 index 000000000..b4b656843 --- /dev/null +++ b/config/samples/operator_v1beta2_clustercryostat.yaml @@ -0,0 +1,16 @@ +apiVersion: operator.cryostat.io/v1beta2 +kind: ClusterCryostat +metadata: + name: clustercryostat-sample +spec: + minimal: false + enableCertManager: true + trustedCertSecrets: [] + eventTemplates: [] + storageOptions: + pvc: + labels: {} + annotations: {} + spec: {} + reportOptions: + replicas: 0 diff --git a/config/samples/operator_v1beta2_cryostat.yaml b/config/samples/operator_v1beta2_cryostat.yaml new file mode 100644 index 000000000..69cc3b956 --- /dev/null +++ b/config/samples/operator_v1beta2_cryostat.yaml @@ -0,0 +1,16 @@ +apiVersion: operator.cryostat.io/v1beta2 +kind: Cryostat +metadata: + name: cryostat-sample +spec: + minimal: false + enableCertManager: true + trustedCertSecrets: [] + eventTemplates: [] + storageOptions: + pvc: + labels: {} + annotations: {} + spec: {} + reportOptions: + replicas: 0 diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml new file mode 100644 index 000000000..9cf26134e --- /dev/null +++ b/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml new file mode 100644 index 000000000..25e21e3c9 --- /dev/null +++ b/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true +- kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: +- path: metadata/annotations diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml new file mode 100644 index 000000000..39f016e00 --- /dev/null +++ b/config/webhook/manifests.yaml @@ -0,0 +1,54 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-operator-cryostat-io-v1beta2-cryostat + failurePolicy: Fail + name: mcryostat.kb.io + rules: + - apiGroups: + - operator.cryostat.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cryostats + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-operator-cryostat-io-v1beta2-cryostat + failurePolicy: Fail + name: vcryostat.kb.io + rules: + - apiGroups: + - operator.cryostat.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cryostats + sideEffects: None diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml new file mode 100644 index 000000000..451723750 --- /dev/null +++ b/config/webhook/service.yaml @@ -0,0 +1,20 @@ + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: service + app.kubernetes.io/instance: webhook-service + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: cryostat-operator + app.kubernetes.io/part-of: cryostat-operator + app.kubernetes.io/managed-by: kustomize + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/internal/controllers/certmanager.go b/internal/controllers/certmanager.go index ae9fa875c..45b305b7a 100644 --- a/internal/controllers/certmanager.go +++ b/internal/controllers/certmanager.go @@ -56,14 +56,14 @@ func (r *Reconciler) setupTLS(ctx context.Context, cr *model.CryostatInstance) ( } // Create CA certificate for Cryostat using the self-signed issuer - caCert := resources.NewCryostatCACert(cr) + caCert := resources.NewCryostatCACert(r.gvk, cr) err = r.createOrUpdateCertificate(ctx, caCert, cr.Object) if err != nil { return nil, err } // Create CA issuer using the CA cert just created - err = r.createOrUpdateIssuer(ctx, resources.NewCryostatCAIssuer(cr), cr.Object) + err = r.createOrUpdateIssuer(ctx, resources.NewCryostatCAIssuer(r.gvk, cr), cr.Object) if err != nil { return nil, err } @@ -136,13 +136,7 @@ func (r *Reconciler) setupTLS(ctx context.Context, cr *model.CryostatInstance) ( }, Type: corev1.SecretTypeOpaque, } - err = r.createOrUpdateSecret(ctx, namespaceSecret, cr.Object, func() error { - if namespaceSecret.Data == nil { - namespaceSecret.Data = map[string][]byte{} - } - namespaceSecret.Data[corev1.TLSCertKey] = secret.Data[corev1.TLSCertKey] - return nil - }) + err = r.createOrUpdateCertSecret(ctx, namespaceSecret, secret.Data[corev1.TLSCertKey]) if err != nil { return nil, err } @@ -174,7 +168,7 @@ func (r *Reconciler) setupTLS(ctx context.Context, cr *model.CryostatInstance) ( } func (r *Reconciler) finalizeTLS(ctx context.Context, cr *model.CryostatInstance) error { - caCert := resources.NewCryostatCACert(cr) + caCert := resources.NewCryostatCACert(r.gvk, cr) for _, ns := range cr.TargetNamespaces { if ns != cr.InstallNamespace { namespaceSecret := &corev1.Secret{ @@ -307,6 +301,21 @@ func (r *Reconciler) createOrUpdateKeystoreSecret(ctx context.Context, secret *c return nil } +func (r *Reconciler) createOrUpdateCertSecret(ctx context.Context, secret *corev1.Secret, cert []byte) error { + op, err := controllerutil.CreateOrUpdate(ctx, r.Client, secret, func() error { + if secret.Data == nil { + secret.Data = map[string][]byte{} + } + secret.Data[corev1.TLSCertKey] = cert + return nil + }) + if err != nil { + return err + } + r.Log.Info(fmt.Sprintf("Secret %s", op), "name", secret.Name, "namespace", secret.Namespace) + return nil +} + func (r *Reconciler) deleteCert(ctx context.Context, cert *certv1.Certificate) error { err := r.Client.Delete(ctx, cert) if err != nil && !kerrors.IsNotFound(err) { diff --git a/internal/controllers/clustercryostat_controller.go b/internal/controllers/clustercryostat_controller.go index a79da08ee..a33b23a62 100644 --- a/internal/controllers/clustercryostat_controller.go +++ b/internal/controllers/clustercryostat_controller.go @@ -19,7 +19,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" "github.com/cryostatio/cryostat-operator/internal/controllers/model" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -39,7 +39,7 @@ type ClusterCryostatReconciler struct { } func NewClusterCryostatReconciler(config *ReconcilerConfig) (*ClusterCryostatReconciler, error) { - delegate, err := newReconciler(config, &operatorv1beta1.ClusterCryostat{}, false) + delegate, err := newReconciler(config, &operatorv1beta2.ClusterCryostat{}, false) if err != nil { return nil, err } @@ -76,7 +76,7 @@ func (r *ClusterCryostatReconciler) Reconcile(ctx context.Context, request ctrl. reqLogger.Info("Reconciling ClusterCryostat") // Fetch the Cryostat instance - cr := &operatorv1beta1.ClusterCryostat{} + cr := &operatorv1beta2.ClusterCryostat{} err := r.Client.Get(ctx, request.NamespacedName, cr) if err != nil { if kerrors.IsNotFound(err) { diff --git a/internal/controllers/clustercryostat_controller_test.go b/internal/controllers/clustercryostat_controller_test.go index a5227600a..249d55e87 100644 --- a/internal/controllers/clustercryostat_controller_test.go +++ b/internal/controllers/clustercryostat_controller_test.go @@ -15,14 +15,8 @@ package controllers_test import ( - "context" - "github.com/cryostatio/cryostat-operator/internal/controllers" . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" ) var _ = Describe("ClusterCryostatController", func() { @@ -32,108 +26,8 @@ var _ = Describe("ClusterCryostatController", func() { } c.commonTests() - - Context("reconciling a multi-namespace request", func() { - var t *cryostatTestInput - targetNamespaces := []string{"multi-test-one", "multi-test-two"} - - BeforeEach(func() { - t = c.commonBeforeEach() - t.TargetNamespaces = targetNamespaces - t.objs = append(t.objs, t.NewCryostat().Object) - // Create Namespaces - saveNS := t.Namespace - for _, ns := range targetNamespaces { - t.Namespace = ns - t.objs = append(t.objs, t.NewNamespace()) - } - t.Namespace = saveNS - }) - - JustBeforeEach(func() { - c.commonJustBeforeEach(t) - t.reconcileCryostatFully() - }) - - JustAfterEach(func() { - c.commonJustAfterEach(t) - }) - - It("should create the expected main deployment", func() { - t.expectMainDeployment() - }) - - It("should create CA Cert secret in each namespace", func() { - t.expectCertificates() - }) - - It("should create RBAC in each namespace", func() { - t.expectRBAC() - }) - - It("should update the target namespaces in Status", func() { - t.expectTargetNamespaces() - }) - - Context("with removed target namespaces", func() { - BeforeEach(func() { - t = c.commonBeforeEach() - // Begin with RBAC set up for two namespaces, - // and remove the second namespace from the spec - t.TargetNamespaces = targetNamespaces[:1] - cr := t.NewCryostat() - *cr.TargetNamespaceStatus = targetNamespaces - t.objs = append(t.objs, cr.Object, - t.NewRoleBinding(targetNamespaces[0]), - t.NewRoleBinding(targetNamespaces[1]), - t.NewCACertSecret(targetNamespaces[0]), - t.NewCACertSecret(targetNamespaces[1])) - }) - It("should create the expected main deployment", func() { - t.expectMainDeployment() - }) - It("leave RBAC for the first namespace", func() { - t.expectRBAC() - }) - It("should remove RBAC from the second namespace", func() { - binding := t.NewRoleBinding(targetNamespaces[1]) - err := t.Client.Get(context.Background(), types.NamespacedName{Name: binding.Name, Namespace: binding.Namespace}, binding) - Expect(err).ToNot(BeNil()) - Expect(errors.IsNotFound(err)).To(BeTrue()) - }) - It("leave CA Cert secret for the first namespace", func() { - t.expectCertificates() - }) - It("should remove CA Cert secret from the second namespace", func() { - caCert := t.NewCACert() - secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: caCert.Name, Namespace: targetNamespaces[1]}, secret) - Expect(err).ToNot(BeNil()) - Expect(errors.IsNotFound(err)).To(BeTrue()) - }) - It("should update the target namespaces in Status", func() { - t.expectTargetNamespaces() - }) - }) - - Context("with no target namespaces", func() { - BeforeEach(func() { - t = c.commonBeforeEach() - t.TargetNamespaces = nil - t.objs = append(t.objs, t.NewCryostat().Object) - }) - It("should update the target namespaces in Status", func() { - t.expectTargetNamespaces() - }) - }) - }) }) -func (t *cryostatTestInput) expectTargetNamespaces() { - cr := t.getCryostatInstance() - Expect(*cr.TargetNamespaceStatus).To(ConsistOf(t.TargetNamespaces)) -} - func newClusterCryostatController(config *controllers.ReconcilerConfig) (controllers.CommonReconciler, error) { return controllers.NewClusterCryostatReconciler(config) } diff --git a/internal/controllers/common/common_utils.go b/internal/controllers/common/common_utils.go index 454d349f3..6258a4bfd 100644 --- a/internal/controllers/common/common_utils.go +++ b/internal/controllers/common/common_utils.go @@ -66,10 +66,21 @@ func (o *DefaultOSUtils) GenPasswd(length int) string { // ClusterUniqueName returns a name for cluster-scoped objects that is // uniquely identified by a namespace and name. func ClusterUniqueName(gvk *schema.GroupVersionKind, name string, namespace string) string { + return ClusterUniqueNameWithPrefix(gvk, "", name, namespace) +} + +// ClusterUniqueName returns a name for cluster-scoped objects that is +// uniquely identified by a namespace and name. Appends the prefix to the +// provided Kind. +func ClusterUniqueNameWithPrefix(gvk *schema.GroupVersionKind, prefix string, name string, namespace string) string { + prefixWithKind := strings.ToLower(gvk.Kind) + if len(prefix) > 0 { + prefixWithKind += "-" + prefix + } // Use the SHA256 checksum of the namespaced name as a suffix nn := types.NamespacedName{Namespace: namespace, Name: name} suffix := fmt.Sprintf("%x", sha256.Sum256([]byte(nn.String()))) - return strings.ToLower(gvk.Kind) + "-" + suffix + return prefixWithKind + "-" + suffix } // MergeLabelsAndAnnotations copies labels and annotations from a source diff --git a/internal/controllers/common/resource_definitions/certificates.go b/internal/controllers/common/resource_definitions/certificates.go index 3d3dd0769..33b8ae183 100644 --- a/internal/controllers/common/resource_definitions/certificates.go +++ b/internal/controllers/common/resource_definitions/certificates.go @@ -19,9 +19,11 @@ 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" ) func NewSelfSignedIssuer(cr *model.CryostatInstance) *certv1.Issuer { @@ -38,7 +40,7 @@ func NewSelfSignedIssuer(cr *model.CryostatInstance) *certv1.Issuer { } } -func NewCryostatCAIssuer(cr *model.CryostatInstance) *certv1.Issuer { +func NewCryostatCAIssuer(gvk *schema.GroupVersionKind, cr *model.CryostatInstance) *certv1.Issuer { return &certv1.Issuer{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name + "-ca", @@ -47,14 +49,14 @@ func NewCryostatCAIssuer(cr *model.CryostatInstance) *certv1.Issuer { Spec: certv1.IssuerSpec{ IssuerConfig: certv1.IssuerConfig{ CA: &certv1.CAIssuer{ - SecretName: cr.Name + "-ca", + SecretName: NewCryostatCACert(gvk, cr).Spec.SecretName, }, }, }, } } -func NewCryostatCACert(cr *model.CryostatInstance) *certv1.Certificate { +func NewCryostatCACert(gvk *schema.GroupVersionKind, cr *model.CryostatInstance) *certv1.Certificate { return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name + "-ca", @@ -62,7 +64,7 @@ func NewCryostatCACert(cr *model.CryostatInstance) *certv1.Certificate { }, Spec: certv1.CertificateSpec{ CommonName: fmt.Sprintf("ca.%s.cert-manager", cr.Name), - SecretName: cr.Name + "-ca", + SecretName: common.ClusterUniqueNameWithPrefix(gvk, "ca", cr.Name, cr.InstallNamespace), IssuerRef: certMeta.ObjectReference{ Name: cr.Name + "-self-signed", }, diff --git a/internal/controllers/cryostat_controller.go b/internal/controllers/cryostat_controller.go index 554f16e2d..97125870b 100644 --- a/internal/controllers/cryostat_controller.go +++ b/internal/controllers/cryostat_controller.go @@ -19,7 +19,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" "github.com/cryostatio/cryostat-operator/internal/controllers/model" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -36,7 +36,7 @@ type CryostatReconciler struct { } func NewCryostatReconciler(config *ReconcilerConfig) (*CryostatReconciler, error) { - delegate, err := newReconciler(config, &operatorv1beta1.Cryostat{}, true) + delegate, err := newReconciler(config, &operatorv1beta2.Cryostat{}, true) if err != nil { return nil, err } @@ -57,7 +57,7 @@ func (r *CryostatReconciler) Reconcile(ctx context.Context, request ctrl.Request reqLogger.Info("Reconciling Cryostat") // Fetch the Cryostat instance - cr := &operatorv1beta1.Cryostat{} + cr := &operatorv1beta2.Cryostat{} err := r.Client.Get(ctx, request.NamespacedName, cr) if err != nil { if kerrors.IsNotFound(err) { diff --git a/internal/controllers/ingresses.go b/internal/controllers/ingresses.go index cadb91562..33cde225a 100644 --- a/internal/controllers/ingresses.go +++ b/internal/controllers/ingresses.go @@ -19,7 +19,7 @@ import ( "fmt" "net/url" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" common "github.com/cryostatio/cryostat-operator/internal/controllers/common" "github.com/cryostatio/cryostat-operator/internal/controllers/common/resource_definitions" "github.com/cryostatio/cryostat-operator/internal/controllers/model" @@ -77,7 +77,7 @@ func (r *Reconciler) reconcileGrafanaIngress(ctx context.Context, cr *model.Cryo } func (r *Reconciler) reconcileIngress(ctx context.Context, ingress *netv1.Ingress, cr *model.CryostatInstance, - config *operatorv1beta1.NetworkConfiguration) (*url.URL, error) { + config *operatorv1beta2.NetworkConfiguration) (*url.URL, error) { ingress, err := r.createOrUpdateIngress(ctx, ingress, cr.Object, config) if err != nil { return nil, err @@ -99,7 +99,7 @@ func (r *Reconciler) reconcileIngress(ctx context.Context, ingress *netv1.Ingres } func (r *Reconciler) createOrUpdateIngress(ctx context.Context, ingress *netv1.Ingress, owner metav1.Object, - config *operatorv1beta1.NetworkConfiguration) (*netv1.Ingress, error) { + config *operatorv1beta2.NetworkConfiguration) (*netv1.Ingress, error) { op, err := controllerutil.CreateOrUpdate(ctx, r.Client, ingress, func() error { // Set labels and annotations from CR common.MergeLabelsAndAnnotations(&ingress.ObjectMeta, config.Labels, config.Annotations) @@ -119,31 +119,31 @@ func (r *Reconciler) createOrUpdateIngress(ctx context.Context, ingress *netv1.I return ingress, nil } -func configureCoreIngress(cr *model.CryostatInstance) *operatorv1beta1.NetworkConfiguration { - var config *operatorv1beta1.NetworkConfiguration +func configureCoreIngress(cr *model.CryostatInstance) *operatorv1beta2.NetworkConfiguration { + var config *operatorv1beta2.NetworkConfiguration if cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.CoreConfig == nil { - config = &operatorv1beta1.NetworkConfiguration{} + config = &operatorv1beta2.NetworkConfiguration{} } else { config = cr.Spec.NetworkOptions.CoreConfig } - configureRoute(config, cr.Name, "cryostat") + configureIngress(config, cr.Name, "cryostat") return config } -func configureGrafanaIngress(cr *model.CryostatInstance) *operatorv1beta1.NetworkConfiguration { - var config *operatorv1beta1.NetworkConfiguration +func configureGrafanaIngress(cr *model.CryostatInstance) *operatorv1beta2.NetworkConfiguration { + var config *operatorv1beta2.NetworkConfiguration if cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.GrafanaConfig == nil { - config = &operatorv1beta1.NetworkConfiguration{} + config = &operatorv1beta2.NetworkConfiguration{} } else { config = cr.Spec.NetworkOptions.GrafanaConfig } - configureRoute(config, cr.Name, "cryostat") + configureIngress(config, cr.Name, "cryostat") return config } -func configureIngress(config *operatorv1beta1.NetworkConfiguration, appLabel string, componentLabel string) { +func configureIngress(config *operatorv1beta2.NetworkConfiguration, appLabel string, componentLabel string) { if config.Labels == nil { config.Labels = map[string]string{} } diff --git a/internal/controllers/model/instance.go b/internal/controllers/model/instance.go index 32dce7a62..04bcf50cf 100644 --- a/internal/controllers/model/instance.go +++ b/internal/controllers/model/instance.go @@ -15,7 +15,7 @@ package model import ( - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -35,21 +35,20 @@ type CryostatInstance struct { // For ClusterCryostat, this is a reference to status.TargetNamespaces. TargetNamespaceStatus *[]string // Reference to the common Spec properties to both CRD types. - Spec *operatorv1beta1.CryostatSpec + Spec *operatorv1beta2.CryostatSpec // Reference to the common Status properties to both CRD types. - Status *operatorv1beta1.CryostatStatus + Status *operatorv1beta2.CryostatStatus // The actual CR instance as a generic Kubernetes object. Object client.Object } // FromCryostat creates a CryostatInstance from a Cryostat CR -func FromCryostat(cr *operatorv1beta1.Cryostat) *CryostatInstance { - targetNS := []string{cr.Namespace} +func FromCryostat(cr *operatorv1beta2.Cryostat) *CryostatInstance { return &CryostatInstance{ Name: cr.Name, InstallNamespace: cr.Namespace, - TargetNamespaces: targetNS, - TargetNamespaceStatus: &targetNS, + TargetNamespaces: cr.Spec.TargetNamespaces, + TargetNamespaceStatus: &cr.Status.TargetNamespaces, Spec: &cr.Spec, Status: &cr.Status, @@ -59,7 +58,8 @@ func FromCryostat(cr *operatorv1beta1.Cryostat) *CryostatInstance { } // FromClusterCryostat creates a CryostatInstance from a ClusterCryostat CR -func FromClusterCryostat(cr *operatorv1beta1.ClusterCryostat) *CryostatInstance { +func FromClusterCryostat(cr *operatorv1beta2.ClusterCryostat) *CryostatInstance { + // TODO Remove this CRD return &CryostatInstance{ Name: cr.Name, InstallNamespace: cr.Spec.InstallNamespace, diff --git a/internal/controllers/pvc.go b/internal/controllers/pvc.go index 33ee2538b..96c3cb1b9 100644 --- a/internal/controllers/pvc.go +++ b/internal/controllers/pvc.go @@ -18,7 +18,7 @@ import ( "context" "fmt" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" "github.com/cryostatio/cryostat-operator/internal/controllers/common" "github.com/cryostatio/cryostat-operator/internal/controllers/model" corev1 "k8s.io/api/core/v1" @@ -62,7 +62,7 @@ func (r *Reconciler) reconcilePVC(ctx context.Context, cr *model.CryostatInstanc } func (r *Reconciler) createOrUpdatePVC(ctx context.Context, pvc *corev1.PersistentVolumeClaim, - owner metav1.Object, config *operatorv1beta1.PersistentVolumeClaimConfig) error { + owner metav1.Object, config *operatorv1beta2.PersistentVolumeClaimConfig) error { op, err := controllerutil.CreateOrUpdate(ctx, r.Client, pvc, func() error { // Merge labels and annotations to prevent overriding any set by Kubernetes common.MergeLabelsAndAnnotations(&pvc.ObjectMeta, config.Labels, config.Annotations) @@ -94,11 +94,11 @@ func (r *Reconciler) createOrUpdatePVC(ctx context.Context, pvc *corev1.Persiste return nil } -func configurePVC(cr *model.CryostatInstance) *operatorv1beta1.PersistentVolumeClaimConfig { +func configurePVC(cr *model.CryostatInstance) *operatorv1beta2.PersistentVolumeClaimConfig { // Check for PVC config within CR - var config *operatorv1beta1.PersistentVolumeClaimConfig + var config *operatorv1beta2.PersistentVolumeClaimConfig if cr.Spec.StorageOptions == nil || cr.Spec.StorageOptions.PVC == nil { - config = &operatorv1beta1.PersistentVolumeClaimConfig{} + config = &operatorv1beta2.PersistentVolumeClaimConfig{} } else { config = cr.Spec.StorageOptions.PVC.DeepCopy() } diff --git a/internal/controllers/rbac.go b/internal/controllers/rbac.go index 92ab4eab6..cd4cb4a6b 100644 --- a/internal/controllers/rbac.go +++ b/internal/controllers/rbac.go @@ -53,7 +53,11 @@ func (r *Reconciler) reconcileRBAC(ctx context.Context, cr *model.CryostatInstan } func (r *Reconciler) finalizeRBAC(ctx context.Context, cr *model.CryostatInstance) error { - return r.deleteClusterRoleBinding(ctx, r.newClusterRoleBinding(cr)) + err := r.deleteClusterRoleBinding(ctx, r.newClusterRoleBinding(cr)) + if err != nil { + return err + } + return r.finalizeRoleBindings(ctx, cr) } func newServiceAccount(cr *model.CryostatInstance) *corev1.ServiceAccount { @@ -106,10 +110,10 @@ func (r *Reconciler) reconcileRole(ctx context.Context, cr *model.CryostatInstan return r.cleanUpRole(ctx, cr, newRole(cr)) } -func newRoleBinding(cr *model.CryostatInstance, namespace string) *rbacv1.RoleBinding { +func (r *Reconciler) newRoleBinding(cr *model.CryostatInstance, namespace string) *rbacv1.RoleBinding { return &rbacv1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name, + Name: common.ClusterUniqueName(r.gvk, cr.Name, cr.InstallNamespace), Namespace: namespace, }, } @@ -127,7 +131,7 @@ func (r *Reconciler) reconcileRoleBinding(ctx context.Context, cr *model.Cryosta // Create a RoleBinding in each target namespace for _, ns := range cr.TargetNamespaces { - binding := newRoleBinding(cr, ns) + binding := r.newRoleBinding(cr, ns) roleRef := &rbacv1.RoleRef{ APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", @@ -140,7 +144,7 @@ func (r *Reconciler) reconcileRoleBinding(ctx context.Context, cr *model.Cryosta } // Delete any RoleBindings in target namespaces that are no longer requested for _, ns := range toDelete(cr) { - binding := newRoleBinding(cr, ns) + binding := r.newRoleBinding(cr, ns) err := r.deleteRoleBinding(ctx, binding) if err != nil { return err @@ -150,6 +154,17 @@ func (r *Reconciler) reconcileRoleBinding(ctx context.Context, cr *model.Cryosta return nil } +func (r *Reconciler) finalizeRoleBindings(ctx context.Context, cr *model.CryostatInstance) error { + for _, ns := range cr.TargetNamespaces { + binding := r.newRoleBinding(cr, ns) + err := r.deleteRoleBinding(ctx, binding) + if err != nil { + return err + } + } + return nil +} + func (r *Reconciler) newClusterRoleBinding(cr *model.CryostatInstance) *rbacv1.ClusterRoleBinding { return &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ @@ -237,11 +252,6 @@ func (r *Reconciler) createOrUpdateRoleBinding(ctx context.Context, binding *rba return err } binding.RoleRef = *roleRef - - // Set the Cryostat CR as controller - if err := controllerutil.SetControllerReference(owner, binding, r.Scheme); err != nil { - return err - } return nil }) if err != nil { diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 4241d0ae4..ec636d386 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -45,7 +45,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" "github.com/cryostatio/cryostat-operator/internal/controllers" "github.com/cryostatio/cryostat-operator/internal/controllers/model" "github.com/cryostatio/cryostat-operator/internal/test" @@ -170,7 +170,7 @@ func expectSuccessful(t **cryostatTestInput) { (*t).expectStatusGrafanaSecretName((*t).NewGrafanaSecret().Name) }) It("should set TLSSetupComplete condition", func() { - (*t).checkConditionPresent(operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, + (*t).checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "AllCertificatesReady") }) Context("deployment is progressing", func() { @@ -178,22 +178,22 @@ func expectSuccessful(t **cryostatTestInput) { (*t).makeDeploymentProgress((*t).Name) }) It("should update conditions", func() { - (*t).checkConditionPresent(operatorv1beta1.ConditionTypeMainDeploymentAvailable, metav1.ConditionFalse, + (*t).checkConditionPresent(operatorv1beta2.ConditionTypeMainDeploymentAvailable, metav1.ConditionFalse, "TestAvailable") - (*t).checkConditionPresent(operatorv1beta1.ConditionTypeMainDeploymentProgressing, metav1.ConditionTrue, + (*t).checkConditionPresent(operatorv1beta2.ConditionTypeMainDeploymentProgressing, metav1.ConditionTrue, "TestProgressing") - (*t).checkConditionAbsent(operatorv1beta1.ConditionTypeMainDeploymentReplicaFailure) + (*t).checkConditionAbsent(operatorv1beta2.ConditionTypeMainDeploymentReplicaFailure) }) Context("then becomes available", func() { JustBeforeEach(func() { (*t).makeDeploymentAvailable((*t).Name) }) It("should update conditions", func() { - (*t).checkConditionPresent(operatorv1beta1.ConditionTypeMainDeploymentAvailable, metav1.ConditionTrue, + (*t).checkConditionPresent(operatorv1beta2.ConditionTypeMainDeploymentAvailable, metav1.ConditionTrue, "TestAvailable") - (*t).checkConditionPresent(operatorv1beta1.ConditionTypeMainDeploymentProgressing, metav1.ConditionTrue, + (*t).checkConditionPresent(operatorv1beta2.ConditionTypeMainDeploymentProgressing, metav1.ConditionTrue, "TestProgressing") - (*t).checkConditionAbsent(operatorv1beta1.ConditionTypeMainDeploymentReplicaFailure) + (*t).checkConditionAbsent(operatorv1beta2.ConditionTypeMainDeploymentReplicaFailure) }) }) Context("then fails to roll out", func() { @@ -201,11 +201,11 @@ func expectSuccessful(t **cryostatTestInput) { (*t).makeDeploymentFail((*t).Name) }) It("should update conditions", func() { - (*t).checkConditionPresent(operatorv1beta1.ConditionTypeMainDeploymentAvailable, metav1.ConditionFalse, + (*t).checkConditionPresent(operatorv1beta2.ConditionTypeMainDeploymentAvailable, metav1.ConditionFalse, "TestAvailable") - (*t).checkConditionPresent(operatorv1beta1.ConditionTypeMainDeploymentProgressing, metav1.ConditionFalse, + (*t).checkConditionPresent(operatorv1beta2.ConditionTypeMainDeploymentProgressing, metav1.ConditionFalse, "TestProgressing") - (*t).checkConditionPresent(operatorv1beta1.ConditionTypeMainDeploymentReplicaFailure, metav1.ConditionTrue, + (*t).checkConditionPresent(operatorv1beta2.ConditionTypeMainDeploymentReplicaFailure, metav1.ConditionTrue, "TestReplicaFailure") }) }) @@ -471,18 +471,16 @@ func (c *controllerTest) commonTests() { t.reconcileCryostatFully() }) It("should update the Role Binding", func() { + expected := t.NewRoleBinding(t.Namespace) binding := &rbacv1.RoleBinding{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, binding) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, binding) Expect(err).ToNot(HaveOccurred()) - Expect(metav1.IsControlledBy(binding, cr.Object)).To(BeTrue()) - // Labels are unaffected Expect(binding.Labels).To(Equal(oldBinding.Labels)) Expect(binding.Annotations).To(Equal(oldBinding.Annotations)) // Subjects and RoleRef should be fully replaced - expected := t.NewRoleBinding(t.Namespace) Expect(binding.Subjects).To(Equal(expected.Subjects)) Expect(binding.RoleRef).To(Equal(expected.RoleRef)) }) @@ -752,22 +750,22 @@ func (c *controllerTest) commonTests() { t.makeDeploymentProgress(t.Name + "-reports") }) It("should update conditions", func() { - t.checkConditionPresent(operatorv1beta1.ConditionTypeReportsDeploymentAvailable, metav1.ConditionFalse, + t.checkConditionPresent(operatorv1beta2.ConditionTypeReportsDeploymentAvailable, metav1.ConditionFalse, "TestAvailable") - t.checkConditionPresent(operatorv1beta1.ConditionTypeReportsDeploymentProgressing, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeReportsDeploymentProgressing, metav1.ConditionTrue, "TestProgressing") - t.checkConditionAbsent(operatorv1beta1.ConditionTypeReportsDeploymentReplicaFailure) + t.checkConditionAbsent(operatorv1beta2.ConditionTypeReportsDeploymentReplicaFailure) }) Context("then becomes available", func() { JustBeforeEach(func() { t.makeDeploymentAvailable(t.Name + "-reports") }) It("should update conditions", func() { - t.checkConditionPresent(operatorv1beta1.ConditionTypeReportsDeploymentAvailable, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeReportsDeploymentAvailable, metav1.ConditionTrue, "TestAvailable") - t.checkConditionPresent(operatorv1beta1.ConditionTypeReportsDeploymentProgressing, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeReportsDeploymentProgressing, metav1.ConditionTrue, "TestProgressing") - t.checkConditionAbsent(operatorv1beta1.ConditionTypeReportsDeploymentReplicaFailure) + t.checkConditionAbsent(operatorv1beta2.ConditionTypeReportsDeploymentReplicaFailure) }) }) Context("then fails to roll out", func() { @@ -775,11 +773,11 @@ func (c *controllerTest) commonTests() { t.makeDeploymentFail(t.Name + "-reports") }) It("should update conditions", func() { - t.checkConditionPresent(operatorv1beta1.ConditionTypeReportsDeploymentAvailable, metav1.ConditionFalse, + t.checkConditionPresent(operatorv1beta2.ConditionTypeReportsDeploymentAvailable, metav1.ConditionFalse, "TestAvailable") - t.checkConditionPresent(operatorv1beta1.ConditionTypeReportsDeploymentProgressing, metav1.ConditionFalse, + t.checkConditionPresent(operatorv1beta2.ConditionTypeReportsDeploymentProgressing, metav1.ConditionFalse, "TestProgressing") - t.checkConditionPresent(operatorv1beta1.ConditionTypeReportsDeploymentReplicaFailure, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeReportsDeploymentReplicaFailure, metav1.ConditionTrue, "TestReplicaFailure") }) }) @@ -795,7 +793,7 @@ func (c *controllerTest) commonTests() { cryostat := t.getCryostatInstance() t.ReportReplicas = 1 - cryostat.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + cryostat.Spec.ReportOptions = &operatorv1beta2.ReportConfiguration{ Replicas: t.ReportReplicas, } t.updateCryostatInstance(cryostat) @@ -875,9 +873,9 @@ func (c *controllerTest) commonTests() { t.expectNoReportsDeployment() }) It("should remove conditions", func() { - t.checkConditionAbsent(operatorv1beta1.ConditionTypeReportsDeploymentAvailable) - t.checkConditionAbsent(operatorv1beta1.ConditionTypeReportsDeploymentProgressing) - t.checkConditionAbsent(operatorv1beta1.ConditionTypeReportsDeploymentReplicaFailure) + t.checkConditionAbsent(operatorv1beta2.ConditionTypeReportsDeploymentAvailable) + t.checkConditionAbsent(operatorv1beta2.ConditionTypeReportsDeploymentProgressing) + t.checkConditionAbsent(operatorv1beta2.ConditionTypeReportsDeploymentReplicaFailure) }) }) Context("Cryostat CR has list of certificate secrets", func() { @@ -1396,7 +1394,7 @@ func (c *controllerTest) commonTests() { }) It("should set TLSSetupComplete condition", func() { t.reconcileCryostatFully() - t.checkConditionPresent(operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "AllCertificatesReady") }) }) @@ -1425,7 +1423,7 @@ func (c *controllerTest) commonTests() { }) It("should set TLSSetupComplete Condition", func() { t.reconcileCryostatFully() - t.checkConditionPresent(operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "CertManagerDisabled") }) }) @@ -1452,7 +1450,7 @@ func (c *controllerTest) commonTests() { t.expectRoutes() }) It("should set TLSSetupComplete Condition", func() { - t.checkConditionPresent(operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "CertManagerDisabled") }) }) @@ -1483,7 +1481,7 @@ func (c *controllerTest) commonTests() { t.expectRoutes() }) It("should set TLSSetupComplete condition", func() { - t.checkConditionPresent(operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "AllCertificatesReady") }) }) @@ -1507,7 +1505,7 @@ func (c *controllerTest) commonTests() { Expect(eventMsg).To(ContainSubstring("CertManagerUnavailable")) }) It("should set TLSSetupComplete Condition", func() { - t.checkConditionPresent(operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionFalse, + t.checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionFalse, "CertManagerUnavailable") }) }) @@ -1525,7 +1523,7 @@ func (c *controllerTest) commonTests() { Expect(recorder.Events).ToNot(Receive()) }) It("should set TLSSetupComplete Condition", func() { - t.checkConditionPresent(operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, + t.checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "CertManagerDisabled") }) }) @@ -1811,8 +1809,6 @@ func (c *controllerTest) commonTests() { // Reconcile conflicting namespaced Cryostat fully otherInput.reconcileCryostatFully() - // Try reconciling ClusterCryostat - reconcileErr = t.reconcileCryostatFullyWithError() }) JustAfterEach(func() { @@ -1828,6 +1824,11 @@ func (c *controllerTest) commonTests() { otherInput.objs = t.objs }) + JustBeforeEach(func() { + // Try reconciling ClusterCryostat + reconcileErr = t.reconcileCryostatFullyWithError() + }) + It("should fail to reconcile", func() { t.expectAlreadyOwnedError(reconcileErr, "ConfigMap", t.NewLockConfigMap(), otherInput) }) @@ -1881,16 +1882,107 @@ func (c *controllerTest) commonTests() { otherInput.objs = t.objs }) - It("should fail to reconcile", func() { - t.expectAlreadyOwnedError(reconcileErr, "RoleBinding", t.NewRoleBinding(nsInput.Namespace), otherInput) + JustBeforeEach(func() { + // Try reconciling ClusterCryostat + t.reconcileCryostatFully() }) - It("should emit a CryostatNameConflict event", func() { - t.expectNameConflictEvent() + // Existing Cryostat installation should be unaffected + Context("existing installation", func() { + expectSuccessful(&otherInput) }) - // Existing Cryostat installation should be unaffected - expectSuccessful(&otherInput) + // New installation should also be unaffected + Context("new installation", func() { + expectSuccessful(&otherInput) + }) + }) + }) + + Context("reconciling a multi-namespace request", func() { + targetNamespaces := []string{"multi-test-one", "multi-test-two"} + + BeforeEach(func() { + // Create Namespaces + for _, ns := range targetNamespaces { + t.objs = append(t.objs, t.NewOtherNamespace(ns)) + } + }) + + JustBeforeEach(func() { + t.reconcileCryostatFully() + }) + + Context("with unchanged target namespaces", func() { + BeforeEach(func() { + t.TargetNamespaces = targetNamespaces + t.objs = append(t.objs, t.NewCryostat().Object) + }) + + It("should create the expected main deployment", func() { + t.expectMainDeployment() + }) + + It("should create CA Cert secret in each namespace", func() { + t.expectCertificates() + }) + + It("should create RBAC in each namespace", func() { + t.expectRBAC() + }) + + It("should update the target namespaces in Status", func() { + t.expectTargetNamespaces() + }) + }) + + Context("with removed target namespaces", func() { + BeforeEach(func() { + // Begin with RBAC set up for two namespaces, + // and remove the second namespace from the spec + t.TargetNamespaces = targetNamespaces[:1] + cr := t.NewCryostat() + *cr.TargetNamespaceStatus = targetNamespaces + t.objs = append(t.objs, cr.Object, + t.NewRoleBinding(targetNamespaces[0]), + t.NewRoleBinding(targetNamespaces[1]), + t.NewCACertSecret(targetNamespaces[0]), + t.NewCACertSecret(targetNamespaces[1])) + }) + It("should create the expected main deployment", func() { + t.expectMainDeployment() + }) + It("leave RBAC for the first namespace", func() { + t.expectRBAC() + }) + It("should remove RBAC from the second namespace", func() { + binding := t.NewRoleBinding(targetNamespaces[1]) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: binding.Name, Namespace: binding.Namespace}, binding) + Expect(err).ToNot(BeNil()) + Expect(kerrors.IsNotFound(err)).To(BeTrue()) + }) + It("leave CA Cert secret for the first namespace", func() { + t.expectCertificates() + }) + It("should remove CA Cert secret from the second namespace", func() { + secret := t.NewCACertSecret(targetNamespaces[1]) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: secret.Name, Namespace: secret.Namespace}, secret) + Expect(err).ToNot(BeNil()) + Expect(kerrors.IsNotFound(err)).To(BeTrue()) + }) + It("should update the target namespaces in Status", func() { + t.expectTargetNamespaces() + }) + }) + + Context("with no target namespaces", func() { + BeforeEach(func() { + t.TargetNamespaces = nil + t.objs = append(t.objs, t.NewCryostat().Object) + }) + It("should update the target namespaces in Status", func() { + t.expectTargetNamespaces() + }) }) }) }) @@ -2168,18 +2260,16 @@ func (c *controllerTest) commonTests() { It("should update the Role Binding", func() { t.reconcileCryostatFully() + expected := t.NewRoleBinding(t.Namespace) binding := &rbacv1.RoleBinding{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, binding) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, binding) Expect(err).ToNot(HaveOccurred()) - Expect(metav1.IsControlledBy(binding, cr.Object)).To(BeTrue()) - // Labels are unaffected Expect(binding.Labels).To(Equal(oldBinding.Labels)) Expect(binding.Annotations).To(Equal(oldBinding.Annotations)) // Subjects and RoleRef should be fully replaced - expected := t.NewRoleBinding(t.Namespace) Expect(binding.Subjects).To(Equal(expected.Subjects)) Expect(binding.RoleRef).To(Equal(expected.RoleRef)) }) @@ -2246,7 +2336,7 @@ func (t *cryostatTestInput) checkRoute(expected *openshiftv1.Route) *openshiftv1 return route } -func (t *cryostatTestInput) checkConditionPresent(condType operatorv1beta1.CryostatConditionType, status metav1.ConditionStatus, reason string) { +func (t *cryostatTestInput) checkConditionPresent(condType operatorv1beta2.CryostatConditionType, status metav1.ConditionStatus, reason string) { cr := t.getCryostatInstance() condition := meta.FindStatusCondition(cr.Status.Conditions, string(condType)) @@ -2255,7 +2345,7 @@ func (t *cryostatTestInput) checkConditionPresent(condType operatorv1beta1.Cryos Expect(condition.Reason).To(Equal(reason)) } -func (t *cryostatTestInput) checkConditionAbsent(condType operatorv1beta1.CryostatConditionType) { +func (t *cryostatTestInput) checkConditionAbsent(condType operatorv1beta2.CryostatConditionType) { cr := t.getCryostatInstance() condition := meta.FindStatusCondition(cr.Status.Conditions, string(condType)) @@ -2296,12 +2386,16 @@ func (t *cryostatTestInput) reconcileDeletedCryostat() { } func (t *cryostatTestInput) checkMetadata(object metav1.Object, expected metav1.Object) { + t.checkMetadataNoOwner(object, expected) + Expect(object.GetOwnerReferences()).To(HaveLen(1)) + Expect(metav1.IsControlledBy(object, t.getCryostatInstance().Object)) +} + +func (t *cryostatTestInput) checkMetadataNoOwner(object metav1.Object, expected metav1.Object) { Expect(object.GetName()).To(Equal(expected.GetName())) Expect(object.GetNamespace()).To(Equal(expected.GetNamespace())) Expect(object.GetLabels()).To(Equal(expected.GetLabels())) Expect(object.GetAnnotations()).To(Equal(expected.GetAnnotations())) - Expect(object.GetOwnerReferences()).To(HaveLen(1)) - Expect(metav1.IsControlledBy(object, t.getCryostatInstance().Object)) } func (t *cryostatTestInput) expectNoCryostat() { @@ -2315,7 +2409,7 @@ func (t *cryostatTestInput) expectWaitingForCertificate() { Expect(result).To(Equal(reconcile.Result{RequeueAfter: 5 * time.Second})) // Check TLSSetupComplete condition - t.checkConditionPresent(operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionFalse, + t.checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionFalse, "WaitingForCertificate") } @@ -2359,13 +2453,14 @@ func (t *cryostatTestInput) expectCertificates() { Expect(t.TargetNamespaces).ToNot(BeEmpty()) for _, ns := range t.TargetNamespaces { if ns != t.Namespace { - namespaceSecret := t.NewCACertSecret(ns) + expectedSecret := t.NewCACertSecret(ns) secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: namespaceSecret.Name, Namespace: ns}, secret) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: expectedSecret.Name, Namespace: ns}, secret) Expect(err).ToNot(HaveOccurred()) - t.checkMetadata(secret, namespaceSecret) - Expect(secret.Data).To(Equal(namespaceSecret.Data)) - Expect(secret.Type).To(Equal(namespaceSecret.Type)) + t.checkMetadataNoOwner(secret, expectedSecret) + Expect(secret.GetOwnerReferences()).To(BeEmpty()) + Expect(secret.Data).To(Equal(expectedSecret.Data)) + Expect(secret.Type).To(Equal(expectedSecret.Type)) } } } @@ -2383,11 +2478,12 @@ func (t *cryostatTestInput) expectRBAC() { // Check for Role and RoleBinding in each target namespace Expect(t.TargetNamespaces).ToNot(BeEmpty()) // Sanity check for tests for _, ns := range t.TargetNamespaces { + expectedBinding := t.NewRoleBinding(ns) binding := &rbacv1.RoleBinding{} - err = t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: ns}, binding) + err = t.Client.Get(context.Background(), types.NamespacedName{Name: expectedBinding.Name, Namespace: expectedBinding.Namespace}, binding) Expect(err).ToNot(HaveOccurred()) - expectedBinding := t.NewRoleBinding(ns) - t.checkMetadata(binding, expectedBinding) + t.checkMetadataNoOwner(binding, expectedBinding) + Expect(binding.GetOwnerReferences()).To(BeEmpty()) Expect(binding.Subjects).To(Equal(expectedBinding.Subjects)) Expect(binding.RoleRef).To(Equal(expectedBinding.RoleRef)) } @@ -3024,14 +3120,14 @@ func (t *cryostatTestInput) getCryostatInstance() *model.CryostatInstance { func (t *cryostatTestInput) lookupCryostatInstance() (*model.CryostatInstance, error) { if t.ClusterScoped { - cr := &operatorv1beta1.ClusterCryostat{} + cr := &operatorv1beta2.ClusterCryostat{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name}, cr) if err != nil { return nil, err } return t.ConvertClusterToModel(cr), nil } else { - cr := &operatorv1beta1.Cryostat{} + cr := &operatorv1beta2.Cryostat{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, cr) if err != nil { return nil, err @@ -3098,6 +3194,11 @@ func (t *cryostatTestInput) expectResourcesUnaffected() { } } +func (t *cryostatTestInput) expectTargetNamespaces() { + cr := t.getCryostatInstance() + Expect(*cr.TargetNamespaceStatus).To(ConsistOf(t.TargetNamespaces)) +} + func getControllerFunc(clusterScoped bool) func(*controllers.ReconcilerConfig) (controllers.CommonReconciler, error) { if clusterScoped { return newClusterCryostatController diff --git a/internal/controllers/routes.go b/internal/controllers/routes.go index 97564639b..6f2a6145d 100644 --- a/internal/controllers/routes.go +++ b/internal/controllers/routes.go @@ -20,7 +20,7 @@ import ( "fmt" "net/url" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" common "github.com/cryostatio/cryostat-operator/internal/controllers/common" "github.com/cryostatio/cryostat-operator/internal/controllers/common/resource_definitions" "github.com/cryostatio/cryostat-operator/internal/controllers/constants" @@ -79,7 +79,7 @@ func (r *Reconciler) reconcileGrafanaRoute(ctx context.Context, svc *corev1.Serv var ErrIngressNotReady = goerrors.New("ingress configuration not yet available") func (r *Reconciler) reconcileRoute(ctx context.Context, route *routev1.Route, svc *corev1.Service, - cr *model.CryostatInstance, tls *resource_definitions.TLSConfig, config *operatorv1beta1.NetworkConfiguration) (*url.URL, error) { + cr *model.CryostatInstance, tls *resource_definitions.TLSConfig, config *operatorv1beta2.NetworkConfiguration) (*url.URL, error) { port, err := getHTTPPort(svc) if err != nil { return nil, err @@ -101,7 +101,7 @@ func (r *Reconciler) reconcileRoute(ctx context.Context, route *routev1.Route, s } func (r *Reconciler) createOrUpdateRoute(ctx context.Context, route *routev1.Route, owner metav1.Object, - svc *corev1.Service, exposePort *corev1.ServicePort, tlsConfig *resource_definitions.TLSConfig, config *operatorv1beta1.NetworkConfiguration) (*routev1.Route, error) { + svc *corev1.Service, exposePort *corev1.ServicePort, tlsConfig *resource_definitions.TLSConfig, config *operatorv1beta2.NetworkConfiguration) (*routev1.Route, error) { // Use edge termination by default var routeTLS *routev1.TLSConfig if tlsConfig == nil { @@ -165,10 +165,10 @@ func getHTTPPort(svc *corev1.Service) (*corev1.ServicePort, error) { return nil, fmt.Errorf("no \"%s\"port in %s service in %s namespace", constants.HttpPortName, svc.Name, svc.Namespace) } -func configureCoreRoute(cr *model.CryostatInstance) *operatorv1beta1.NetworkConfiguration { - var config *operatorv1beta1.NetworkConfiguration +func configureCoreRoute(cr *model.CryostatInstance) *operatorv1beta2.NetworkConfiguration { + var config *operatorv1beta2.NetworkConfiguration if cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.CoreConfig == nil { - config = &operatorv1beta1.NetworkConfiguration{} + config = &operatorv1beta2.NetworkConfiguration{} } else { config = cr.Spec.NetworkOptions.CoreConfig } @@ -177,10 +177,10 @@ func configureCoreRoute(cr *model.CryostatInstance) *operatorv1beta1.NetworkConf return config } -func configureGrafanaRoute(cr *model.CryostatInstance) *operatorv1beta1.NetworkConfiguration { - var config *operatorv1beta1.NetworkConfiguration +func configureGrafanaRoute(cr *model.CryostatInstance) *operatorv1beta2.NetworkConfiguration { + var config *operatorv1beta2.NetworkConfiguration if cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.GrafanaConfig == nil { - config = &operatorv1beta1.NetworkConfiguration{} + config = &operatorv1beta2.NetworkConfiguration{} } else { config = cr.Spec.NetworkOptions.GrafanaConfig } @@ -189,7 +189,7 @@ func configureGrafanaRoute(cr *model.CryostatInstance) *operatorv1beta1.NetworkC return config } -func configureRoute(config *operatorv1beta1.NetworkConfiguration, appLabel string, componentLabel string) { +func configureRoute(config *operatorv1beta2.NetworkConfiguration, appLabel string, componentLabel string) { if config.Labels == nil { config.Labels = map[string]string{} } diff --git a/internal/controllers/services.go b/internal/controllers/services.go index 2332ee0cc..6718c2d2f 100644 --- a/internal/controllers/services.go +++ b/internal/controllers/services.go @@ -20,7 +20,7 @@ import ( "net/url" "strconv" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" common "github.com/cryostatio/cryostat-operator/internal/controllers/common" "github.com/cryostatio/cryostat-operator/internal/controllers/common/resource_definitions" "github.com/cryostatio/cryostat-operator/internal/controllers/constants" @@ -159,11 +159,11 @@ func (r *Reconciler) reconcileReportsService(ctx context.Context, cr *model.Cryo return nil } -func configureCoreService(cr *model.CryostatInstance) *operatorv1beta1.CoreServiceConfig { +func configureCoreService(cr *model.CryostatInstance) *operatorv1beta2.CoreServiceConfig { // Check CR for config - var config *operatorv1beta1.CoreServiceConfig + var config *operatorv1beta2.CoreServiceConfig if cr.Spec.ServiceOptions == nil || cr.Spec.ServiceOptions.CoreConfig == nil { - config = &operatorv1beta1.CoreServiceConfig{} + config = &operatorv1beta2.CoreServiceConfig{} } else { config = cr.Spec.ServiceOptions.CoreConfig.DeepCopy() } @@ -184,11 +184,11 @@ func configureCoreService(cr *model.CryostatInstance) *operatorv1beta1.CoreServi return config } -func configureGrafanaService(cr *model.CryostatInstance) *operatorv1beta1.GrafanaServiceConfig { +func configureGrafanaService(cr *model.CryostatInstance) *operatorv1beta2.GrafanaServiceConfig { // Check CR for config - var config *operatorv1beta1.GrafanaServiceConfig + var config *operatorv1beta2.GrafanaServiceConfig if cr.Spec.ServiceOptions == nil || cr.Spec.ServiceOptions.GrafanaConfig == nil { - config = &operatorv1beta1.GrafanaServiceConfig{} + config = &operatorv1beta2.GrafanaServiceConfig{} } else { config = cr.Spec.ServiceOptions.GrafanaConfig.DeepCopy() } @@ -205,11 +205,11 @@ func configureGrafanaService(cr *model.CryostatInstance) *operatorv1beta1.Grafan return config } -func configureReportsService(cr *model.CryostatInstance) *operatorv1beta1.ReportsServiceConfig { +func configureReportsService(cr *model.CryostatInstance) *operatorv1beta2.ReportsServiceConfig { // Check CR for config - var config *operatorv1beta1.ReportsServiceConfig + var config *operatorv1beta2.ReportsServiceConfig if cr.Spec.ServiceOptions == nil || cr.Spec.ServiceOptions.ReportsConfig == nil { - config = &operatorv1beta1.ReportsServiceConfig{} + config = &operatorv1beta2.ReportsServiceConfig{} } else { config = cr.Spec.ServiceOptions.ReportsConfig.DeepCopy() } @@ -226,7 +226,7 @@ func configureReportsService(cr *model.CryostatInstance) *operatorv1beta1.Report return config } -func configureService(config *operatorv1beta1.ServiceConfig, appLabel string, componentLabel string) { +func configureService(config *operatorv1beta2.ServiceConfig, appLabel string, componentLabel string) { if config.ServiceType == nil { svcType := corev1.ServiceTypeClusterIP config.ServiceType = &svcType @@ -244,7 +244,7 @@ func configureService(config *operatorv1beta1.ServiceConfig, appLabel string, co } func (r *Reconciler) createOrUpdateService(ctx context.Context, svc *corev1.Service, owner metav1.Object, - config *operatorv1beta1.ServiceConfig, delegate controllerutil.MutateFn) error { + config *operatorv1beta2.ServiceConfig, delegate controllerutil.MutateFn) error { op, err := controllerutil.CreateOrUpdate(ctx, r.Client, svc, func() error { // Update labels and annotations common.MergeLabelsAndAnnotations(&svc.ObjectMeta, config.Labels, config.Annotations) diff --git a/internal/main.go b/internal/main.go index 229200b95..b5d4c2fd4 100644 --- a/internal/main.go +++ b/internal/main.go @@ -15,6 +15,7 @@ package main import ( + "crypto/tls" "flag" "fmt" "net/url" @@ -35,11 +36,14 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/webhook" operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + 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/insights" + "github.com/cryostatio/cryostat-operator/internal/webhooks" // +kubebuilder:scaffold:imports ) @@ -59,6 +63,7 @@ func init() { utilruntime.Must(consolev1.AddToScheme(scheme)) utilruntime.Must(configv1.AddToScheme(scheme)) + utilruntime.Must(operatorv1beta2.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme } @@ -66,11 +71,13 @@ func main() { var metricsAddr string var enableLeaderElection bool var probeAddr string + var enableHTTP2 bool flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") + flag.BoolVar(&enableHTTP2, "enable-http2", false, "If HTTP/2 should be enabled for the metrics and webhook servers.") opts := zap.Options{ Development: true, } @@ -79,6 +86,17 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + // Customize the webhook server to disable HTTP/2 by default + disableHTTP2 := func(c *tls.Config) { + if enableHTTP2 { + return + } + c.NextProtos = []string{"http/1.1"} + } + webhookServer := &webhook.Server{ + TLSOpts: []func(config *tls.Config){disableHTTP2}, + } + // FIXME Disable metrics until this issue is resolved: // https://github.com/operator-framework/operator-sdk/issues/4684 metricsAddr = "0" @@ -89,6 +107,7 @@ func main() { HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionID: "d696d7ab.redhat.com", + WebhookServer: webhookServer, }) if err != nil { setupLog.Error(err, "unable to start manager") @@ -155,6 +174,10 @@ func main() { setupLog.Error(err, "unable to add controller to manager", "controller", "Cryostat") os.Exit(1) } + if err = webhooks.SetupWebhookWithManager(mgr, &operatorv1beta2.Cryostat{}); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Cryostat") + os.Exit(1) + } // +kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/internal/test/conversion.go b/internal/test/conversion.go new file mode 100644 index 000000000..b1167a327 --- /dev/null +++ b/internal/test/conversion.go @@ -0,0 +1,638 @@ +// 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 ( + operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + corev1 "k8s.io/api/core/v1" + netv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// v1beta1 versions of Cryostat CRs used for testing the conversion webhook + +func (r *TestResources) NewCryostatV1Beta1() *operatorv1beta1.Cryostat { + return &operatorv1beta1.Cryostat{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name, + Namespace: r.Namespace, + }, + Spec: r.newCryostatSpecV1Beta1(), + } +} + +func (r *TestResources) newCryostatSpecV1Beta1() operatorv1beta1.CryostatSpec { + certManager := true + var reportOptions *operatorv1beta1.ReportConfiguration + if r.ReportReplicas > 0 { + reportOptions = &operatorv1beta1.ReportConfiguration{ + Replicas: r.ReportReplicas, + } + } + return operatorv1beta1.CryostatSpec{ + Minimal: r.Minimal, + EnableCertManager: &certManager, + ReportOptions: reportOptions, + } +} + +func (r *TestResources) NewCryostatWithSecretsV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + key := "test.crt" + cr.Spec.TrustedCertSecrets = []operatorv1beta1.CertificateSecret{ + { + SecretName: "testCert1", + CertificateKey: &key, + }, + { + SecretName: "testCert2", + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithTemplatesV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.EventTemplates = []operatorv1beta1.TemplateConfigMap{ + { + ConfigMapName: "templateCM1", + Filename: "template.jfc", + }, + { + ConfigMapName: "templateCM2", + Filename: "other-template.jfc", + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithIngressV1Beta1() *operatorv1beta1.Cryostat { + return r.addIngressToCryostatV1Beta1(r.NewCryostatV1Beta1()) +} + +func (r *TestResources) NewCryostatWithIngressCertManagerDisabledV1Beta1() *operatorv1beta1.Cryostat { + return r.addIngressToCryostatV1Beta1(r.NewCryostatCertManagerDisabledV1Beta1()) +} + +func (r *TestResources) addIngressToCryostatV1Beta1(cr *operatorv1beta1.Cryostat) *operatorv1beta1.Cryostat { + networkConfig := r.newNetworkConfigurationListV1Beta1() + cr.Spec.NetworkOptions = &networkConfig + return cr +} + +func (r *TestResources) NewCryostatWithPVCSpecV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ + PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ + Annotations: map[string]string{ + "my/custom": "annotation", + }, + Labels: map[string]string{ + "my": "label", + "app": "somethingelse", + }, + Spec: newPVCSpec("cool-storage", "10Gi", corev1.ReadWriteMany), + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithPVCSpecSomeDefaultV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ + PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ + Spec: newPVCSpec("", "1Gi"), + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithPVCLabelsOnlyV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ + PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ + Labels: map[string]string{ + "my": "label", + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithDefaultEmptyDirV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ + EmptyDir: &operatorv1beta1.EmptyDirConfig{ + Enabled: true, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithEmptyDirSpecV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ + EmptyDir: &operatorv1beta1.EmptyDirConfig{ + Enabled: true, + Medium: "Memory", + SizeLimit: "200Mi", + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithCoreSvcV1Beta1() *operatorv1beta1.Cryostat { + svcType := corev1.ServiceTypeNodePort + httpPort := int32(8080) + jmxPort := int32(9095) + cr := r.NewCryostatV1Beta1() + cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ + CoreConfig: &operatorv1beta1.CoreServiceConfig{ + HTTPPort: &httpPort, + JMXPort: &jmxPort, + ServiceConfig: operatorv1beta1.ServiceConfig{ + ServiceType: &svcType, + Annotations: map[string]string{ + "my/custom": "annotation", + }, + Labels: map[string]string{ + "my": "label", + "app": "somethingelse", + }, + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithGrafanaSvcV1Beta1() *operatorv1beta1.Cryostat { + svcType := corev1.ServiceTypeNodePort + httpPort := int32(8080) + cr := r.NewCryostatV1Beta1() + cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ + GrafanaConfig: &operatorv1beta1.GrafanaServiceConfig{ + HTTPPort: &httpPort, + ServiceConfig: operatorv1beta1.ServiceConfig{ + ServiceType: &svcType, + Annotations: map[string]string{ + "my/custom": "annotation", + }, + Labels: map[string]string{ + "my": "label", + "app": "somethingelse", + }, + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithReportsSvcV1Beta1() *operatorv1beta1.Cryostat { + svcType := corev1.ServiceTypeNodePort + httpPort := int32(13161) + cr := r.NewCryostatV1Beta1() + cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ + ReportsConfig: &operatorv1beta1.ReportsServiceConfig{ + HTTPPort: &httpPort, + ServiceConfig: operatorv1beta1.ServiceConfig{ + ServiceType: &svcType, + Annotations: map[string]string{ + "my/custom": "annotation", + }, + Labels: map[string]string{ + "my": "label", + "app": "somethingelse", + }, + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithCoreNetworkOptionsV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.NetworkOptions = &operatorv1beta1.NetworkConfigurationList{ + CoreConfig: &operatorv1beta1.NetworkConfiguration{ + Annotations: map[string]string{"custom": "annotation"}, + Labels: map[string]string{ + "custom": "label", + "app": "test-app", + "component": "test-comp", + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithGrafanaNetworkOptionsV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.NetworkOptions = &operatorv1beta1.NetworkConfigurationList{ + GrafanaConfig: &operatorv1beta1.NetworkConfiguration{ + Annotations: map[string]string{"grafana": "annotation"}, + Labels: map[string]string{ + "grafana": "label", + "component": "test-comp", + "app": "test-app", + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithReportsResourcesV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + Replicas: 1, + Resources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1600m"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("800m"), + corev1.ResourceMemory: resource.MustParse("512Mi"), + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithReportLowResourceLimitV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + Replicas: 1, + Resources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("20m"), + corev1.ResourceMemory: resource.MustParse("32Mi"), + }, + }, + } + return cr +} + +func populateCryostatWithSchedulingV1Beta1() *operatorv1beta1.SchedulingConfiguration { + return &operatorv1beta1.SchedulingConfiguration{ + NodeSelector: map[string]string{"node": "good"}, + Affinity: &operatorv1beta1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "node", + Operator: corev1.NodeSelectorOpIn, + Values: []string{ + "good", + "better", + }, + }, + }, + }, + }, + }, + }, + PodAffinity: &corev1.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ + { + LabelSelector: metav1.AddLabelToSelector(&metav1.LabelSelector{}, + "pod", "good"), + TopologyKey: "topology.kubernetes.io/zone", + }, + }, + }, + PodAntiAffinity: &corev1.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ + {LabelSelector: metav1.AddLabelToSelector(&metav1.LabelSelector{}, + "pod", "bad"), + TopologyKey: "topology.kubernetes.io/zone", + }, + }, + }, + }, + Tolerations: []corev1.Toleration{ + { + Key: "node", + Operator: corev1.TolerationOpEqual, + Value: "ok", + Effect: corev1.TaintEffectNoExecute, + }, + }, + } + +} + +func (r *TestResources) NewCryostatWithSchedulingV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.SchedulingOptions = populateCryostatWithSchedulingV1Beta1() + return cr +} + +func (r *TestResources) NewCryostatWithReportsSchedulingV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + Replicas: 1, + SchedulingOptions: populateCryostatWithSchedulingV1Beta1(), + } + + return cr +} + +func (r *TestResources) NewCryostatCertManagerDisabledV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + certManager := false + cr.Spec.EnableCertManager = &certManager + return cr +} + +func (r *TestResources) NewCryostatCertManagerUndefinedV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.EnableCertManager = nil + return cr +} + +func (r *TestResources) NewCryostatWithResourcesV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.Resources = &operatorv1beta1.ResourceConfigList{ + CoreResources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("256Mi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("250m"), + corev1.ResourceMemory: resource.MustParse("128Mi"), + }, + }, + GrafanaResources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("550m"), + corev1.ResourceMemory: resource.MustParse("512Mi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("128m"), + corev1.ResourceMemory: resource.MustParse("256Mi"), + }, + }, + DataSourceResources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("600m"), + corev1.ResourceMemory: resource.MustParse("128Mi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("300m"), + corev1.ResourceMemory: resource.MustParse("64Mi"), + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithLowResourceLimitV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.Resources = &operatorv1beta1.ResourceConfigList{ + CoreResources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("10m"), + corev1.ResourceMemory: resource.MustParse("32Mi"), + }, + }, + GrafanaResources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("10m"), + corev1.ResourceMemory: resource.MustParse("32Mi"), + }, + }, + DataSourceResources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("10m"), + corev1.ResourceMemory: resource.MustParse("32Mi"), + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithAuthPropertiesV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.AuthProperties = &operatorv1beta1.AuthorizationProperties{ + ConfigMapName: "authConfigMapName", + Filename: "auth.properties", + ClusterRoleName: "custom-auth-cluster-role", + } + return cr +} + +func (r *TestResources) NewCryostatWithBuiltInDiscoveryDisabledV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.TargetDiscoveryOptions = &operatorv1beta1.TargetDiscoveryOptions{ + BuiltInDiscoveryDisabled: true, + } + return cr +} + +func (r *TestResources) NewCryostatWithJmxCacheOptionsSpecV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.JmxCacheOptions = &operatorv1beta1.JmxCacheOptions{ + TargetCacheSize: 10, + TargetCacheTTL: 20, + } + return cr +} + +func (r *TestResources) NewCryostatWithWsConnectionsSpecV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.MaxWsConnections = 10 + return cr +} + +func (r *TestResources) NewCryostatWithReportSubprocessHeapSpecV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + if cr.Spec.ReportOptions == nil { + cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{} + } + cr.Spec.ReportOptions.SubProcessMaxHeapSize = 500 + return cr +} + +func (r *TestResources) NewCryostatWithSecurityOptionsV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + privEscalation := true + nonRoot := false + runAsUser := int64(0) + fsGroup := int64(20000) + cr.Spec.SecurityOptions = &operatorv1beta1.SecurityOptions{ + PodSecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: &nonRoot, + FSGroup: &fsGroup, + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + }, + CoreSecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: &privEscalation, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{}, + }, + RunAsUser: &runAsUser, + }, + GrafanaSecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: &privEscalation, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{}, + }, + RunAsUser: &runAsUser, + }, + DataSourceSecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: &privEscalation, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{}, + }, + RunAsUser: &runAsUser, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithReportSecurityOptionsV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + nonRoot := true + privEscalation := false + runAsUser := int64(1002) + if cr.Spec.ReportOptions == nil { + cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{} + } + cr.Spec.ReportOptions.SecurityOptions = &operatorv1beta1.ReportsSecurityOptions{ + PodSecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: &nonRoot, + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + }, + ReportsSecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: &privEscalation, + RunAsUser: &runAsUser, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + }, + } + return cr +} + +func (r *TestResources) NewCryostatWithDatabaseSecretProvidedV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.JmxCredentialsDatabaseOptions = &operatorv1beta1.JmxCredentialsDatabaseOptions{ + DatabaseSecretName: &providedDatabaseSecretName, + } + return cr +} + +func (r *TestResources) NewCryostatWithAdditionalMetadataV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.OperandMetadata = &operatorv1beta1.OperandMetadata{ + DeploymentMetadata: &operatorv1beta1.ResourceMetadata{ + Labels: map[string]string{ + "myDeploymentExtraLabel": "myDeploymentLabel", + "mySecondDeploymentExtraLabel": "mySecondDeploymentLabel", + // below, labels that should be discarded as overriden by the default + "app": "myApp", + "component": "myComponent", + "kind": "myKind", + "app.kubernetes.io/name": "myName", + }, + Annotations: map[string]string{ + "myDeploymentExtraAnnotation": "myDeploymentAnnotation", + "mySecondDeploymentExtraAnnotation": "mySecondDeploymentAnnotation", + // below, annotation that should be discarded as overriden by the default + "app.openshift.io/connects-to": "connectToMe", + }, + }, + PodMetadata: &operatorv1beta1.ResourceMetadata{ + Labels: map[string]string{ + "myPodExtraLabel": "myPodLabel", + "myPodSecondExtraLabel": "myPodSecondLabel", + // below, labels that should be discarded as overriden by the default + "app": "myApp", + "component": "myComponent", + "kind": "myKind", + }, + Annotations: map[string]string{ + "myPodExtraAnnotation": "myPodAnnotation", + "mySecondPodExtraAnnotation": "mySecondPodAnnotation", + }, + }, + } + return cr +} + +func (r *TestResources) newNetworkConfigurationListV1Beta1() operatorv1beta1.NetworkConfigurationList { + coreSVC := r.NewCryostatService() + coreIng := r.newNetworkConfigurationV1Beta1(coreSVC.Name, coreSVC.Spec.Ports[0].Port) + coreIng.Annotations["custom"] = "annotation" + coreIng.Labels["custom"] = "label" + + grafanaSVC := r.NewGrafanaService() + grafanaIng := r.newNetworkConfigurationV1Beta1(grafanaSVC.Name, grafanaSVC.Spec.Ports[0].Port) + grafanaIng.Annotations["grafana"] = "annotation" + grafanaIng.Labels["grafana"] = "label" + + return operatorv1beta1.NetworkConfigurationList{ + CoreConfig: &coreIng, + GrafanaConfig: &grafanaIng, + } +} + +func (r *TestResources) newNetworkConfigurationV1Beta1(svcName string, svcPort int32) operatorv1beta1.NetworkConfiguration { + pathtype := netv1.PathTypePrefix + host := svcName + ".example.com" + + var ingressTLS []netv1.IngressTLS + if r.ExternalTLS { + ingressTLS = []netv1.IngressTLS{{}} + } + return operatorv1beta1.NetworkConfiguration{ + Annotations: map[string]string{"nginx.ingress.kubernetes.io/backend-protocol": "HTTPS"}, + Labels: map[string]string{"my": "label"}, + IngressSpec: &netv1.IngressSpec{ + Rules: []netv1.IngressRule{ + { + Host: host, + IngressRuleValue: netv1.IngressRuleValue{ + HTTP: &netv1.HTTPIngressRuleValue{ + Paths: []netv1.HTTPIngressPath{ + { + Path: "/", + PathType: &pathtype, + Backend: netv1.IngressBackend{ + Service: &netv1.IngressServiceBackend{ + Name: svcName, + Port: netv1.ServiceBackendPort{ + Number: svcPort, + }, + }, + }, + }, + }, + }, + }, + }, + }, + TLS: ingressTLS, + }, + } +} diff --git a/internal/test/resources.go b/internal/test/resources.go index d72f7b305..b2883741d 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -21,7 +21,7 @@ import ( certv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" certMeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" "github.com/cryostatio/cryostat-operator/internal/controllers/model" "github.com/onsi/gomega" configv1 "github.com/openshift/api/config/v1" @@ -59,7 +59,7 @@ func NewTestScheme() *runtime.Scheme { // Add all APIs used by the operator to the scheme sb := runtime.NewSchemeBuilder( - operatorv1beta1.AddToScheme, + operatorv1beta2.AddToScheme, certv1.AddToScheme, routev1.AddToScheme, consolev1.AddToScheme, @@ -91,21 +91,20 @@ func (r *TestResources) NewCryostat() *model.CryostatInstance { } } -func (r *TestResources) newClusterCryostat() *operatorv1beta1.ClusterCryostat { - return &operatorv1beta1.ClusterCryostat{ +func (r *TestResources) newClusterCryostat() *operatorv1beta2.ClusterCryostat { + return &operatorv1beta2.ClusterCryostat{ ObjectMeta: metav1.ObjectMeta{ Name: r.Name, }, - Spec: operatorv1beta1.ClusterCryostatSpec{ + Spec: operatorv1beta2.ClusterCryostatSpec{ InstallNamespace: r.Namespace, - TargetNamespaces: r.TargetNamespaces, CryostatSpec: r.newCryostatSpec(), }, } } -func (r *TestResources) newCryostat() *operatorv1beta1.Cryostat { - return &operatorv1beta1.Cryostat{ +func (r *TestResources) newCryostat() *operatorv1beta2.Cryostat { + return &operatorv1beta2.Cryostat{ ObjectMeta: metav1.ObjectMeta{ Name: r.Name, Namespace: r.Namespace, @@ -114,35 +113,35 @@ func (r *TestResources) newCryostat() *operatorv1beta1.Cryostat { } } -func (r *TestResources) newCryostatSpec() operatorv1beta1.CryostatSpec { +func (r *TestResources) newCryostatSpec() operatorv1beta2.CryostatSpec { certManager := true - var reportOptions *operatorv1beta1.ReportConfiguration + var reportOptions *operatorv1beta2.ReportConfiguration if r.ReportReplicas > 0 { - reportOptions = &operatorv1beta1.ReportConfiguration{ + reportOptions = &operatorv1beta2.ReportConfiguration{ Replicas: r.ReportReplicas, } } - return operatorv1beta1.CryostatSpec{ + return operatorv1beta2.CryostatSpec{ + TargetNamespaces: r.TargetNamespaces, Minimal: r.Minimal, EnableCertManager: &certManager, ReportOptions: reportOptions, } } -func (r *TestResources) ConvertNamespacedToModel(cr *operatorv1beta1.Cryostat) *model.CryostatInstance { - targetNS := []string{cr.Namespace} +func (r *TestResources) ConvertNamespacedToModel(cr *operatorv1beta2.Cryostat) *model.CryostatInstance { return &model.CryostatInstance{ Name: cr.Name, InstallNamespace: cr.Namespace, - TargetNamespaces: targetNS, - TargetNamespaceStatus: &targetNS, + TargetNamespaces: cr.Spec.TargetNamespaces, + TargetNamespaceStatus: &cr.Status.TargetNamespaces, Spec: &cr.Spec, Status: &cr.Status, Object: cr, } } -func (r *TestResources) ConvertClusterToModel(cr *operatorv1beta1.ClusterCryostat) *model.CryostatInstance { +func (r *TestResources) ConvertClusterToModel(cr *operatorv1beta2.ClusterCryostat) *model.CryostatInstance { return &model.CryostatInstance{ Name: cr.Name, InstallNamespace: cr.Spec.InstallNamespace, @@ -157,7 +156,7 @@ func (r *TestResources) ConvertClusterToModel(cr *operatorv1beta1.ClusterCryosta func (r *TestResources) NewCryostatWithSecrets() *model.CryostatInstance { cr := r.NewCryostat() key := "test.crt" - cr.Spec.TrustedCertSecrets = []operatorv1beta1.CertificateSecret{ + cr.Spec.TrustedCertSecrets = []operatorv1beta2.CertificateSecret{ { SecretName: "testCert1", CertificateKey: &key, @@ -171,7 +170,7 @@ func (r *TestResources) NewCryostatWithSecrets() *model.CryostatInstance { func (r *TestResources) NewCryostatWithTemplates() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.EventTemplates = []operatorv1beta1.TemplateConfigMap{ + cr.Spec.EventTemplates = []operatorv1beta2.TemplateConfigMap{ { ConfigMapName: "templateCM1", Filename: "template.jfc", @@ -200,8 +199,8 @@ func (r *TestResources) addIngressToCryostat(cr *model.CryostatInstance) *model. func (r *TestResources) NewCryostatWithPVCSpec() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ - PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ + cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ + PVC: &operatorv1beta2.PersistentVolumeClaimConfig{ Annotations: map[string]string{ "my/custom": "annotation", }, @@ -217,8 +216,8 @@ func (r *TestResources) NewCryostatWithPVCSpec() *model.CryostatInstance { func (r *TestResources) NewCryostatWithPVCSpecSomeDefault() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ - PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ + cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ + PVC: &operatorv1beta2.PersistentVolumeClaimConfig{ Spec: newPVCSpec("", "1Gi"), }, } @@ -227,8 +226,8 @@ func (r *TestResources) NewCryostatWithPVCSpecSomeDefault() *model.CryostatInsta func (r *TestResources) NewCryostatWithPVCLabelsOnly() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ - PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ + cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ + PVC: &operatorv1beta2.PersistentVolumeClaimConfig{ Labels: map[string]string{ "my": "label", }, @@ -239,8 +238,8 @@ func (r *TestResources) NewCryostatWithPVCLabelsOnly() *model.CryostatInstance { func (r *TestResources) NewCryostatWithDefaultEmptyDir() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ - EmptyDir: &operatorv1beta1.EmptyDirConfig{ + cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ + EmptyDir: &operatorv1beta2.EmptyDirConfig{ Enabled: true, }, } @@ -249,8 +248,8 @@ func (r *TestResources) NewCryostatWithDefaultEmptyDir() *model.CryostatInstance func (r *TestResources) NewCryostatWithEmptyDirSpec() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ - EmptyDir: &operatorv1beta1.EmptyDirConfig{ + cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ + EmptyDir: &operatorv1beta2.EmptyDirConfig{ Enabled: true, Medium: "Memory", SizeLimit: "200Mi", @@ -264,11 +263,11 @@ func (r *TestResources) NewCryostatWithCoreSvc() *model.CryostatInstance { httpPort := int32(8080) jmxPort := int32(9095) cr := r.NewCryostat() - cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ - CoreConfig: &operatorv1beta1.CoreServiceConfig{ + cr.Spec.ServiceOptions = &operatorv1beta2.ServiceConfigList{ + CoreConfig: &operatorv1beta2.CoreServiceConfig{ HTTPPort: &httpPort, JMXPort: &jmxPort, - ServiceConfig: operatorv1beta1.ServiceConfig{ + ServiceConfig: operatorv1beta2.ServiceConfig{ ServiceType: &svcType, Annotations: map[string]string{ "my/custom": "annotation", @@ -287,10 +286,10 @@ func (r *TestResources) NewCryostatWithGrafanaSvc() *model.CryostatInstance { svcType := corev1.ServiceTypeNodePort httpPort := int32(8080) cr := r.NewCryostat() - cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ - GrafanaConfig: &operatorv1beta1.GrafanaServiceConfig{ + cr.Spec.ServiceOptions = &operatorv1beta2.ServiceConfigList{ + GrafanaConfig: &operatorv1beta2.GrafanaServiceConfig{ HTTPPort: &httpPort, - ServiceConfig: operatorv1beta1.ServiceConfig{ + ServiceConfig: operatorv1beta2.ServiceConfig{ ServiceType: &svcType, Annotations: map[string]string{ "my/custom": "annotation", @@ -309,10 +308,10 @@ func (r *TestResources) NewCryostatWithReportsSvc() *model.CryostatInstance { svcType := corev1.ServiceTypeNodePort httpPort := int32(13161) cr := r.NewCryostat() - cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ - ReportsConfig: &operatorv1beta1.ReportsServiceConfig{ + cr.Spec.ServiceOptions = &operatorv1beta2.ServiceConfigList{ + ReportsConfig: &operatorv1beta2.ReportsServiceConfig{ HTTPPort: &httpPort, - ServiceConfig: operatorv1beta1.ServiceConfig{ + ServiceConfig: operatorv1beta2.ServiceConfig{ ServiceType: &svcType, Annotations: map[string]string{ "my/custom": "annotation", @@ -329,8 +328,8 @@ func (r *TestResources) NewCryostatWithReportsSvc() *model.CryostatInstance { func (r *TestResources) NewCryostatWithCoreNetworkOptions() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.NetworkOptions = &operatorv1beta1.NetworkConfigurationList{ - CoreConfig: &operatorv1beta1.NetworkConfiguration{ + cr.Spec.NetworkOptions = &operatorv1beta2.NetworkConfigurationList{ + CoreConfig: &operatorv1beta2.NetworkConfiguration{ Annotations: map[string]string{"custom": "annotation"}, Labels: map[string]string{ "custom": "label", @@ -344,8 +343,8 @@ func (r *TestResources) NewCryostatWithCoreNetworkOptions() *model.CryostatInsta func (r *TestResources) NewCryostatWithGrafanaNetworkOptions() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.NetworkOptions = &operatorv1beta1.NetworkConfigurationList{ - GrafanaConfig: &operatorv1beta1.NetworkConfiguration{ + cr.Spec.NetworkOptions = &operatorv1beta2.NetworkConfigurationList{ + GrafanaConfig: &operatorv1beta2.NetworkConfiguration{ Annotations: map[string]string{"grafana": "annotation"}, Labels: map[string]string{ "grafana": "label", @@ -359,7 +358,7 @@ func (r *TestResources) NewCryostatWithGrafanaNetworkOptions() *model.CryostatIn func (r *TestResources) NewCryostatWithReportsResources() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + cr.Spec.ReportOptions = &operatorv1beta2.ReportConfiguration{ Replicas: 1, Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ @@ -377,7 +376,7 @@ func (r *TestResources) NewCryostatWithReportsResources() *model.CryostatInstanc func (r *TestResources) NewCryostatWithReportLowResourceLimit() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + cr.Spec.ReportOptions = &operatorv1beta2.ReportConfiguration{ Replicas: 1, Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ @@ -389,10 +388,10 @@ func (r *TestResources) NewCryostatWithReportLowResourceLimit() *model.CryostatI return cr } -func populateCryostatWithScheduling() *operatorv1beta1.SchedulingConfiguration { - return &operatorv1beta1.SchedulingConfiguration{ +func populateCryostatWithScheduling() *operatorv1beta2.SchedulingConfiguration { + return &operatorv1beta2.SchedulingConfiguration{ NodeSelector: map[string]string{"node": "good"}, - Affinity: &operatorv1beta1.Affinity{ + Affinity: &operatorv1beta2.Affinity{ NodeAffinity: &corev1.NodeAffinity{ RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ NodeSelectorTerms: []corev1.NodeSelectorTerm{ @@ -449,7 +448,7 @@ func (r *TestResources) NewCryostatWithScheduling() *model.CryostatInstance { func (r *TestResources) NewCryostatWithReportsScheduling() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + cr.Spec.ReportOptions = &operatorv1beta2.ReportConfiguration{ Replicas: 1, SchedulingOptions: populateCryostatWithScheduling(), } @@ -472,7 +471,7 @@ func (r *TestResources) NewCryostatCertManagerUndefined() *model.CryostatInstanc func (r *TestResources) NewCryostatWithResources() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.Resources = &operatorv1beta1.ResourceConfigList{ + cr.Spec.Resources = &operatorv1beta2.ResourceConfigList{ CoreResources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("500m"), @@ -509,7 +508,7 @@ func (r *TestResources) NewCryostatWithResources() *model.CryostatInstance { func (r *TestResources) NewCryostatWithLowResourceLimit() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.Resources = &operatorv1beta1.ResourceConfigList{ + cr.Spec.Resources = &operatorv1beta2.ResourceConfigList{ CoreResources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("10m"), @@ -534,7 +533,7 @@ func (r *TestResources) NewCryostatWithLowResourceLimit() *model.CryostatInstanc func (r *TestResources) NewCryostatWithAuthProperties() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.AuthProperties = &operatorv1beta1.AuthorizationProperties{ + cr.Spec.AuthProperties = &operatorv1beta2.AuthorizationProperties{ ConfigMapName: "authConfigMapName", Filename: "auth.properties", ClusterRoleName: "custom-auth-cluster-role", @@ -544,7 +543,7 @@ func (r *TestResources) NewCryostatWithAuthProperties() *model.CryostatInstance func (r *TestResources) NewCryostatWithBuiltInDiscoveryDisabled() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.TargetDiscoveryOptions = &operatorv1beta1.TargetDiscoveryOptions{ + cr.Spec.TargetDiscoveryOptions = &operatorv1beta2.TargetDiscoveryOptions{ BuiltInDiscoveryDisabled: true, } return cr @@ -583,7 +582,7 @@ func newPVCSpec(storageClass string, storageRequest string, func (r *TestResources) NewCryostatWithJmxCacheOptionsSpec() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.JmxCacheOptions = &operatorv1beta1.JmxCacheOptions{ + cr.Spec.JmxCacheOptions = &operatorv1beta2.JmxCacheOptions{ TargetCacheSize: 10, TargetCacheTTL: 20, } @@ -599,7 +598,7 @@ func (r *TestResources) NewCryostatWithWsConnectionsSpec() *model.CryostatInstan func (r *TestResources) NewCryostatWithReportSubprocessHeapSpec() *model.CryostatInstance { cr := r.NewCryostat() if cr.Spec.ReportOptions == nil { - cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{} + cr.Spec.ReportOptions = &operatorv1beta2.ReportConfiguration{} } cr.Spec.ReportOptions.SubProcessMaxHeapSize = 500 return cr @@ -611,7 +610,7 @@ func (r *TestResources) NewCryostatWithSecurityOptions() *model.CryostatInstance nonRoot := false runAsUser := int64(0) fsGroup := int64(20000) - cr.Spec.SecurityOptions = &operatorv1beta1.SecurityOptions{ + cr.Spec.SecurityOptions = &operatorv1beta2.SecurityOptions{ PodSecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: &nonRoot, FSGroup: &fsGroup, @@ -650,9 +649,9 @@ func (r *TestResources) NewCryostatWithReportSecurityOptions() *model.CryostatIn privEscalation := false runAsUser := int64(1002) if cr.Spec.ReportOptions == nil { - cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{} + cr.Spec.ReportOptions = &operatorv1beta2.ReportConfiguration{} } - cr.Spec.ReportOptions.SecurityOptions = &operatorv1beta1.ReportsSecurityOptions{ + cr.Spec.ReportOptions.SecurityOptions = &operatorv1beta2.ReportsSecurityOptions{ PodSecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: &nonRoot, SeccompProfile: &corev1.SeccompProfile{ @@ -674,7 +673,7 @@ var providedDatabaseSecretName string = "credentials-database-secret" func (r *TestResources) NewCryostatWithDatabaseSecretProvided() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.JmxCredentialsDatabaseOptions = &operatorv1beta1.JmxCredentialsDatabaseOptions{ + cr.Spec.JmxCredentialsDatabaseOptions = &operatorv1beta2.JmxCredentialsDatabaseOptions{ DatabaseSecretName: &providedDatabaseSecretName, } return cr @@ -682,8 +681,8 @@ func (r *TestResources) NewCryostatWithDatabaseSecretProvided() *model.CryostatI func (r *TestResources) NewCryostatWithAdditionalMetadata() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.OperandMetadata = &operatorv1beta1.OperandMetadata{ - DeploymentMetadata: &operatorv1beta1.ResourceMetadata{ + cr.Spec.OperandMetadata = &operatorv1beta2.OperandMetadata{ + DeploymentMetadata: &operatorv1beta2.ResourceMetadata{ Labels: map[string]string{ "myDeploymentExtraLabel": "myDeploymentLabel", "mySecondDeploymentExtraLabel": "mySecondDeploymentLabel", @@ -700,7 +699,7 @@ func (r *TestResources) NewCryostatWithAdditionalMetadata() *model.CryostatInsta "app.openshift.io/connects-to": "connectToMe", }, }, - PodMetadata: &operatorv1beta1.ResourceMetadata{ + PodMetadata: &operatorv1beta2.ResourceMetadata{ Labels: map[string]string{ "myPodExtraLabel": "myPodLabel", "myPodSecondExtraLabel": "myPodSecondLabel", @@ -726,7 +725,7 @@ func (r *TestResources) NewCryostatService() *corev1.Service { Namespace: r.Namespace, OwnerReferences: []metav1.OwnerReference{ { - APIVersion: operatorv1beta1.GroupVersion.String(), + APIVersion: operatorv1beta2.GroupVersion.String(), Kind: "Cryostat", Name: r.Name, UID: "", @@ -768,7 +767,7 @@ func (r *TestResources) NewGrafanaService() *corev1.Service { Namespace: r.Namespace, OwnerReferences: []metav1.OwnerReference{ { - APIVersion: operatorv1beta1.GroupVersion.String(), + APIVersion: operatorv1beta2.GroupVersion.String(), Kind: "Cryostat", Name: r.Name, UID: "", @@ -805,7 +804,7 @@ func (r *TestResources) NewReportsService() *corev1.Service { Namespace: r.Namespace, OwnerReferences: []metav1.OwnerReference{ { - APIVersion: operatorv1beta1.GroupVersion.String(), + APIVersion: operatorv1beta2.GroupVersion.String(), Kind: "Cryostat", Name: r.Name + "-reports", UID: "", @@ -901,7 +900,7 @@ func (r *TestResources) NewTestService() *corev1.Service { func (r *TestResources) NewCACertSecret(ns string) *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-ca", + Name: r.getClusterUniqueNameForCA(), Namespace: ns, }, Type: corev1.SecretTypeOpaque, @@ -1110,7 +1109,7 @@ func (r *TestResources) NewCACert() *certv1.Certificate { }, Spec: certv1.CertificateSpec{ CommonName: fmt.Sprintf("ca.%s.cert-manager", r.Name), - SecretName: r.Name + "-ca", + SecretName: r.getClusterUniqueNameForCA(), IssuerRef: certMeta.ObjectReference{ Name: r.Name + "-self-signed", }, @@ -1142,7 +1141,7 @@ func (r *TestResources) NewCryostatCAIssuer() *certv1.Issuer { Spec: certv1.IssuerSpec{ IssuerConfig: certv1.IssuerConfig{ CA: &certv1.CAIssuer{ - SecretName: r.Name + "-ca", + SecretName: r.getClusterUniqueNameForCA(), }, }, }, @@ -2364,7 +2363,7 @@ func (r *TestResources) OtherGrafanaIngress() *netv1.Ingress { } } -func (r *TestResources) newNetworkConfigurationList() operatorv1beta1.NetworkConfigurationList { +func (r *TestResources) newNetworkConfigurationList() operatorv1beta2.NetworkConfigurationList { coreSVC := r.NewCryostatService() coreIng := r.newNetworkConfiguration(coreSVC.Name, coreSVC.Spec.Ports[0].Port) coreIng.Annotations["custom"] = "annotation" @@ -2375,13 +2374,13 @@ func (r *TestResources) newNetworkConfigurationList() operatorv1beta1.NetworkCon grafanaIng.Annotations["grafana"] = "annotation" grafanaIng.Labels["grafana"] = "label" - return operatorv1beta1.NetworkConfigurationList{ + return operatorv1beta2.NetworkConfigurationList{ CoreConfig: &coreIng, GrafanaConfig: &grafanaIng, } } -func (r *TestResources) newNetworkConfiguration(svcName string, svcPort int32) operatorv1beta1.NetworkConfiguration { +func (r *TestResources) newNetworkConfiguration(svcName string, svcPort int32) operatorv1beta2.NetworkConfiguration { pathtype := netv1.PathTypePrefix host := svcName + ".example.com" @@ -2389,7 +2388,7 @@ func (r *TestResources) newNetworkConfiguration(svcName string, svcPort int32) o if r.ExternalTLS { ingressTLS = []netv1.IngressTLS{{}} } - return operatorv1beta1.NetworkConfiguration{ + return operatorv1beta2.NetworkConfiguration{ Annotations: map[string]string{"nginx.ingress.kubernetes.io/backend-protocol": "HTTPS"}, Labels: map[string]string{"my": "label"}, IngressSpec: &netv1.IngressSpec{ @@ -2551,7 +2550,7 @@ func (r *TestResources) NewAuthClusterRole() *rbacv1.ClusterRole { func (r *TestResources) NewRoleBinding(ns string) *rbacv1.RoleBinding { return &rbacv1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: r.Name, + Name: r.getClusterUniqueName(), Namespace: ns, }, Subjects: []rbacv1.Subject{ @@ -2572,7 +2571,7 @@ func (r *TestResources) NewRoleBinding(ns string) *rbacv1.RoleBinding { func (r *TestResources) OtherRoleBinding(ns string) *rbacv1.RoleBinding { return &rbacv1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: r.Name, + Name: r.getClusterUniqueName(), Namespace: ns, Labels: map[string]string{ "test": "label", @@ -2693,6 +2692,14 @@ func (r *TestResources) NewNamespace() *corev1.Namespace { } } +func (r *TestResources) NewOtherNamespace(name string) *corev1.Namespace { + return &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } +} + func (r *TestResources) NewNamespaceWithSCCSupGroups() *corev1.Namespace { ns := r.NewNamespace() ns.Annotations = map[string]string{ @@ -2908,3 +2915,11 @@ func (r *TestResources) getClusterUniqueName() string { } return prefix + r.clusterUniqueSuffix() } + +func (r *TestResources) getClusterUniqueNameForCA() string { + prefix := "cryostat-ca-" + if r.ClusterScoped { + prefix = "clustercryostat-ca-" + } + return prefix + r.clusterUniqueSuffix() +} diff --git a/internal/webhooks/cryostat_webhook.go b/internal/webhooks/cryostat_webhook.go new file mode 100644 index 000000000..64da3fa40 --- /dev/null +++ b/internal/webhooks/cryostat_webhook.go @@ -0,0 +1,44 @@ +// 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 webhooks + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +// log is for logging in this package. +var cryostatlog = logf.Log.WithName("cryostat-resource") + +// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create + +//+kubebuilder:webhook:path=/mutate-operator-cryostat-io-v1beta2-cryostat,mutating=true,failurePolicy=fail,sideEffects=None,groups=operator.cryostat.io,resources=cryostats,verbs=create;update,versions=v1beta2,name=mcryostat.kb.io,admissionReviewVersions=v1 + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-operator-cryostat-io-v1beta2-cryostat,mutating=false,failurePolicy=fail,sideEffects=None,groups=operator.cryostat.io,resources=cryostats,verbs=create;update,versions=v1beta2,name=vcryostat.kb.io,admissionReviewVersions=v1 + +func SetupWebhookWithManager(mgr ctrl.Manager, apiType runtime.Object) error { + return ctrl.NewWebhookManagedBy(mgr). + For(apiType). + WithValidator(&CryostatValidator{ + Client: mgr.GetClient(), + Log: &cryostatlog, + }). + WithDefaulter(&cryostatDefaulter{ + log: &cryostatlog, + }). + Complete() +} diff --git a/internal/webhooks/defaulter.go b/internal/webhooks/defaulter.go new file mode 100644 index 000000000..f58292625 --- /dev/null +++ b/internal/webhooks/defaulter.go @@ -0,0 +1,46 @@ +// 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 webhooks + +import ( + "context" + "fmt" + + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +type cryostatDefaulter struct { + log *logr.Logger +} + +var _ admission.CustomDefaulter = &cryostatDefaulter{} + +// Default applies default values to a Cryostat +func (r *cryostatDefaulter) Default(ctx context.Context, obj runtime.Object) error { + cr, ok := obj.(*operatorv1beta2.Cryostat) + if !ok { + return fmt.Errorf("expected a Cryostat, but received a %T", obj) + } + r.log.Info("defaulting Cryostat", "name", cr.Name, "namespace", cr.Namespace) + + if cr.Spec.TargetNamespaces == nil { + r.log.Info("defaulting target namespaces", "name", cr.Name, "namespace", cr.Namespace) + cr.Spec.TargetNamespaces = []string{cr.Namespace} + } + return nil +} diff --git a/internal/webhooks/test/resources.go b/internal/webhooks/test/resources.go new file mode 100644 index 000000000..b8839530e --- /dev/null +++ b/internal/webhooks/test/resources.go @@ -0,0 +1,72 @@ +// 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 ( + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "github.com/cryostatio/cryostat-operator/internal/test" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type WebhookTestResources struct { + *test.TestResources +} + +func (r *WebhookTestResources) NewWebhookTestServiceAccount() *corev1.ServiceAccount { + return &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name + "-webhook-test", + Namespace: r.Namespace, + }, + } +} + +func (r *WebhookTestResources) NewWebhookTestRole(namespace string) *rbacv1.Role { + return &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name + "-webhook-test", + Namespace: namespace, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{operatorv1beta2.GroupVersion.Group}, + Verbs: []string{"*"}, + Resources: []string{"cryostats"}, + }, + }, + } +} + +func (r *WebhookTestResources) NewWebhookTestRoleBinding(namespace string) *rbacv1.RoleBinding { + return &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name + "-webhook-test", + Namespace: namespace, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "Role", + Name: r.NewWebhookTestRole(namespace).Name, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: r.NewWebhookTestServiceAccount().Name, + }, + }, + } +} diff --git a/internal/webhooks/validator.go b/internal/webhooks/validator.go new file mode 100644 index 000000000..f1b3dd910 --- /dev/null +++ b/internal/webhooks/validator.go @@ -0,0 +1,128 @@ +// 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 webhooks + +import ( + "context" + "fmt" + + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" + "github.com/go-logr/logr" + authnv1 "k8s.io/api/authentication/v1" + authzv1 "k8s.io/api/authorization/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +type CryostatValidator struct { + Client client.Client + Log *logr.Logger +} + +var _ admission.CustomValidator = &CryostatValidator{} + +// ValidateCreate validates a Create operation on a Cryostat +func (r *CryostatValidator) ValidateCreate(ctx context.Context, obj runtime.Object) error { + return r.validate(ctx, obj, "create") +} + +// ValidateCreate validates an Update operation on a Cryostat +func (r *CryostatValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) error { + return r.validate(ctx, newObj, "update") +} + +// ValidateCreate validates a Delete operation on a Cryostat +func (r *CryostatValidator) ValidateDelete(ctx context.Context, obj runtime.Object) error { + // Nothing to validate on deletion + return nil +} + +type ErrNotPermitted struct { + operation string + namespace string +} + +func NewErrNotPermitted(operation string, namespace string) *ErrNotPermitted { + return &ErrNotPermitted{ + operation: operation, + namespace: namespace, + } +} + +func (e *ErrNotPermitted) Error() string { + return fmt.Sprintf("unable to %s Cryostat: user is not permitted to create a Cryostat in namespace %s", e.operation, e.namespace) +} + +var _ error = &ErrNotPermitted{} + +func (r *CryostatValidator) validate(ctx context.Context, obj runtime.Object, op string) error { + cr, ok := obj.(*operatorv1beta2.Cryostat) + if !ok { + return fmt.Errorf("expected a Cryostat, but received a %T", obj) + } + r.Log.Info(fmt.Sprintf("validate %s", op), "name", cr.Name, "namespace", cr.Namespace) + + // Look up the user who made this request + req, err := admission.RequestFromContext(ctx) + if err != nil { + return fmt.Errorf("no admission request found in context: %w", err) + } + userInfo := req.UserInfo + + // Check that for each target namespace, the user has permissions + // to create a Cryostat CR in that namespace + for _, namespace := range cr.Spec.TargetNamespaces { + sar := &authzv1.SubjectAccessReview{ + Spec: authzv1.SubjectAccessReviewSpec{ + User: userInfo.Username, + Groups: userInfo.Groups, + UID: userInfo.UID, + Extra: translateExtra(userInfo.Extra), + ResourceAttributes: &authzv1.ResourceAttributes{ + Namespace: namespace, + Verb: "create", + Group: operatorv1beta2.GroupVersion.Group, + Version: operatorv1beta2.GroupVersion.Version, + Resource: "cryostats", + }, + }, + } + + err := r.Client.Create(ctx, sar) + if err != nil { + return fmt.Errorf("failed to check permissions: %w", err) + } + + if !sar.Status.Allowed { + return NewErrNotPermitted(op, namespace) + } + } + + return nil +} + +func translateExtra(extra map[string]authnv1.ExtraValue) map[string]authzv1.ExtraValue { + var result map[string]authzv1.ExtraValue + if extra == nil { + return result + } + result = make(map[string]authzv1.ExtraValue, len(extra)) + for k, v := range extra { + result[k] = authzv1.ExtraValue(v) + } + + return result +} diff --git a/internal/webhooks/validator_test.go b/internal/webhooks/validator_test.go new file mode 100644 index 000000000..584976ac0 --- /dev/null +++ b/internal/webhooks/validator_test.go @@ -0,0 +1,199 @@ +// 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 webhooks_test + +import ( + "fmt" + "strconv" + + "github.com/cryostatio/cryostat-operator/internal/controllers/model" + "github.com/cryostatio/cryostat-operator/internal/test" + "github.com/cryostatio/cryostat-operator/internal/webhooks" + webhooktests "github.com/cryostatio/cryostat-operator/internal/webhooks/test" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" + 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 validatorTestInput struct { + client ctrlclient.Client + validator *webhooks.CryostatValidator + objs []ctrlclient.Object + *webhooktests.WebhookTestResources +} + +var _ = Describe("CryostatValidator", func() { + var t *validatorTestInput + var otherNS string + count := 0 + + namespaceWithSuffix := func(name string) string { + return name + "-" + strconv.Itoa(count) + } + + BeforeEach(func() { + ns := namespaceWithSuffix("test") + otherNS = namespaceWithSuffix("other") + t = &validatorTestInput{ + WebhookTestResources: &webhooktests.WebhookTestResources{ + TestResources: &test.TestResources{ + Name: "cryostat", + Namespace: ns, + TargetNamespaces: []string{ + ns, otherNS, + }, + }, + }, + } + t.objs = []ctrlclient.Object{ + t.NewNamespace(), t.NewOtherNamespace(otherNS), + } + }) + + JustBeforeEach(func() { + logger := zap.New() + logf.SetLogger(logger) + + t.client = k8sClient + t.validator = &webhooks.CryostatValidator{ + Client: k8sClient, + Log: &logger, + } + + 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("authorized user", func() { + var cr *model.CryostatInstance + + BeforeEach(func() { + cr = t.NewCryostat() + }) + + Context("creates a Cryostat", func() { + It("should allow the request", func() { + err := t.client.Create(ctx, cr.Object) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + Context("updates a Cryostat", func() { + BeforeEach(func() { + t.objs = append(t.objs, cr.Object) + }) + + It("should allow the request", func() { + err := t.client.Update(ctx, cr.Object) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + Context("deletes a Cryostat", func() { + BeforeEach(func() { + t.objs = append(t.objs, cr.Object) + }) + + It("should allow the request", func() { + err := t.client.Delete(ctx, cr.Object) + Expect(err).ToNot(HaveOccurred()) + }) + }) + }) + + Context("unauthorized user", func() { + var cr *model.CryostatInstance + var sa *corev1.ServiceAccount + var saClient ctrlclient.Client + + BeforeEach(func() { + cr = t.NewCryostat() + sa = t.NewWebhookTestServiceAccount() + t.objs = append(t.objs, + sa, + t.NewWebhookTestRole(t.Namespace), + t.NewWebhookTestRoleBinding(t.Namespace), + ) + }) + + JustBeforeEach(func() { + config := rest.CopyConfig(cfg) + config.Impersonate = rest.ImpersonationConfig{ + UserName: fmt.Sprintf("system:serviceaccount:%s:%s", sa.Namespace, sa.Name), + } + client, err := ctrlclient.New(config, ctrlclient.Options{Scheme: k8sScheme}) + Expect(err).ToNot(HaveOccurred()) + saClient = client + }) + + Context("creates a Cryostat", func() { + It("should deny the request", func() { + err := saClient.Create(ctx, cr.Object) + Expect(err).To((HaveOccurred())) + expectErrNotPermitted(err, "create", otherNS) + }) + }) + + Context("updates a Cryostat", func() { + BeforeEach(func() { + t.objs = append(t.objs, cr.Object) + }) + + It("should deny the request", func() { + err := saClient.Update(ctx, cr.Object) + Expect(err).To((HaveOccurred())) + expectErrNotPermitted(err, "update", otherNS) + }) + }) + + Context("deletes a Cryostat", func() { + BeforeEach(func() { + t.objs = append(t.objs, cr.Object) + }) + + It("should allow the request", func() { + err := saClient.Delete(ctx, cr.Object) + Expect(err).ToNot(HaveOccurred()) + }) + }) + }) + +}) + +func expectErrNotPermitted(actual error, op string, namespace string) { + expectedErr := webhooks.NewErrNotPermitted(op, namespace) + Expect(kerrors.IsForbidden(actual)).To(BeTrue(), "expected Forbidden API error") + Expect(kerrors.ReasonForError(actual)).To(Equal(metav1.StatusReason(expectedErr.Error()))) +} diff --git a/internal/webhooks/webhook_suite_test.go b/internal/webhooks/webhook_suite_test.go new file mode 100644 index 000000000..7d7dca37f --- /dev/null +++ b/internal/webhooks/webhook_suite_test.go @@ -0,0 +1,137 @@ +// 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 webhooks_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/webhooks" + 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" +) + +// 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 + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "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, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + err = webhooks.SetupWebhookWithManager(mgr, &operatorv1beta2.Cryostat{}) + 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()) +}) From 1613624702b462adfe03d65339a2357d03e1be6e Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 15 Feb 2024 12:13:35 -0800 Subject: [PATCH 04/53] feat(discovery): discovery port name/number options for v1betav2 (#733) * feat(discovery): discovery port name/number options for v1betav2 * fix(conversion): add missing conversion to betav1 --- api/v1beta1/cryostat_conversion.go | 12 ++++- api/v1beta1/cryostat_conversion_test.go | 4 ++ api/v1beta2/cryostat_types.go | 16 ++++++ api/v1beta2/zz_generated.deepcopy.go | 12 ++++- ...yostat-operator.clusterserviceversion.yaml | 54 +++++++++++++++++-- ...operator.cryostat.io_clustercryostats.yaml | 21 ++++++++ .../operator.cryostat.io_cryostats.yaml | 21 ++++++++ ...operator.cryostat.io_clustercryostats.yaml | 21 ++++++++ .../bases/operator.cryostat.io_cryostats.yaml | 21 ++++++++ ...yostat-operator.clusterserviceversion.yaml | 48 +++++++++++++++++ internal/test/conversion.go | 18 +++++++ internal/test/resources.go | 4 +- 12 files changed, 244 insertions(+), 8 deletions(-) diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index bf6a7d73d..fd818f608 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -269,7 +269,11 @@ func convertTargetDiscoveryTo(srcOpts *TargetDiscoveryOptions) *operatorv1beta2. var dstOpts *operatorv1beta2.TargetDiscoveryOptions if srcOpts != nil { dstOpts = &operatorv1beta2.TargetDiscoveryOptions{ - BuiltInDiscoveryDisabled: srcOpts.BuiltInDiscoveryDisabled, + BuiltInDiscoveryDisabled: srcOpts.BuiltInDiscoveryDisabled, + DisableBuiltInPortNames: srcOpts.DisableBuiltInPortNames, + DiscoveryPortNames: srcOpts.DiscoveryPortNames, + DisableBuiltInPortNumbers: srcOpts.DisableBuiltInPortNumbers, + DiscoveryPortNumbers: srcOpts.DiscoveryPortNumbers, } } return dstOpts @@ -551,7 +555,11 @@ func convertTargetDiscoveryFrom(srcOpts *operatorv1beta2.TargetDiscoveryOptions) var dstOpts *TargetDiscoveryOptions if srcOpts != nil { dstOpts = &TargetDiscoveryOptions{ - BuiltInDiscoveryDisabled: srcOpts.BuiltInDiscoveryDisabled, + BuiltInDiscoveryDisabled: srcOpts.BuiltInDiscoveryDisabled, + DisableBuiltInPortNames: srcOpts.DisableBuiltInPortNames, + DiscoveryPortNames: srcOpts.DiscoveryPortNames, + DisableBuiltInPortNumbers: srcOpts.DisableBuiltInPortNumbers, + DiscoveryPortNumbers: srcOpts.DiscoveryPortNumbers, } } return dstOpts diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go index 37b78304c..ae9129692 100644 --- a/api/v1beta1/cryostat_conversion_test.go +++ b/api/v1beta1/cryostat_conversion_test.go @@ -128,6 +128,10 @@ func tableEntries() []TableEntry { (*test.TestResources).NewCryostatWithAuthProperties), Entry("built-in discovery disabled", (*test.TestResources).NewCryostatWithBuiltInDiscoveryDisabledV1Beta1, (*test.TestResources).NewCryostatWithBuiltInDiscoveryDisabled), + Entry("discovery port custom config", (*test.TestResources).NewCryostatWithDiscoveryPortConfigV1Beta1, + (*test.TestResources).NewCryostatWithDiscoveryPortConfig), + Entry("discovery port config disabled", (*test.TestResources).NewCryostatWithBuiltInPortConfigDisabledV1Beta1, + (*test.TestResources).NewCryostatWithBuiltInPortConfigDisabled), Entry("JMX cache options", (*test.TestResources).NewCryostatWithJmxCacheOptionsSpecV1Beta1, (*test.TestResources).NewCryostatWithJmxCacheOptionsSpec), Entry("WS connections", (*test.TestResources).NewCryostatWithWsConnectionsSpecV1Beta1, diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 1fc0d947d..22fbeeae3 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -548,6 +548,22 @@ type TargetDiscoveryOptions struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable Built-in Discovery",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} BuiltInDiscoveryDisabled bool `json:"builtInDiscoveryDisabled,omitempty"` + // When true, the Cryostat application will use the default port name jfr-jmx to look for JMX connectable targets. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable Built-in Port Names",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + DisableBuiltInPortNames bool `json:"disableBuiltInPortNames,omitempty"` + // List of port names that the Cryostat application should look for in order to consider a target as JMX connectable. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true"} + DiscoveryPortNames []string `json:"discoveryPortNames,omitempty"` + // When true, the Cryostat application will use the default port number 9091 to look for JMX connectable targets. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable Built-in Port Numbers",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + DisableBuiltInPortNumbers bool `json:"disableBuiltInPortNumbers,omitempty"` + // List of port numbers that the Cryostat application should look for in order to consider a target as JMX connectable. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true"} + DiscoveryPortNumbers []int32 `json:"discoveryPortNumbers,omitempty"` } // JmxCredentialsDatabaseOptions provides configuration options to the Cryostat application's credentials database. diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index c1850c2d1..570167226 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -340,7 +340,7 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { if in.TargetDiscoveryOptions != nil { in, out := &in.TargetDiscoveryOptions, &out.TargetDiscoveryOptions *out = new(TargetDiscoveryOptions) - **out = **in + (*in).DeepCopyInto(*out) } if in.JmxCredentialsDatabaseOptions != nil { in, out := &in.JmxCredentialsDatabaseOptions, &out.JmxCredentialsDatabaseOptions @@ -865,6 +865,16 @@ func (in *StorageConfiguration) DeepCopy() *StorageConfiguration { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TargetDiscoveryOptions) DeepCopyInto(out *TargetDiscoveryOptions) { *out = *in + if in.DiscoveryPortNames != nil { + in, out := &in.DiscoveryPortNames, &out.DiscoveryPortNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.DiscoveryPortNumbers != nil { + in, out := &in.DiscoveryPortNumbers, &out.DiscoveryPortNumbers + *out = make([]int32, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetDiscoveryOptions. diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 83d78572a..f7cf6fee5 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -100,7 +100,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-02-12T22:09:00Z" + createdAt: "2024-02-14T20:36:04Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -490,11 +490,35 @@ spec: displayName: Target Discovery Options path: targetDiscoveryOptions - description: When true, the Cryostat application will disable the built-in - discovery mechanisms. Defaults to false + discovery mechanisms. Defaults to false. displayName: Disable Built-in Discovery path: targetDiscoveryOptions.builtInDiscoveryDisabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + name jfr-jmx to look for JMX connectable targets. + displayName: Disable Built-in Port Names + path: targetDiscoveryOptions.disableBuiltInPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + number 9091 to look for JMX connectable targets. + displayName: Disable Built-in Port Numbers + path: targetDiscoveryOptions.disableBuiltInPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: List of port names that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Names + path: targetDiscoveryOptions.discoveryPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true + - description: List of port numbers that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Numbers + path: targetDiscoveryOptions.discoveryPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - description: List of TLS certificates to trust when connecting to targets. displayName: Trusted TLS Certificates path: trustedCertSecrets @@ -900,6 +924,30 @@ spec: path: targetDiscoveryOptions.builtInDiscoveryDisabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + name jfr-jmx to look for JMX connectable targets. + displayName: Disable Built-in Port Names + path: targetDiscoveryOptions.disableBuiltInPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + number 9091 to look for JMX connectable targets. + displayName: Disable Built-in Port Numbers + path: targetDiscoveryOptions.disableBuiltInPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: List of port names that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Names + path: targetDiscoveryOptions.discoveryPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true + - description: List of port numbers that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Numbers + path: targetDiscoveryOptions.discoveryPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - description: List of TLS certificates to trust when connecting to targets. displayName: Trusted TLS Certificates path: trustedCertSecrets @@ -1693,7 +1741,7 @@ spec: displayName: Target Discovery Options path: targetDiscoveryOptions - description: When true, the Cryostat application will disable the built-in - discovery mechanisms. Defaults to false. + discovery mechanisms. Defaults to false displayName: Disable Built-in Discovery path: targetDiscoveryOptions.builtInDiscoveryDisabled x-descriptors: diff --git a/bundle/manifests/operator.cryostat.io_clustercryostats.yaml b/bundle/manifests/operator.cryostat.io_clustercryostats.yaml index b117234a9..831ebbc1c 100644 --- a/bundle/manifests/operator.cryostat.io_clustercryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_clustercryostats.yaml @@ -9355,6 +9355,27 @@ spec: description: When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false type: boolean + disableBuiltInPortNames: + description: When true, the Cryostat application will use the + default port name jfr-jmx to look for JMX connectable targets. + type: boolean + disableBuiltInPortNumbers: + description: When true, the Cryostat application will use the + default port number 9091 to look for JMX connectable targets. + type: boolean + discoveryPortNames: + description: List of port names that the Cryostat application + should look for in order to consider a target as JMX connectable. + items: + type: string + type: array + discoveryPortNumbers: + description: List of port numbers that the Cryostat application + should look for in order to consider a target as JMX connectable. + items: + format: int32 + type: integer + type: array type: object targetNamespaces: description: 'List of namespaces whose workloads Cryostat should be diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 25ebf2503..347253aa9 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -9332,6 +9332,27 @@ spec: description: When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false type: boolean + disableBuiltInPortNames: + description: When true, the Cryostat application will use the + default port name jfr-jmx to look for JMX connectable targets. + type: boolean + disableBuiltInPortNumbers: + description: When true, the Cryostat application will use the + default port number 9091 to look for JMX connectable targets. + type: boolean + discoveryPortNames: + description: List of port names that the Cryostat application + should look for in order to consider a target as JMX connectable. + items: + type: string + type: array + discoveryPortNumbers: + description: List of port numbers that the Cryostat application + should look for in order to consider a target as JMX connectable. + items: + format: int32 + type: integer + type: array type: object targetNamespaces: description: 'List of namespaces whose workloads Cryostat should be diff --git a/config/crd/bases/operator.cryostat.io_clustercryostats.yaml b/config/crd/bases/operator.cryostat.io_clustercryostats.yaml index d92d831dc..29e232ec9 100644 --- a/config/crd/bases/operator.cryostat.io_clustercryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_clustercryostats.yaml @@ -9345,6 +9345,27 @@ spec: description: When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false type: boolean + disableBuiltInPortNames: + description: When true, the Cryostat application will use the + default port name jfr-jmx to look for JMX connectable targets. + type: boolean + disableBuiltInPortNumbers: + description: When true, the Cryostat application will use the + default port number 9091 to look for JMX connectable targets. + type: boolean + discoveryPortNames: + description: List of port names that the Cryostat application + should look for in order to consider a target as JMX connectable. + items: + type: string + type: array + discoveryPortNumbers: + description: List of port numbers that the Cryostat application + should look for in order to consider a target as JMX connectable. + items: + format: int32 + type: integer + type: array type: object targetNamespaces: description: 'List of namespaces whose workloads Cryostat should be diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 5de7ef336..af307be48 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -9322,6 +9322,27 @@ spec: description: When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false type: boolean + disableBuiltInPortNames: + description: When true, the Cryostat application will use the + default port name jfr-jmx to look for JMX connectable targets. + type: boolean + disableBuiltInPortNumbers: + description: When true, the Cryostat application will use the + default port number 9091 to look for JMX connectable targets. + type: boolean + discoveryPortNames: + description: List of port names that the Cryostat application + should look for in order to consider a target as JMX connectable. + items: + type: string + type: array + discoveryPortNumbers: + description: List of port numbers that the Cryostat application + should look for in order to consider a target as JMX connectable. + items: + format: int32 + type: integer + type: array type: object targetNamespaces: description: 'List of namespaces whose workloads Cryostat should be diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 3c3207178..42891093d 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -399,6 +399,30 @@ spec: path: targetDiscoveryOptions.builtInDiscoveryDisabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + name jfr-jmx to look for JMX connectable targets. + displayName: Disable Built-in Port Names + path: targetDiscoveryOptions.disableBuiltInPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + number 9091 to look for JMX connectable targets. + displayName: Disable Built-in Port Numbers + path: targetDiscoveryOptions.disableBuiltInPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: List of port names that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Names + path: targetDiscoveryOptions.discoveryPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true + - description: List of port numbers that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Numbers + path: targetDiscoveryOptions.discoveryPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - description: List of TLS certificates to trust when connecting to targets. displayName: Trusted TLS Certificates path: trustedCertSecrets @@ -1202,6 +1226,30 @@ spec: path: targetDiscoveryOptions.builtInDiscoveryDisabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + name jfr-jmx to look for JMX connectable targets. + displayName: Disable Built-in Port Names + path: targetDiscoveryOptions.disableBuiltInPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: When true, the Cryostat application will use the default port + number 9091 to look for JMX connectable targets. + displayName: Disable Built-in Port Numbers + path: targetDiscoveryOptions.disableBuiltInPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: List of port names that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Names + path: targetDiscoveryOptions.discoveryPortNames + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true + - description: List of port numbers that the Cryostat application should look + for in order to consider a target as JMX connectable. + displayName: Discovery Port Numbers + path: targetDiscoveryOptions.discoveryPortNumbers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - description: List of TLS certificates to trust when connecting to targets. displayName: Trusted TLS Certificates path: trustedCertSecrets diff --git a/internal/test/conversion.go b/internal/test/conversion.go index b1167a327..ab123ddd3 100644 --- a/internal/test/conversion.go +++ b/internal/test/conversion.go @@ -445,6 +445,24 @@ func (r *TestResources) NewCryostatWithBuiltInDiscoveryDisabledV1Beta1() *operat return cr } +func (r *TestResources) NewCryostatWithDiscoveryPortConfigV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.TargetDiscoveryOptions = &operatorv1beta1.TargetDiscoveryOptions{ + DiscoveryPortNames: []string{"custom-port-name", "another-custom-port-name"}, + DiscoveryPortNumbers: []int32{9092, 9090}, + } + return cr +} + +func (r *TestResources) NewCryostatWithBuiltInPortConfigDisabledV1Beta1() *operatorv1beta1.Cryostat { + cr := r.NewCryostatV1Beta1() + cr.Spec.TargetDiscoveryOptions = &operatorv1beta1.TargetDiscoveryOptions{ + DisableBuiltInPortNames: true, + DisableBuiltInPortNumbers: true, + } + return cr +} + func (r *TestResources) NewCryostatWithJmxCacheOptionsSpecV1Beta1() *operatorv1beta1.Cryostat { cr := r.NewCryostatV1Beta1() cr.Spec.JmxCacheOptions = &operatorv1beta1.JmxCacheOptions{ diff --git a/internal/test/resources.go b/internal/test/resources.go index b2883741d..e12902889 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -551,7 +551,7 @@ func (r *TestResources) NewCryostatWithBuiltInDiscoveryDisabled() *model.Cryosta func (r *TestResources) NewCryostatWithDiscoveryPortConfig() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.TargetDiscoveryOptions = &operatorv1beta1.TargetDiscoveryOptions{ + cr.Spec.TargetDiscoveryOptions = &operatorv1beta2.TargetDiscoveryOptions{ DiscoveryPortNames: []string{"custom-port-name", "another-custom-port-name"}, DiscoveryPortNumbers: []int32{9092, 9090}, } @@ -560,7 +560,7 @@ func (r *TestResources) NewCryostatWithDiscoveryPortConfig() *model.CryostatInst func (r *TestResources) NewCryostatWithBuiltInPortConfigDisabled() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.TargetDiscoveryOptions = &operatorv1beta1.TargetDiscoveryOptions{ + cr.Spec.TargetDiscoveryOptions = &operatorv1beta2.TargetDiscoveryOptions{ DisableBuiltInPortNames: true, DisableBuiltInPortNumbers: true, } From 5b66ff149faf5a687a8384360a5ea7b134dcba29 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Tue, 20 Feb 2024 11:45:06 -0500 Subject: [PATCH 05/53] chore(api): remove ClusterCryostat CRD (#737) * chore(api): remove ClusterCryostat CRD * Update config.md * Delete docs/multi-namespace.md * Add RoleBinding finalizer tests --- Makefile | 14 +- PROJECT | 20 - api/v1beta1/clustercryostat_conversion.go | 62 - api/v1beta1/clustercryostat_types.go | 81 - api/v1beta1/zz_generated.deepcopy.go | 101 - api/v1beta2/clustercryostat_conversion.go | 24 - api/v1beta2/clustercryostat_types.go | 70 - api/v1beta2/cryostat_types.go | 4 +- api/v1beta2/zz_generated.deepcopy.go | 91 - ...yostat-operator.clusterserviceversion.yaml | 1093 +- ...operator.cryostat.io_clustercryostats.yaml | 9505 ----------------- .../operator.cryostat.io_cryostats.yaml | 10 +- ...operator.cryostat.io_clustercryostats.yaml | 9489 ---------------- .../bases/operator.cryostat.io_cryostats.yaml | 10 +- config/crd/kustomization.yaml | 3 - .../cainjection_in_clustercryostats.yaml | 7 - .../patches/webhook_in_clustercryostats.yaml | 16 - ...yostat-operator.clusterserviceversion.yaml | 842 +- config/manifests/targetNamespaces_patch.yaml | 32 - config/rbac/clustercryostat_editor_role.yaml | 24 - config/rbac/clustercryostat_viewer_role.yaml | 20 - config/rbac/role.yaml | 20 - config/samples/kustomization.yaml | 2 - .../operator_v1beta1_clustercryostat.yaml | 16 - .../operator_v1beta2_clustercryostat.yaml | 16 - docs/config.md | 19 + docs/multi-namespace.md | 72 - .../controllers/clustercryostat_controller.go | 104 - .../clustercryostat_controller_test.go | 33 - internal/controllers/cryostat_controller.go | 16 + .../controllers/cryostat_controller_test.go | 1 - internal/controllers/model/instance.go | 32 +- internal/controllers/reconciler.go | 33 +- internal/controllers/reconciler_test.go | 219 +- internal/main.go | 13 +- internal/test/resources.go | 43 +- 36 files changed, 246 insertions(+), 21911 deletions(-) delete mode 100644 api/v1beta1/clustercryostat_conversion.go delete mode 100644 api/v1beta1/clustercryostat_types.go delete mode 100644 api/v1beta2/clustercryostat_conversion.go delete mode 100644 api/v1beta2/clustercryostat_types.go delete mode 100644 bundle/manifests/operator.cryostat.io_clustercryostats.yaml delete mode 100644 config/crd/bases/operator.cryostat.io_clustercryostats.yaml delete mode 100644 config/crd/patches/cainjection_in_clustercryostats.yaml delete mode 100644 config/crd/patches/webhook_in_clustercryostats.yaml delete mode 100644 config/rbac/clustercryostat_editor_role.yaml delete mode 100644 config/rbac/clustercryostat_viewer_role.yaml delete mode 100644 config/samples/operator_v1beta1_clustercryostat.yaml delete mode 100644 config/samples/operator_v1beta2_clustercryostat.yaml delete mode 100644 docs/multi-namespace.md delete mode 100644 internal/controllers/clustercryostat_controller.go delete mode 100644 internal/controllers/clustercryostat_controller_test.go diff --git a/Makefile b/Makefile index 4dbf7bfb8..df9c88915 100644 --- a/Makefile +++ b/Makefile @@ -468,7 +468,6 @@ endif .PHONY: undeploy undeploy: ## Undeploy controller from the configured cluster in ~/.kube/config. - $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f config/samples/operator_v1beta1_cryostat.yaml - - $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f config/samples/operator_v1beta1_clustercryostat.yaml - $(KUSTOMIZE) build $(KUSTOMIZE_DIR) | $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f - .PHONY: deploy_bundle @@ -495,19 +494,8 @@ undeploy_bundle: operator-sdk ## Undeploy the controller in the bundle format wi .PHONY: create_cryostat_cr create_cryostat_cr: destroy_cryostat_cr ## Create a namespaced Cryostat instance. - $(CLUSTER_CLIENT) create -f config/samples/operator_v1beta1_cryostat.yaml - -.PHONY: create_clustercryostat_cr -create_clustercryostat_cr: destroy_clustercryostat_cr ## Create a cluster-wide Cryostat instance. - target_ns_json=$$(jq -nc '$$ARGS.positional' --args -- $(TARGET_NAMESPACES)) && \ - $(CLUSTER_CLIENT) patch -f config/samples/operator_v1beta1_clustercryostat.yaml --local=true --type=merge \ - -p "{\"spec\": {\"installNamespace\": \"$(DEPLOY_NAMESPACE)\", \"targetNamespaces\": $$target_ns_json}}" -o yaml | \ - $(CLUSTER_CLIENT) apply -f - + $(CLUSTER_CLIENT) create -f config/samples/operator_v1beta2_cryostat.yaml .PHONY: destroy_cryostat_cr destroy_cryostat_cr: ## Delete a namespaced Cryostat instance. - $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f config/samples/operator_v1beta1_cryostat.yaml - -.PHONY: destroy_clustercryostat_cr -destroy_clustercryostat_cr: ## Delete a cluster-wide Cryostat instance. - - $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f config/samples/operator_v1beta1_clustercryostat.yaml diff --git a/PROJECT b/PROJECT index 9c30663a2..8b0b7c1f3 100644 --- a/PROJECT +++ b/PROJECT @@ -19,14 +19,6 @@ resources: kind: Cryostat path: github.com/cryostatio/cryostat-operator/api/v1beta1 version: v1beta1 -- api: - crdVersion: v1 - namespaced: false - domain: cryostat.io - group: operator - kind: ClusterCryostat - path: github.com/cryostatio/cryostat-operator/api/v1beta1 - version: v1beta1 - api: crdVersion: v1 namespaced: true @@ -41,16 +33,4 @@ resources: defaulting: true validation: true webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: false - controller: true - domain: cryostat.io - group: operator - kind: ClusterCryostat - path: github.com/cryostatio/cryostat-operator/api/v1beta2 - version: v1beta2 - webhooks: - conversion: true - webhookVersion: v1 version: "3" diff --git a/api/v1beta1/clustercryostat_conversion.go b/api/v1beta1/clustercryostat_conversion.go deleted file mode 100644 index cb7cb194c..000000000 --- a/api/v1beta1/clustercryostat_conversion.go +++ /dev/null @@ -1,62 +0,0 @@ -// 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 v1beta1 - -import ( - operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" - "sigs.k8s.io/controller-runtime/pkg/conversion" -) - -// TODO Remove this file with ClusterCryostat CRD - -var _ conversion.Convertible = &ClusterCryostat{} - -// ConvertTo converts this ClusterCryostat to the Hub version (v1beta2). -func (src *ClusterCryostat) ConvertTo(dstRaw conversion.Hub) error { - dst := dstRaw.(*operatorv1beta2.ClusterCryostat) - - // Copy ObjectMeta as-is - dst.ObjectMeta = src.ObjectMeta - - // Convert existing Spec fields - convertSpecTo(&src.Spec.CryostatSpec, &dst.Spec.CryostatSpec) - dst.Spec.InstallNamespace = src.Spec.InstallNamespace - dst.Spec.TargetNamespaces = src.Spec.TargetNamespaces - - // Convert existing Status fields - convertStatusTo(&src.Status.CryostatStatus, &dst.Status.CryostatStatus) - dst.Status.TargetNamespaces = src.Spec.TargetNamespaces - - return nil -} - -// ConvertFrom converts from the Hub version (v1beta2) to this version. -func (dst *ClusterCryostat) ConvertFrom(srcRaw conversion.Hub) error { - src := srcRaw.(*operatorv1beta2.ClusterCryostat) - - // Copy ObjectMeta as-is - dst.ObjectMeta = src.ObjectMeta - - // Convert existing Spec fields - convertSpecFrom(&src.Spec.CryostatSpec, &dst.Spec.CryostatSpec) - dst.Spec.InstallNamespace = src.Spec.InstallNamespace - dst.Spec.TargetNamespaces = src.Spec.TargetNamespaces - - // Convert existing Status fields - convertStatusFrom(&src.Status.CryostatStatus, &dst.Status.CryostatStatus) - dst.Status.TargetNamespaces = src.Spec.TargetNamespaces - - return nil -} diff --git a/api/v1beta1/clustercryostat_types.go b/api/v1beta1/clustercryostat_types.go deleted file mode 100644 index 6628164a5..000000000 --- a/api/v1beta1/clustercryostat_types.go +++ /dev/null @@ -1,81 +0,0 @@ -// 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 v1beta1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// ClusterCryostatSpec defines the desired state of ClusterCryostat. -type ClusterCryostatSpec struct { - // Namespace where Cryostat should be installed. - // On multi-tenant clusters, we strongly suggest installing Cryostat into - // its own namespace. - // +operator-sdk:csv:customresourcedefinitions:type=spec,order=1,xDescriptors={"urn:alm:descriptor:io.kubernetes:Namespace"} - InstallNamespace string `json:"installNamespace"` - // List of namespaces whose workloads Cryostat should be - // permitted to access and profile. Warning: All Cryostat users will be able to create and manage - // recordings for workloads in the listed namespaces. - // More details: https://github.com/cryostatio/cryostat-operator/blob/v2.3.0/docs/multi-namespace.md#data-isolation - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,order=2 - TargetNamespaces []string `json:"targetNamespaces,omitempty"` - // +operator-sdk:csv:customresourcedefinitions:type=spec - CryostatSpec `json:",inline"` -} - -// ClusterCryostatStatus defines the observed state of ClusterCryostat. -type ClusterCryostatStatus struct { - // List of namespaces that Cryostat has been configured - // and authorized to access and profile. - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=status,order=3 - TargetNamespaces []string `json:"targetNamespaces,omitempty"` - // +operator-sdk:csv:customresourcedefinitions:type=status - CryostatStatus `json:",inline"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +kubebuilder:resource:path=clustercryostats,scope=Cluster - -// ClusterCryostat allows you to install Cryostat for multiple namespaces or cluster-wide. -// It contains configuration options for controlling the Deployment of the Cryostat -// application and its related components. -// A ClusterCryostat or Cryostat instance must be created to instruct the operator -// to deploy the Cryostat application. -// +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} -// +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` -// +kubebuilder:printcolumn:name="Grafana Secret",type=string,JSONPath=`.status.grafanaSecret` -type ClusterCryostat struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ClusterCryostatSpec `json:"spec,omitempty"` - Status ClusterCryostatStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// ClusterCryostatList contains a list of ClusterCryostat -type ClusterCryostatList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ClusterCryostat `json:"items"` -} - -func init() { - SchemeBuilder.Register(&ClusterCryostat{}, &ClusterCryostatList{}) -} diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index b4ca832b2..a4098fcbd 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -91,107 +91,6 @@ func (in *CertificateSecret) DeepCopy() *CertificateSecret { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterCryostat) DeepCopyInto(out *ClusterCryostat) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostat. -func (in *ClusterCryostat) DeepCopy() *ClusterCryostat { - if in == nil { - return nil - } - out := new(ClusterCryostat) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterCryostat) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterCryostatList) DeepCopyInto(out *ClusterCryostatList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ClusterCryostat, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatList. -func (in *ClusterCryostatList) DeepCopy() *ClusterCryostatList { - if in == nil { - return nil - } - out := new(ClusterCryostatList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterCryostatList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterCryostatSpec) DeepCopyInto(out *ClusterCryostatSpec) { - *out = *in - if in.TargetNamespaces != nil { - in, out := &in.TargetNamespaces, &out.TargetNamespaces - *out = make([]string, len(*in)) - copy(*out, *in) - } - in.CryostatSpec.DeepCopyInto(&out.CryostatSpec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatSpec. -func (in *ClusterCryostatSpec) DeepCopy() *ClusterCryostatSpec { - if in == nil { - return nil - } - out := new(ClusterCryostatSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterCryostatStatus) DeepCopyInto(out *ClusterCryostatStatus) { - *out = *in - if in.TargetNamespaces != nil { - in, out := &in.TargetNamespaces, &out.TargetNamespaces - *out = make([]string, len(*in)) - copy(*out, *in) - } - in.CryostatStatus.DeepCopyInto(&out.CryostatStatus) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatStatus. -func (in *ClusterCryostatStatus) DeepCopy() *ClusterCryostatStatus { - if in == nil { - return nil - } - out := new(ClusterCryostatStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CoreServiceConfig) DeepCopyInto(out *CoreServiceConfig) { *out = *in diff --git a/api/v1beta2/clustercryostat_conversion.go b/api/v1beta2/clustercryostat_conversion.go deleted file mode 100644 index 2f1604627..000000000 --- a/api/v1beta2/clustercryostat_conversion.go +++ /dev/null @@ -1,24 +0,0 @@ -// 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 v1beta2 - -import "sigs.k8s.io/controller-runtime/pkg/conversion" - -// TODO Remove this file with ClusterCryostat CRD - -var _ conversion.Hub = &ClusterCryostat{} - -// Hub marks this type as a conversion hub. -func (*ClusterCryostat) Hub() {} diff --git a/api/v1beta2/clustercryostat_types.go b/api/v1beta2/clustercryostat_types.go deleted file mode 100644 index 686a970fa..000000000 --- a/api/v1beta2/clustercryostat_types.go +++ /dev/null @@ -1,70 +0,0 @@ -// 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 v1beta2 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// ClusterCryostatSpec defines the desired state of ClusterCryostat. -type ClusterCryostatSpec struct { - // Namespace where Cryostat should be installed. - // On multi-tenant clusters, we strongly suggest installing Cryostat into - // its own namespace. - // +operator-sdk:csv:customresourcedefinitions:type=spec,order=1,xDescriptors={"urn:alm:descriptor:io.kubernetes:Namespace"} - InstallNamespace string `json:"installNamespace"` - // +operator-sdk:csv:customresourcedefinitions:type=spec - CryostatSpec `json:",inline"` -} - -// ClusterCryostatStatus defines the observed state of ClusterCryostat. -type ClusterCryostatStatus struct { - // +operator-sdk:csv:customresourcedefinitions:type=status - CryostatStatus `json:",inline"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +kubebuilder:storageversion -// +kubebuilder:resource:path=clustercryostats,scope=Cluster - -// ClusterCryostat allows you to install Cryostat for multiple namespaces or cluster-wide. -// It contains configuration options for controlling the Deployment of the Cryostat -// application and its related components. -// A ClusterCryostat or Cryostat instance must be created to instruct the operator -// to deploy the Cryostat application. -// +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} -// +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` -// +kubebuilder:printcolumn:name="Grafana Secret",type=string,JSONPath=`.status.grafanaSecret` -type ClusterCryostat struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ClusterCryostatSpec `json:"spec,omitempty"` - Status ClusterCryostatStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// ClusterCryostatList contains a list of ClusterCryostat -type ClusterCryostatList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ClusterCryostat `json:"items"` -} - -func init() { - SchemeBuilder.Register(&ClusterCryostat{}, &ClusterCryostatList{}) -} diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 22fbeeae3..e0e1f5279 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -431,10 +431,10 @@ type JmxCacheOptions struct { // +kubebuilder:storageversion // +kubebuilder:resource:path=cryostats,scope=Namespaced -// Cryostat allows you to install Cryostat for a single namespace. +// Cryostat allows you to install Cryostat for a single namespace, or multiple namespaces. // It contains configuration options for controlling the Deployment of the Cryostat // application and its related components. -// A ClusterCryostat or Cryostat instance must be created to instruct the operator +// A Cryostat instance must be created to instruct the operator // to deploy the Cryostat application. // +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} // +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 570167226..a8111e005 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -91,97 +91,6 @@ func (in *CertificateSecret) DeepCopy() *CertificateSecret { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterCryostat) DeepCopyInto(out *ClusterCryostat) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostat. -func (in *ClusterCryostat) DeepCopy() *ClusterCryostat { - if in == nil { - return nil - } - out := new(ClusterCryostat) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterCryostat) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterCryostatList) DeepCopyInto(out *ClusterCryostatList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ClusterCryostat, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatList. -func (in *ClusterCryostatList) DeepCopy() *ClusterCryostatList { - if in == nil { - return nil - } - out := new(ClusterCryostatList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterCryostatList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterCryostatSpec) DeepCopyInto(out *ClusterCryostatSpec) { - *out = *in - in.CryostatSpec.DeepCopyInto(&out.CryostatSpec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatSpec. -func (in *ClusterCryostatSpec) DeepCopy() *ClusterCryostatSpec { - if in == nil { - return nil - } - out := new(ClusterCryostatSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterCryostatStatus) DeepCopyInto(out *ClusterCryostatStatus) { - *out = *in - in.CryostatStatus.DeepCopyInto(&out.CryostatStatus) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCryostatStatus. -func (in *ClusterCryostatStatus) DeepCopy() *ClusterCryostatStatus { - if in == nil { - return nil - } - out := new(ClusterCryostatStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CoreServiceConfig) DeepCopyInto(out *CoreServiceConfig) { *out = *in diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index f7cf6fee5..5cb15f3da 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -6,989 +6,85 @@ metadata: [ { "apiVersion": "operator.cryostat.io/v1beta1", - "kind": "ClusterCryostat", - "metadata": { - "name": "clustercryostat-sample" - }, - "spec": { - "enableCertManager": true, - "eventTemplates": [], - "minimal": false, - "reportOptions": { - "replicas": 0 - }, - "storageOptions": { - "pvc": { - "annotations": {}, - "labels": {}, - "spec": {} - } - }, - "trustedCertSecrets": [] - } - }, - { - "apiVersion": "operator.cryostat.io/v1beta1", - "kind": "Cryostat", - "metadata": { - "name": "cryostat-sample" - }, - "spec": { - "enableCertManager": true, - "eventTemplates": [], - "minimal": false, - "reportOptions": { - "replicas": 0 - }, - "storageOptions": { - "pvc": { - "annotations": {}, - "labels": {}, - "spec": {} - } - }, - "trustedCertSecrets": [] - } - }, - { - "apiVersion": "operator.cryostat.io/v1beta2", - "kind": "ClusterCryostat", - "metadata": { - "name": "clustercryostat-sample" - }, - "spec": { - "enableCertManager": true, - "eventTemplates": [], - "minimal": false, - "reportOptions": { - "replicas": 0 - }, - "storageOptions": { - "pvc": { - "annotations": {}, - "labels": {}, - "spec": {} - } - }, - "trustedCertSecrets": [] - } - }, - { - "apiVersion": "operator.cryostat.io/v1beta2", - "kind": "Cryostat", - "metadata": { - "name": "cryostat-sample" - }, - "spec": { - "enableCertManager": true, - "eventTemplates": [], - "minimal": false, - "reportOptions": { - "replicas": 0 - }, - "storageOptions": { - "pvc": { - "annotations": {}, - "labels": {}, - "spec": {} - } - }, - "trustedCertSecrets": [] - } - } - ] - capabilities: Seamless Upgrades - categories: Monitoring, Developer Tools - containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-02-14T20:36:04Z" - description: JVM monitoring and profiling tool - operatorframework.io/initialization-resource: |- - { - "apiVersion": "operator.cryostat.io/v1beta2", - "kind": "Cryostat", - "metadata": { - "name": "cryostat-sample" - }, - "spec": { - "enableCertManager": true, - "minimal": false, - "reportOptions": { - "replicas": 0 - } - } - } - operators.operatorframework.io/builder: operator-sdk-v1.31.0 - operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 - repository: github.com/cryostatio/cryostat-operator - support: Cryostat Community - labels: - operatorframework.io/arch.amd64: supported - operatorframework.io/arch.arm64: supported - operatorframework.io/os.linux: supported - name: cryostat-operator.v2.5.0-dev - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: ClusterCryostat allows you to install Cryostat for multiple namespaces - or cluster-wide. It contains configuration options for controlling the Deployment - of the Cryostat application and its related components. A ClusterCryostat - or Cryostat instance must be created to instruct the operator to deploy the - Cryostat application. - displayName: Cluster Cryostat - kind: ClusterCryostat - name: clustercryostats.operator.cryostat.io - resources: - - kind: ConsoleLink - name: "" - version: v1 - - kind: Deployment - name: "" - version: v1 - - kind: Ingress - name: "" - version: v1 - - kind: PersistentVolumeClaim - name: "" - version: v1 - - kind: Route - name: "" - version: v1 - - kind: Secret - name: "" - version: v1 - - kind: Service - name: "" - version: v1 - specDescriptors: - - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - displayName: Install Namespace - path: installNamespace - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - - description: 'List of namespaces whose workloads Cryostat should be permitted - to access and profile. Warning: All Cryostat users will be able to create - and manage recordings for workloads in the listed namespaces. More details: - https://github.com/cryostatio/cryostat-operator/blob/v2.3.0/docs/multi-namespace.md#data-isolation' - displayName: Target Namespaces - path: targetNamespaces - - description: Use cert-manager to secure in-cluster communication between Cryostat - components. Requires cert-manager to be installed. - displayName: Enable cert-manager Integration - path: enableCertManager - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard - or JFR Data Source. - displayName: Minimal Deployment - path: minimal - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Override default authorization properties for Cryostat on OpenShift. - displayName: Authorization Properties - path: authProperties - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped - OAuth token. This ClusterRole should contain permissions for all Kubernetes - objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: ClusterRole Name - path: authProperties.clusterRoleName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ClusterRole - - description: Name of config map in the local namespace. - displayName: ConfigMap Name - path: authProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Filename within config map containing the resource mapping. - displayName: Filename - path: authProperties.filename - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. - displayName: Event Templates - path: eventTemplates - - description: Name of config map in the local namespace. - displayName: Config Map Name - path: eventTemplates[0].configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Options to customize the JMX target connections cache for the - Cryostat application. - displayName: JMX Connections Cache Options - path: jmxCacheOptions - - description: The maximum number of JMX connections to cache. Use `-1` for - an unlimited cache size (TTL expiration only). Defaults to `-1`. - displayName: Target Cache Size - path: jmxCacheOptions.targetCacheSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: The time to live (in seconds) for cached JMX connections. Defaults - to `10`. - displayName: Target Cache TTL - path: jmxCacheOptions.targetCacheTTL - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to configure the Cryostat application's credentials database. - displayName: Credentials Database Options - path: jmxCredentialsDatabaseOptions - - description: Name of the secret containing the password to encrypt credentials - database. - displayName: Database Secret Name - path: jmxCredentialsDatabaseOptions.databaseSecretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: The maximum number of WebSocket client connections allowed (minimum - 1, default unlimited). - displayName: Max WebSocket Connections - path: maxWsConnections - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to control how the operator exposes the application outside - of the cluster, such as using an Ingress or Route. - displayName: Network Options - path: networkOptions - - description: "Specifications for how to expose the Cryostat command service, - which serves the WebSocket command channel. \n Deprecated: CommandConfig - is no longer used." - displayName: Command Config - path: networkOptions.commandConfig - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:hidden - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.commandConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.commandConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.commandConfig.labels - - description: Specifications for how to expose the Cryostat service, which - serves the Cryostat application. - displayName: Core Config - path: networkOptions.coreConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.coreConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.coreConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.coreConfig.labels - - description: Specifications for how to expose Cryostat's Grafana service, - which serves the Grafana dashboard. - displayName: Grafana Config - path: networkOptions.grafanaConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.grafanaConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.grafanaConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.grafanaConfig.labels - - description: Options to configure the Cryostat deployments and pods metadata - displayName: Operand metadata - path: operandMetadata - - description: Options to configure the Cryostat deployments metadata - displayName: Deployments metadata - path: operandMetadata.deploymentMetadata - - description: Options to configure the Cryostat pods metadata - displayName: Pods metadata - path: operandMetadata.podMetadata - - description: Options to configure Cryostat Automated Report Analysis. - displayName: Report Options - path: reportOptions - - description: The number of report sidecar replica containers to deploy. Each - replica can service one report generation request at a time. - displayName: Replicas - path: reportOptions.replicas - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podCount - - description: The resources allocated to each sidecar replica. A replica with - more resources can handle larger input recordings and will process them - faster. - displayName: Resources - path: reportOptions.resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Options to configure scheduling for the reports deployment - displayName: Scheduling Options - path: reportOptions.schedulingOptions - - description: Affinity rules for scheduling Cryostat pods. - displayName: Affinity - path: reportOptions.schedulingOptions.affinity - - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - displayName: Node Affinity - path: reportOptions.schedulingOptions.affinity.nodeAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:nodeAffinity - - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - displayName: Pod Affinity - path: reportOptions.schedulingOptions.affinity.podAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAffinity - - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: - https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - displayName: Pod Anti Affinity - path: reportOptions.schedulingOptions.affinity.podAntiAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity - - description: 'Label selector used to schedule a Cryostat pod to a node. See: - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - displayName: Node Selector - path: reportOptions.schedulingOptions.nodeSelector - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node - - description: 'Tolerations to allow scheduling of Cryostat pods to tainted - nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - displayName: Tolerations - path: reportOptions.schedulingOptions.tolerations - - description: Options to configure the Security Contexts for the Cryostat report - generator. - displayName: Security Options - path: reportOptions.securityOptions - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: Security Context to apply to the Cryostat report generator pod. - displayName: Pod Security Context - path: reportOptions.securityOptions.podSecurityContext - - description: Security Context to apply to the Cryostat report generator container. - displayName: Reports Security Context - path: reportOptions.securityOptions.reportsSecurityContext - - description: When zero report sidecar replicas are requested, SubProcessMaxHeapSize - configures the maximum heap size of the basic subprocess report generator - in MiB. The default heap size is `200` (MiB). - displayName: Sub Process Max Heap Size - path: reportOptions.subProcessMaxHeapSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Resource requirements for the Cryostat deployment. - displayName: Resources - path: resources - - description: Resource requirements for the Cryostat application. If specifying - a memory limit, at least 768MiB is recommended. - displayName: Core Resources - path: resources.coreResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Resource requirements for the JFR Data Source container. - displayName: Data Source Resources - path: resources.dataSourceResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Resource requirements for the Grafana container. - displayName: Grafana Resources - path: resources.grafanaResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Options to configure scheduling for the Cryostat deployment - displayName: Scheduling Options - path: schedulingOptions - - description: Affinity rules for scheduling Cryostat pods. - displayName: Affinity - path: schedulingOptions.affinity - - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - displayName: Node Affinity - path: schedulingOptions.affinity.nodeAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:nodeAffinity - - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - displayName: Pod Affinity - path: schedulingOptions.affinity.podAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAffinity - - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: - https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - displayName: Pod Anti Affinity - path: schedulingOptions.affinity.podAntiAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity - - description: 'Label selector used to schedule a Cryostat pod to a node. See: - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - displayName: Node Selector - path: schedulingOptions.nodeSelector - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node - - description: 'Tolerations to allow scheduling of Cryostat pods to tainted - nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - displayName: Tolerations - path: schedulingOptions.tolerations - - description: Options to configure the Security Contexts for the Cryostat application. - displayName: Security Options - path: securityOptions - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: Security Context to apply to the Cryostat application container. - displayName: Core Security Context - path: securityOptions.coreSecurityContext - - description: Security Context to apply to the JFR Data Source container. - displayName: Data Source Security Context - path: securityOptions.dataSourceSecurityContext - - description: Security Context to apply to the Grafana container. - displayName: Grafana Security Context - path: securityOptions.grafanaSecurityContext - - description: Security Context to apply to the Cryostat pod. - displayName: Pod Security Context - path: securityOptions.podSecurityContext - - description: Options to customize the services created for the Cryostat application - and Grafana dashboard. - displayName: Service Options - path: serviceOptions - - description: Options to customize the storage for Flight Recordings and Templates. - displayName: Storage Options - path: storageOptions - - description: Configuration for an EmptyDir to be created by the operator instead - of a PVC. - displayName: Empty Dir - path: storageOptions.emptyDir - - description: When enabled, Cryostat will use EmptyDir volumes instead of a - Persistent Volume Claim. Any PVC configurations will be ignored. - displayName: Enabled - path: storageOptions.emptyDir.enabled - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Unless specified, the emptyDir volume will be mounted on the - same storage medium backing the node. Setting this field to "Memory" will - mount the emptyDir on a tmpfs (RAM-backed filesystem). - displayName: Medium - path: storageOptions.emptyDir.medium - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true - - description: The maximum memory limit for the emptyDir. Default is unbounded. - displayName: Size Limit - path: storageOptions.emptyDir.sizeLimit - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true - - description: Configuration for the Persistent Volume Claim to be created by - the operator. - displayName: PVC - path: storageOptions.pvc - - description: Spec for a Persistent Volume Claim, whose options will override - the defaults used by the operator. Unless overriden, the PVC will be created - with the default Storage Class and 500MiB of storage. Once the operator - has created the PVC, changes to this field have no effect. - displayName: Spec - path: storageOptions.pvc.spec - - description: Options to configure the Cryostat application's target discovery - mechanisms. - displayName: Target Discovery Options - path: targetDiscoveryOptions - - description: When true, the Cryostat application will disable the built-in - discovery mechanisms. Defaults to false. - displayName: Disable Built-in Discovery - path: targetDiscoveryOptions.builtInDiscoveryDisabled - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - name jfr-jmx to look for JMX connectable targets. - displayName: Disable Built-in Port Names - path: targetDiscoveryOptions.disableBuiltInPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - number 9091 to look for JMX connectable targets. - displayName: Disable Built-in Port Numbers - path: targetDiscoveryOptions.disableBuiltInPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: List of port names that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Names - path: targetDiscoveryOptions.discoveryPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true - - description: List of port numbers that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Numbers - path: targetDiscoveryOptions.discoveryPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - - description: List of TLS certificates to trust when connecting to targets. - displayName: Trusted TLS Certificates - path: trustedCertSecrets - - description: Name of secret in the local namespace. - displayName: Secret Name - path: trustedCertSecrets[0].secretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: A namespace whose workloads Cryostat should be able to connect - and record - displayName: Target Namespace - path: targetNamespaces[0] - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - statusDescriptors: - - description: Address of the deployed Cryostat web application. - displayName: Application URL - path: applicationUrl - x-descriptors: - - urn:alm:descriptor:org.w3:link - - description: Name of the Secret containing the generated Grafana credentials. - displayName: Grafana Secret - path: grafanaSecret - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: List of namespaces that Cryostat has been configured and authorized - to access and profile. - displayName: Target Namespaces - path: targetNamespaces - - description: Conditions of the components managed by the Cryostat Operator. - displayName: Cryostat Conditions - path: conditions - x-descriptors: - - urn:alm:descriptor:io.kubernetes.conditions - - description: A namespace whose workloads Cryostat should be able to connect - and record - displayName: Target Namespace - path: targetNamespaces[0] - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - version: v1beta1 - - description: ClusterCryostat allows you to install Cryostat for multiple namespaces - or cluster-wide. It contains configuration options for controlling the Deployment - of the Cryostat application and its related components. A ClusterCryostat - or Cryostat instance must be created to instruct the operator to deploy the - Cryostat application. - displayName: Cluster Cryostat - kind: ClusterCryostat - name: clustercryostats.operator.cryostat.io - resources: - - kind: ConsoleLink - name: "" - version: v1 - - kind: Deployment - name: "" - version: v1 - - kind: Ingress - name: "" - version: v1 - - kind: PersistentVolumeClaim - name: "" - version: v1 - - kind: Route - name: "" - version: v1 - - kind: Secret - name: "" - version: v1 - - kind: Service - name: "" - version: v1 - specDescriptors: - - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - displayName: Install Namespace - path: installNamespace - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - - description: 'List of namespaces whose workloads Cryostat should be permitted - to access and profile. Defaults to this Cryostat''s namespace. Warning: - All Cryostat users will be able to create and manage recordings for workloads - in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' - displayName: Target Namespaces - path: targetNamespaces - - description: Use cert-manager to secure in-cluster communication between Cryostat - components. Requires cert-manager to be installed. - displayName: Enable cert-manager Integration - path: enableCertManager - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard - or JFR Data Source. - displayName: Minimal Deployment - path: minimal - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Override default authorization properties for Cryostat on OpenShift. - displayName: Authorization Properties - path: authProperties - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped - OAuth token. This ClusterRole should contain permissions for all Kubernetes - objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: ClusterRole Name - path: authProperties.clusterRoleName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ClusterRole - - description: Name of config map in the local namespace. - displayName: ConfigMap Name - path: authProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Filename within config map containing the resource mapping. - displayName: Filename - path: authProperties.filename - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. - displayName: Event Templates - path: eventTemplates - - description: Name of config map in the local namespace. - displayName: Config Map Name - path: eventTemplates[0].configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Options to customize the JMX target connections cache for the - Cryostat application. - displayName: JMX Connections Cache Options - path: jmxCacheOptions - - description: The maximum number of JMX connections to cache. Use `-1` for - an unlimited cache size (TTL expiration only). Defaults to `-1`. - displayName: Target Cache Size - path: jmxCacheOptions.targetCacheSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: The time to live (in seconds) for cached JMX connections. Defaults - to `10`. - displayName: Target Cache TTL - path: jmxCacheOptions.targetCacheTTL - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to configure the Cryostat application's credentials database. - displayName: Credentials Database Options - path: jmxCredentialsDatabaseOptions - - description: Name of the secret containing the password to encrypt credentials - database. - displayName: Database Secret Name - path: jmxCredentialsDatabaseOptions.databaseSecretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: The maximum number of WebSocket client connections allowed (minimum - 1, default unlimited). - displayName: Max WebSocket Connections - path: maxWsConnections - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to control how the operator exposes the application outside - of the cluster, such as using an Ingress or Route. - displayName: Network Options - path: networkOptions - - description: "Specifications for how to expose the Cryostat command service, - which serves the WebSocket command channel. \n Deprecated: CommandConfig - is no longer used." - displayName: Command Config - path: networkOptions.commandConfig - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:hidden - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.commandConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.commandConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.commandConfig.labels - - description: Specifications for how to expose the Cryostat service, which - serves the Cryostat application. - displayName: Core Config - path: networkOptions.coreConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.coreConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.coreConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.coreConfig.labels - - description: Specifications for how to expose Cryostat's Grafana service, - which serves the Grafana dashboard. - displayName: Grafana Config - path: networkOptions.grafanaConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.grafanaConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.grafanaConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.grafanaConfig.labels - - description: Options to configure the Cryostat deployments and pods metadata - displayName: Operand metadata - path: operandMetadata - - description: Options to configure the Cryostat deployments metadata - displayName: Deployments metadata - path: operandMetadata.deploymentMetadata - - description: Options to configure the Cryostat pods metadata - displayName: Pods metadata - path: operandMetadata.podMetadata - - description: Options to configure Cryostat Automated Report Analysis. - displayName: Report Options - path: reportOptions - - description: The number of report sidecar replica containers to deploy. Each - replica can service one report generation request at a time. - displayName: Replicas - path: reportOptions.replicas - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podCount - - description: The resources allocated to each sidecar replica. A replica with - more resources can handle larger input recordings and will process them - faster. - displayName: Resources - path: reportOptions.resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Options to configure scheduling for the reports deployment - displayName: Scheduling Options - path: reportOptions.schedulingOptions - - description: Affinity rules for scheduling Cryostat pods. - displayName: Affinity - path: reportOptions.schedulingOptions.affinity - - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - displayName: Node Affinity - path: reportOptions.schedulingOptions.affinity.nodeAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:nodeAffinity - - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - displayName: Pod Affinity - path: reportOptions.schedulingOptions.affinity.podAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAffinity - - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: - https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - displayName: Pod Anti Affinity - path: reportOptions.schedulingOptions.affinity.podAntiAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity - - description: 'Label selector used to schedule a Cryostat pod to a node. See: - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - displayName: Node Selector - path: reportOptions.schedulingOptions.nodeSelector - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node - - description: 'Tolerations to allow scheduling of Cryostat pods to tainted - nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - displayName: Tolerations - path: reportOptions.schedulingOptions.tolerations - - description: Options to configure the Security Contexts for the Cryostat report - generator. - displayName: Security Options - path: reportOptions.securityOptions - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: Security Context to apply to the Cryostat report generator pod. - displayName: Pod Security Context - path: reportOptions.securityOptions.podSecurityContext - - description: Security Context to apply to the Cryostat report generator container. - displayName: Reports Security Context - path: reportOptions.securityOptions.reportsSecurityContext - - description: When zero report sidecar replicas are requested, SubProcessMaxHeapSize - configures the maximum heap size of the basic subprocess report generator - in MiB. The default heap size is `200` (MiB). - displayName: Sub Process Max Heap Size - path: reportOptions.subProcessMaxHeapSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Resource requirements for the Cryostat deployment. - displayName: Resources - path: resources - - description: Resource requirements for the Cryostat application. If specifying - a memory limit, at least 768MiB is recommended. - displayName: Core Resources - path: resources.coreResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Resource requirements for the JFR Data Source container. - displayName: Data Source Resources - path: resources.dataSourceResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Resource requirements for the Grafana container. - displayName: Grafana Resources - path: resources.grafanaResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Options to configure scheduling for the Cryostat deployment - displayName: Scheduling Options - path: schedulingOptions - - description: Affinity rules for scheduling Cryostat pods. - displayName: Affinity - path: schedulingOptions.affinity - - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - displayName: Node Affinity - path: schedulingOptions.affinity.nodeAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:nodeAffinity - - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - displayName: Pod Affinity - path: schedulingOptions.affinity.podAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAffinity - - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: - https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - displayName: Pod Anti Affinity - path: schedulingOptions.affinity.podAntiAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity - - description: 'Label selector used to schedule a Cryostat pod to a node. See: - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - displayName: Node Selector - path: schedulingOptions.nodeSelector - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node - - description: 'Tolerations to allow scheduling of Cryostat pods to tainted - nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - displayName: Tolerations - path: schedulingOptions.tolerations - - description: Options to configure the Security Contexts for the Cryostat application. - displayName: Security Options - path: securityOptions - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: Security Context to apply to the Cryostat application container. - displayName: Core Security Context - path: securityOptions.coreSecurityContext - - description: Security Context to apply to the JFR Data Source container. - displayName: Data Source Security Context - path: securityOptions.dataSourceSecurityContext - - description: Security Context to apply to the Grafana container. - displayName: Grafana Security Context - path: securityOptions.grafanaSecurityContext - - description: Security Context to apply to the Cryostat pod. - displayName: Pod Security Context - path: securityOptions.podSecurityContext - - description: Options to customize the services created for the Cryostat application - and Grafana dashboard. - displayName: Service Options - path: serviceOptions - - description: Options to customize the storage for Flight Recordings and Templates. - displayName: Storage Options - path: storageOptions - - description: Configuration for an EmptyDir to be created by the operator instead - of a PVC. - displayName: Empty Dir - path: storageOptions.emptyDir - - description: When enabled, Cryostat will use EmptyDir volumes instead of a - Persistent Volume Claim. Any PVC configurations will be ignored. - displayName: Enabled - path: storageOptions.emptyDir.enabled - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Unless specified, the emptyDir volume will be mounted on the - same storage medium backing the node. Setting this field to "Memory" will - mount the emptyDir on a tmpfs (RAM-backed filesystem). - displayName: Medium - path: storageOptions.emptyDir.medium - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true - - description: The maximum memory limit for the emptyDir. Default is unbounded. - displayName: Size Limit - path: storageOptions.emptyDir.sizeLimit - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true - - description: Configuration for the Persistent Volume Claim to be created by - the operator. - displayName: PVC - path: storageOptions.pvc - - description: Spec for a Persistent Volume Claim, whose options will override - the defaults used by the operator. Unless overriden, the PVC will be created - with the default Storage Class and 500MiB of storage. Once the operator - has created the PVC, changes to this field have no effect. - displayName: Spec - path: storageOptions.pvc.spec - - description: Options to configure the Cryostat application's target discovery - mechanisms. - displayName: Target Discovery Options - path: targetDiscoveryOptions - - description: When true, the Cryostat application will disable the built-in - discovery mechanisms. Defaults to false - displayName: Disable Built-in Discovery - path: targetDiscoveryOptions.builtInDiscoveryDisabled - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - name jfr-jmx to look for JMX connectable targets. - displayName: Disable Built-in Port Names - path: targetDiscoveryOptions.disableBuiltInPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - number 9091 to look for JMX connectable targets. - displayName: Disable Built-in Port Numbers - path: targetDiscoveryOptions.disableBuiltInPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: List of port names that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Names - path: targetDiscoveryOptions.discoveryPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true - - description: List of port numbers that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Numbers - path: targetDiscoveryOptions.discoveryPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - - description: List of TLS certificates to trust when connecting to targets. - displayName: Trusted TLS Certificates - path: trustedCertSecrets - - description: Name of secret in the local namespace. - displayName: Secret Name - path: trustedCertSecrets[0].secretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: A namespace whose workloads Cryostat should be able to connect - and record - displayName: Target Namespace - path: targetNamespaces[0] - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - statusDescriptors: - - description: Address of the deployed Cryostat web application. - displayName: Application URL - path: applicationUrl - x-descriptors: - - urn:alm:descriptor:org.w3:link - - description: Name of the Secret containing the generated Grafana credentials. - displayName: Grafana Secret - path: grafanaSecret - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: List of namespaces that Cryostat has been configured and authorized - to access and profile. - displayName: Target Namespaces - path: targetNamespaces - - description: Conditions of the components managed by the Cryostat Operator. - displayName: Cryostat Conditions - path: conditions - x-descriptors: - - urn:alm:descriptor:io.kubernetes.conditions - - description: A namespace whose workloads Cryostat should be able to connect - and record - displayName: Target Namespace - path: targetNamespaces[0] - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - version: v1beta2 + "kind": "Cryostat", + "metadata": { + "name": "cryostat-sample" + }, + "spec": { + "enableCertManager": true, + "eventTemplates": [], + "minimal": false, + "reportOptions": { + "replicas": 0 + }, + "storageOptions": { + "pvc": { + "annotations": {}, + "labels": {}, + "spec": {} + } + }, + "trustedCertSecrets": [] + } + }, + { + "apiVersion": "operator.cryostat.io/v1beta2", + "kind": "Cryostat", + "metadata": { + "name": "cryostat-sample" + }, + "spec": { + "enableCertManager": true, + "eventTemplates": [], + "minimal": false, + "reportOptions": { + "replicas": 0 + }, + "storageOptions": { + "pvc": { + "annotations": {}, + "labels": {}, + "spec": {} + } + }, + "trustedCertSecrets": [] + } + } + ] + capabilities: Seamless Upgrades + categories: Monitoring, Developer Tools + containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev + createdAt: "2024-02-15T20:45:48Z" + description: JVM monitoring and profiling tool + operatorframework.io/initialization-resource: |- + { + "apiVersion": "operator.cryostat.io/v1beta2", + "kind": "Cryostat", + "metadata": { + "name": "cryostat-sample" + }, + "spec": { + "enableCertManager": true, + "minimal": false, + "reportOptions": { + "replicas": 0 + } + } + } + operators.operatorframework.io/builder: operator-sdk-v1.31.0 + operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + repository: github.com/cryostatio/cryostat-operator + support: Cryostat Community + labels: + operatorframework.io/arch.amd64: supported + operatorframework.io/arch.arm64: supported + operatorframework.io/os.linux: supported + name: cryostat-operator.v2.5.0-dev + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: - description: Cryostat allows you to install Cryostat for a single namespace. It contains configuration options for controlling the Deployment of the Cryostat application and its related components. A ClusterCryostat or Cryostat instance @@ -1389,10 +485,10 @@ spec: x-descriptors: - urn:alm:descriptor:io.kubernetes.conditions version: v1beta1 - - description: Cryostat allows you to install Cryostat for a single namespace. - It contains configuration options for controlling the Deployment of the Cryostat - application and its related components. A ClusterCryostat or Cryostat instance - must be created to instruct the operator to deploy the Cryostat application. + - description: Cryostat allows you to install Cryostat for a single namespace, + or multiple namespaces. It contains configuration options for controlling + the Deployment of the Cryostat application and its related components. A Cryostat + instance must be created to instruct the operator to deploy the Cryostat application. displayName: Cryostat kind: Cryostat name: cryostats.operator.cryostat.io @@ -1953,26 +1049,6 @@ spec: verbs: - delete - list - - apiGroups: - - operator.cryostat.io - resources: - - clustercryostats - verbs: - - '*' - - apiGroups: - - operator.cryostat.io - resources: - - clustercryostats/finalizers - verbs: - - update - - apiGroups: - - operator.cryostat.io - resources: - - clustercryostats/status - verbs: - - get - - patch - - update - apiGroups: - operator.cryostat.io resources: @@ -2197,10 +1273,9 @@ spec: - v1 containerPort: 443 conversionCRDs: - - clustercryostats.operator.cryostat.io - cryostats.operator.cryostat.io deploymentName: cryostat-operator-controller-manager - generateName: cclustercryostatscryostats.kb.io + generateName: ccryostats.kb.io sideEffects: None targetPort: 9443 type: ConversionWebhook diff --git a/bundle/manifests/operator.cryostat.io_clustercryostats.yaml b/bundle/manifests/operator.cryostat.io_clustercryostats.yaml deleted file mode 100644 index 831ebbc1c..000000000 --- a/bundle/manifests/operator.cryostat.io_clustercryostats.yaml +++ /dev/null @@ -1,9505 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: cryostat-operator-system/cryostat-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null - name: clustercryostats.operator.cryostat.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - name: cryostat-operator-webhook-service - namespace: cryostat-operator-system - path: /convert - conversionReviewVersions: - - v1 - group: operator.cryostat.io - names: - kind: ClusterCryostat - listKind: ClusterCryostatList - plural: clustercryostats - singular: clustercryostat - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .status.applicationUrl - name: Application URL - type: string - - jsonPath: .status.grafanaSecret - name: Grafana Secret - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: ClusterCryostat allows you to install Cryostat for multiple namespaces - or cluster-wide. It contains configuration options for controlling the Deployment - of the Cryostat application and its related components. A ClusterCryostat - or Cryostat instance must be created to instruct the operator to deploy - the Cryostat application. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ClusterCryostatSpec defines the desired state of ClusterCryostat. - properties: - authProperties: - description: Override default authorization properties for Cryostat - on OpenShift. - properties: - clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - type: string - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - clusterRoleName - - configMapName - - filename - type: object - enableCertManager: - description: Use cert-manager to secure in-cluster communication between - Cryostat components. Requires cert-manager to be installed. - type: boolean - eventTemplates: - description: List of Flight Recorder Event Templates to preconfigure - in Cryostat. - items: - description: A ConfigMap containing a .jfc template file. - properties: - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the template - file. - type: string - required: - - configMapName - - filename - type: object - type: array - installNamespace: - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - type: string - jmxCacheOptions: - description: Options to customize the JMX target connections cache - for the Cryostat application. - properties: - targetCacheSize: - description: The maximum number of JMX connections to cache. Use - `-1` for an unlimited cache size (TTL expiration only). Defaults - to `-1`. - format: int32 - minimum: -1 - type: integer - targetCacheTTL: - description: The time to live (in seconds) for cached JMX connections. - Defaults to `10`. - format: int32 - minimum: 1 - type: integer - type: object - jmxCredentialsDatabaseOptions: - description: Options to configure the Cryostat application's credentials - database. - properties: - databaseSecretName: - description: Name of the secret containing the password to encrypt - credentials database. - type: string - type: object - maxWsConnections: - description: The maximum number of WebSocket client connections allowed - (minimum 1, default unlimited). - format: int32 - minimum: 1 - type: integer - minimal: - description: Deploy a pared-down Cryostat instance with no Grafana - Dashboard or JFR Data Source. - type: boolean - networkOptions: - description: Options to control how the operator exposes the application - outside of the cluster, such as using an Ingress or Route. - properties: - commandConfig: - description: "Specifications for how to expose the Cryostat command - service, which serves the WebSocket command channel. \n Deprecated: - CommandConfig is no longer used." - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - coreConfig: - description: Specifications for how to expose the Cryostat service, - which serves the Cryostat application. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - grafanaConfig: - description: Specifications for how to expose Cryostat's Grafana - service, which serves the Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - type: object - operandMetadata: - description: Options to configure the Cryostat deployments and pods - metadata - properties: - deploymentMetadata: - description: Options to configure the Cryostat deployments metadata - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the resources during its - creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the resources during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - type: object - podMetadata: - description: Options to configure the Cryostat pods metadata - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the resources during its - creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the resources during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - type: object - type: object - reportOptions: - description: Options to configure Cryostat Automated Report Analysis. - properties: - replicas: - description: The number of report sidecar replica containers to - deploy. Each replica can service one report generation request - at a time. - format: int32 - type: integer - resources: - description: The resources allocated to each sidecar replica. - A replica with more resources can handle larger input recordings - and will process them faster. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - schedulingOptions: - description: Options to configure scheduling for the reports deployment - properties: - affinity: - description: Affinity rules for scheduling Cryostat pods. - properties: - nodeAffinity: - description: 'Node affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term - matches all objects with implicit weight 0 (i.e. - it's a no-op). A null preferred scheduling term - matches no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching - the corresponding nodeSelectorTerm, in the - range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to an update), the system may or may not try - to eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector - terms. The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: 'Pod affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of - resources, in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to a pod label update), the system may or may - not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, - i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: 'Pod anti-affinity scheduling rules for a - Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to - the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of - resources, in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - anti-affinity requirements specified by this field - cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may - or may not try to eventually evict the pod from - its node. When there are multiple elements, the - lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod - to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat - pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. - type: string - key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period - of time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the value should - be empty, otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the - Cryostat report generator. - properties: - podSecurityContext: - description: Security Context to apply to the Cryostat report - generator pod. - properties: - fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow - the Kubelet to change the ownership of that volume to - be owned by the pod: \n 1. The owning GID will be the - FSGroup 2. The setgid bit is set (new files created - in the volume will be owned by FSGroup) 3. The permission - bits are OR'd with rw-rw---- \n If unset, the Kubelet - will not modify the ownership and permissions of any - volume. Note that this field cannot be set when spec.os.name - is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of - changing ownership and permission of the volume before - being exposed inside Pod. This field will only apply - to volume types which support fsGroup based ownership(and - permissions). It will have no effect on ephemeral volume - types such as: secret, configmaps and emptydir. Valid - values are "OnRootMismatch" and "Always". If not specified, - "Always" is used. Note that this field cannot be set - when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all - containers. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp 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 - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID, the fsGroup (if specified), and group memberships - defined in the container image for the uid of the container - process. If unspecified, no additional groups are added - to any container. Note that group memberships defined - in the container image for the uid of the container - process are still effective, even if they are not included - in this list. Note that this field cannot be set when - spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls - used for the pod. Pods with unsupported sysctls (by - the container runtime) might fail to launch. Note that - this field cannot be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be - set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options within a - container's SecurityContext will be used. If set in - both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - reportsSecurityContext: - description: Security Context to apply to the Cryostat report - generator container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag - will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that this - field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name - is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - type: object - subProcessMaxHeapSize: - description: When zero report sidecar replicas are requested, - SubProcessMaxHeapSize configures the maximum heap size of the - basic subprocess report generator in MiB. The default heap size - is `200` (MiB). - format: int32 - type: integer - type: object - resources: - description: Resource requirements for the Cryostat deployment. - properties: - coreResources: - description: Resource requirements for the Cryostat application. - If specifying a memory limit, at least 768MiB is recommended. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - dataSourceResources: - description: Resource requirements for the JFR Data Source container. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - grafanaResources: - description: Resource requirements for the Grafana container. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - type: object - schedulingOptions: - description: Options to configure scheduling for the Cryostat deployment - properties: - affinity: - description: Affinity rules for scheduling Cryostat pods. - properties: - nodeAffinity: - description: 'Node affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated with - the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: 'Pod affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: 'Pod anti-affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod to - a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat pods - to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the Cryostat - application. - properties: - coreSecurityContext: - description: Security Context to apply to the Cryostat application - container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - dataSourceSecurityContext: - description: Security Context to apply to the JFR Data Source - container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - grafanaSecurityContext: - description: Security Context to apply to the Grafana container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - podSecurityContext: - description: Security Context to apply to the Cryostat pod. - properties: - fsGroup: - description: "A special supplemental group that applies to - all containers in a pod. Some volume types allow the Kubelet - to change the ownership of that volume to be owned by the - pod: \n 1. The owning GID will be the FSGroup 2. The setgid - bit is set (new files created in the volume will be owned - by FSGroup) 3. The permission bits are OR'd with rw-rw---- - \n If unset, the Kubelet will not modify the ownership and - permissions of any volume. Note that this field cannot be - set when spec.os.name is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will - have no effect on ephemeral volume types such as: secret, - configmaps and emptydir. Valid values are "OnRootMismatch" - and "Always". If not specified, "Always" is used. Note that - this field cannot be set when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field - cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is - windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - SecurityContext. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp 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 defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's primary - GID, the fsGroup (if specified), and group memberships defined - in the container image for the uid of the container process. - If unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image - for the uid of the container process are still effective, - even if they are not included in this list. Note that this - field cannot be set when spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. Note that this field cannot - be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - type: object - serviceOptions: - description: Options to customize the services created for the Cryostat - application and Grafana dashboard. - properties: - coreConfig: - description: Specification for the service responsible for the - Cryostat application. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Cryostat application - service. Defaults to 8181. - format: int32 - type: integer - jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - grafanaConfig: - description: Specification for the service responsible for the - Cryostat Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Grafana dashboard service. - Defaults to 3000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - reportsConfig: - description: Specification for the service responsible for the - cryostat-reports sidecars. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the cryostat-reports service. - Defaults to 10000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - type: object - storageOptions: - description: Options to customize the storage for Flight Recordings - and Templates. - properties: - emptyDir: - description: Configuration for an EmptyDir to be created by the - operator instead of a PVC. - properties: - enabled: - description: When enabled, Cryostat will use EmptyDir volumes - instead of a Persistent Volume Claim. Any PVC configurations - will be ignored. - type: boolean - medium: - description: Unless specified, the emptyDir volume will be - mounted on the same storage medium backing the node. Setting - this field to "Memory" will mount the emptyDir on a tmpfs - (RAM-backed filesystem). - type: string - sizeLimit: - description: The maximum memory limit for the emptyDir. Default - is unbounded. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - type: string - type: object - pvc: - description: Configuration for the Persistent Volume Claim to - be created by the operator. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Persistent Volume Claim - during its creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Persistent Volume Claim - during its creation. The label with key "app" is reserved - for use by the operator. - type: object - spec: - description: Spec for a Persistent Volume Claim, whose options - will override the defaults used by the operator. Unless - overriden, the PVC will be created with the default Storage - Class and 500MiB of storage. Once the operator has created - the PVC, changes to this field have no effect. - properties: - accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the 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. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: selector is a label query over volumes to - consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: '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 - volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference to the - PersistentVolume backing this claim. - type: string - type: object - type: object - type: object - targetDiscoveryOptions: - description: Options to configure the Cryostat application's target - discovery mechanisms. - properties: - builtInDiscoveryDisabled: - description: When true, the Cryostat application will disable - the built-in discovery mechanisms. Defaults to false. - type: boolean - disableBuiltInPortNames: - description: When true, the Cryostat application will use the - default port name jfr-jmx to look for JMX connectable targets. - type: boolean - disableBuiltInPortNumbers: - description: When true, the Cryostat application will use the - default port number 9091 to look for JMX connectable targets. - type: boolean - discoveryPortNames: - description: List of port names that the Cryostat application - should look for in order to consider a target as JMX connectable. - items: - type: string - type: array - discoveryPortNumbers: - description: List of port numbers that the Cryostat application - should look for in order to consider a target as JMX connectable. - items: - format: int32 - type: integer - type: array - type: object - targetNamespaces: - description: 'List of namespaces whose workloads Cryostat should be - permitted to access and profile. Warning: All Cryostat users will - be able to create and manage recordings for workloads in the listed - namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.3.0/docs/multi-namespace.md#data-isolation' - items: - type: string - type: array - trustedCertSecrets: - description: List of TLS certificates to trust when connecting to - targets. - items: - properties: - certificateKey: - description: Key within secret containing the certificate. - type: string - secretName: - description: Name of secret in the local namespace. - type: string - required: - - secretName - type: object - type: array - required: - - installNamespace - - minimal - type: object - status: - description: ClusterCryostatStatus defines the observed state of ClusterCryostat. - properties: - applicationUrl: - description: Address of the deployed Cryostat web application. - type: string - conditions: - description: Conditions of the components managed by the Cryostat - Operator. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - grafanaSecret: - description: Name of the Secret containing the generated Grafana credentials. - type: string - targetNamespaces: - description: List of namespaces that Cryostat has been configured - and authorized to access and profile. - items: - type: string - type: array - required: - - applicationUrl - type: object - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .status.applicationUrl - name: Application URL - type: string - - jsonPath: .status.grafanaSecret - name: Grafana Secret - type: string - name: v1beta2 - schema: - openAPIV3Schema: - description: ClusterCryostat allows you to install Cryostat for multiple namespaces - or cluster-wide. It contains configuration options for controlling the Deployment - of the Cryostat application and its related components. A ClusterCryostat - or Cryostat instance must be created to instruct the operator to deploy - the Cryostat application. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ClusterCryostatSpec defines the desired state of ClusterCryostat. - properties: - authProperties: - description: Override default authorization properties for Cryostat - on OpenShift. - properties: - clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - type: string - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - clusterRoleName - - configMapName - - filename - type: object - enableCertManager: - description: Use cert-manager to secure in-cluster communication between - Cryostat components. Requires cert-manager to be installed. - type: boolean - eventTemplates: - description: List of Flight Recorder Event Templates to preconfigure - in Cryostat. - items: - description: A ConfigMap containing a .jfc template file. - properties: - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the template - file. - type: string - required: - - configMapName - - filename - type: object - type: array - installNamespace: - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - type: string - jmxCacheOptions: - description: Options to customize the JMX target connections cache - for the Cryostat application. - properties: - targetCacheSize: - description: The maximum number of JMX connections to cache. Use - `-1` for an unlimited cache size (TTL expiration only). Defaults - to `-1`. - format: int32 - minimum: -1 - type: integer - targetCacheTTL: - description: The time to live (in seconds) for cached JMX connections. - Defaults to `10`. - format: int32 - minimum: 1 - type: integer - type: object - jmxCredentialsDatabaseOptions: - description: Options to configure the Cryostat application's credentials - database. - properties: - databaseSecretName: - description: Name of the secret containing the password to encrypt - credentials database. - type: string - type: object - maxWsConnections: - description: The maximum number of WebSocket client connections allowed - (minimum 1, default unlimited). - format: int32 - minimum: 1 - type: integer - minimal: - description: Deploy a pared-down Cryostat instance with no Grafana - Dashboard or JFR Data Source. - type: boolean - networkOptions: - description: Options to control how the operator exposes the application - outside of the cluster, such as using an Ingress or Route. - properties: - commandConfig: - description: "Specifications for how to expose the Cryostat command - service, which serves the WebSocket command channel. \n Deprecated: - CommandConfig is no longer used." - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - coreConfig: - description: Specifications for how to expose the Cryostat service, - which serves the Cryostat application. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - grafanaConfig: - description: Specifications for how to expose Cryostat's Grafana - service, which serves the Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - type: object - operandMetadata: - description: Options to configure the Cryostat deployments and pods - metadata - properties: - deploymentMetadata: - description: Options to configure the Cryostat deployments metadata - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the resources during its - creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the resources during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - type: object - podMetadata: - description: Options to configure the Cryostat pods metadata - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the resources during its - creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the resources during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - type: object - type: object - reportOptions: - description: Options to configure Cryostat Automated Report Analysis. - properties: - replicas: - description: The number of report sidecar replica containers to - deploy. Each replica can service one report generation request - at a time. - format: int32 - type: integer - resources: - description: The resources allocated to each sidecar replica. - A replica with more resources can handle larger input recordings - and will process them faster. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - schedulingOptions: - description: Options to configure scheduling for the reports deployment - properties: - affinity: - description: Affinity rules for scheduling Cryostat pods. - properties: - nodeAffinity: - description: 'Node affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term - matches all objects with implicit weight 0 (i.e. - it's a no-op). A null preferred scheduling term - matches no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching - the corresponding nodeSelectorTerm, in the - range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to an update), the system may or may not try - to eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector - terms. The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: 'Pod affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of - resources, in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to a pod label update), the system may or may - not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, - i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: 'Pod anti-affinity scheduling rules for a - Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to - the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of - resources, in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - anti-affinity requirements specified by this field - cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may - or may not try to eventually evict the pod from - its node. When there are multiple elements, the - lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod - to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat - pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. - type: string - key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period - of time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the value should - be empty, otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the - Cryostat report generator. - properties: - podSecurityContext: - description: Security Context to apply to the Cryostat report - generator pod. - properties: - fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow - the Kubelet to change the ownership of that volume to - be owned by the pod: \n 1. The owning GID will be the - FSGroup 2. The setgid bit is set (new files created - in the volume will be owned by FSGroup) 3. The permission - bits are OR'd with rw-rw---- \n If unset, the Kubelet - will not modify the ownership and permissions of any - volume. Note that this field cannot be set when spec.os.name - is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of - changing ownership and permission of the volume before - being exposed inside Pod. This field will only apply - to volume types which support fsGroup based ownership(and - permissions). It will have no effect on ephemeral volume - types such as: secret, configmaps and emptydir. Valid - values are "OnRootMismatch" and "Always". If not specified, - "Always" is used. Note that this field cannot be set - when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all - containers. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp 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 - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID, the fsGroup (if specified), and group memberships - defined in the container image for the uid of the container - process. If unspecified, no additional groups are added - to any container. Note that group memberships defined - in the container image for the uid of the container - process are still effective, even if they are not included - in this list. Note that this field cannot be set when - spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls - used for the pod. Pods with unsupported sysctls (by - the container runtime) might fail to launch. Note that - this field cannot be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be - set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options within a - container's SecurityContext will be used. If set in - both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - reportsSecurityContext: - description: Security Context to apply to the Cryostat report - generator container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag - will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that this - field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name - is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - type: object - subProcessMaxHeapSize: - description: When zero report sidecar replicas are requested, - SubProcessMaxHeapSize configures the maximum heap size of the - basic subprocess report generator in MiB. The default heap size - is `200` (MiB). - format: int32 - type: integer - type: object - resources: - description: Resource requirements for the Cryostat deployment. - properties: - coreResources: - description: Resource requirements for the Cryostat application. - If specifying a memory limit, at least 768MiB is recommended. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - dataSourceResources: - description: Resource requirements for the JFR Data Source container. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - grafanaResources: - description: Resource requirements for the Grafana container. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - type: object - schedulingOptions: - description: Options to configure scheduling for the Cryostat deployment - properties: - affinity: - description: Affinity rules for scheduling Cryostat pods. - properties: - nodeAffinity: - description: 'Node affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated with - the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: 'Pod affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: 'Pod anti-affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod to - a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat pods - to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the Cryostat - application. - properties: - coreSecurityContext: - description: Security Context to apply to the Cryostat application - container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - dataSourceSecurityContext: - description: Security Context to apply to the JFR Data Source - container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - grafanaSecurityContext: - description: Security Context to apply to the Grafana container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - podSecurityContext: - description: Security Context to apply to the Cryostat pod. - properties: - fsGroup: - description: "A special supplemental group that applies to - all containers in a pod. Some volume types allow the Kubelet - to change the ownership of that volume to be owned by the - pod: \n 1. The owning GID will be the FSGroup 2. The setgid - bit is set (new files created in the volume will be owned - by FSGroup) 3. The permission bits are OR'd with rw-rw---- - \n If unset, the Kubelet will not modify the ownership and - permissions of any volume. Note that this field cannot be - set when spec.os.name is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will - have no effect on ephemeral volume types such as: secret, - configmaps and emptydir. Valid values are "OnRootMismatch" - and "Always". If not specified, "Always" is used. Note that - this field cannot be set when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field - cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is - windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - SecurityContext. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp 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 defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's primary - GID, the fsGroup (if specified), and group memberships defined - in the container image for the uid of the container process. - If unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image - for the uid of the container process are still effective, - even if they are not included in this list. Note that this - field cannot be set when spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. Note that this field cannot - be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - type: object - serviceOptions: - description: Options to customize the services created for the Cryostat - application and Grafana dashboard. - properties: - coreConfig: - description: Specification for the service responsible for the - Cryostat application. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Cryostat application - service. Defaults to 8181. - format: int32 - type: integer - jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - grafanaConfig: - description: Specification for the service responsible for the - Cryostat Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Grafana dashboard service. - Defaults to 3000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - reportsConfig: - description: Specification for the service responsible for the - cryostat-reports sidecars. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the cryostat-reports service. - Defaults to 10000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - type: object - storageOptions: - description: Options to customize the storage for Flight Recordings - and Templates. - properties: - emptyDir: - description: Configuration for an EmptyDir to be created by the - operator instead of a PVC. - properties: - enabled: - description: When enabled, Cryostat will use EmptyDir volumes - instead of a Persistent Volume Claim. Any PVC configurations - will be ignored. - type: boolean - medium: - description: Unless specified, the emptyDir volume will be - mounted on the same storage medium backing the node. Setting - this field to "Memory" will mount the emptyDir on a tmpfs - (RAM-backed filesystem). - type: string - sizeLimit: - description: The maximum memory limit for the emptyDir. Default - is unbounded. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - type: string - type: object - pvc: - description: Configuration for the Persistent Volume Claim to - be created by the operator. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Persistent Volume Claim - during its creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Persistent Volume Claim - during its creation. The label with key "app" is reserved - for use by the operator. - type: object - spec: - description: Spec for a Persistent Volume Claim, whose options - will override the defaults used by the operator. Unless - overriden, the PVC will be created with the default Storage - Class and 500MiB of storage. Once the operator has created - the PVC, changes to this field have no effect. - properties: - accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the 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. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: selector is a label query over volumes to - consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: '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 - volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference to the - PersistentVolume backing this claim. - type: string - type: object - type: object - type: object - targetDiscoveryOptions: - description: Options to configure the Cryostat application's target - discovery mechanisms. - properties: - builtInDiscoveryDisabled: - description: When true, the Cryostat application will disable - the built-in discovery mechanisms. Defaults to false - type: boolean - disableBuiltInPortNames: - description: When true, the Cryostat application will use the - default port name jfr-jmx to look for JMX connectable targets. - type: boolean - disableBuiltInPortNumbers: - description: When true, the Cryostat application will use the - default port number 9091 to look for JMX connectable targets. - type: boolean - discoveryPortNames: - description: List of port names that the Cryostat application - should look for in order to consider a target as JMX connectable. - items: - type: string - type: array - discoveryPortNumbers: - description: List of port numbers that the Cryostat application - should look for in order to consider a target as JMX connectable. - items: - format: int32 - type: integer - type: array - type: object - targetNamespaces: - description: 'List of namespaces whose workloads Cryostat should be - permitted to access and profile. Defaults to this Cryostat''s namespace. - Warning: All Cryostat users will be able to create and manage recordings - for workloads in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' - items: - type: string - type: array - trustedCertSecrets: - description: List of TLS certificates to trust when connecting to - targets. - items: - properties: - certificateKey: - description: Key within secret containing the certificate. - type: string - secretName: - description: Name of secret in the local namespace. - type: string - required: - - secretName - type: object - type: array - required: - - installNamespace - - minimal - type: object - status: - description: ClusterCryostatStatus defines the observed state of ClusterCryostat. - properties: - applicationUrl: - description: Address of the deployed Cryostat web application. - type: string - conditions: - description: Conditions of the components managed by the Cryostat - Operator. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - grafanaSecret: - description: Name of the Secret containing the generated Grafana credentials. - type: string - targetNamespaces: - description: List of namespaces that Cryostat has been configured - and authorized to access and profile. - items: - type: string - type: array - required: - - applicationUrl - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 347253aa9..26a20df2b 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -4752,11 +4752,11 @@ spec: name: v1beta2 schema: openAPIV3Schema: - description: Cryostat allows you to install Cryostat for a single namespace. - It contains configuration options for controlling the Deployment of the - Cryostat application and its related components. A ClusterCryostat or Cryostat - instance must be created to instruct the operator to deploy the Cryostat - application. + description: Cryostat allows you to install Cryostat for a single namespace, + or multiple namespaces. It contains configuration options for controlling + the Deployment of the Cryostat application and its related components. A + Cryostat instance must be created to instruct the operator to deploy the + Cryostat application. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation diff --git a/config/crd/bases/operator.cryostat.io_clustercryostats.yaml b/config/crd/bases/operator.cryostat.io_clustercryostats.yaml deleted file mode 100644 index 29e232ec9..000000000 --- a/config/crd/bases/operator.cryostat.io_clustercryostats.yaml +++ /dev/null @@ -1,9489 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null - name: clustercryostats.operator.cryostat.io -spec: - group: operator.cryostat.io - names: - kind: ClusterCryostat - listKind: ClusterCryostatList - plural: clustercryostats - singular: clustercryostat - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .status.applicationUrl - name: Application URL - type: string - - jsonPath: .status.grafanaSecret - name: Grafana Secret - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: ClusterCryostat allows you to install Cryostat for multiple namespaces - or cluster-wide. It contains configuration options for controlling the Deployment - of the Cryostat application and its related components. A ClusterCryostat - or Cryostat instance must be created to instruct the operator to deploy - the Cryostat application. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ClusterCryostatSpec defines the desired state of ClusterCryostat. - properties: - authProperties: - description: Override default authorization properties for Cryostat - on OpenShift. - properties: - clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - type: string - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - clusterRoleName - - configMapName - - filename - type: object - enableCertManager: - description: Use cert-manager to secure in-cluster communication between - Cryostat components. Requires cert-manager to be installed. - type: boolean - eventTemplates: - description: List of Flight Recorder Event Templates to preconfigure - in Cryostat. - items: - description: A ConfigMap containing a .jfc template file. - properties: - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the template - file. - type: string - required: - - configMapName - - filename - type: object - type: array - installNamespace: - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - type: string - jmxCacheOptions: - description: Options to customize the JMX target connections cache - for the Cryostat application. - properties: - targetCacheSize: - description: The maximum number of JMX connections to cache. Use - `-1` for an unlimited cache size (TTL expiration only). Defaults - to `-1`. - format: int32 - minimum: -1 - type: integer - targetCacheTTL: - description: The time to live (in seconds) for cached JMX connections. - Defaults to `10`. - format: int32 - minimum: 1 - type: integer - type: object - jmxCredentialsDatabaseOptions: - description: Options to configure the Cryostat application's credentials - database. - properties: - databaseSecretName: - description: Name of the secret containing the password to encrypt - credentials database. - type: string - type: object - maxWsConnections: - description: The maximum number of WebSocket client connections allowed - (minimum 1, default unlimited). - format: int32 - minimum: 1 - type: integer - minimal: - description: Deploy a pared-down Cryostat instance with no Grafana - Dashboard or JFR Data Source. - type: boolean - networkOptions: - description: Options to control how the operator exposes the application - outside of the cluster, such as using an Ingress or Route. - properties: - commandConfig: - description: "Specifications for how to expose the Cryostat command - service, which serves the WebSocket command channel. \n Deprecated: - CommandConfig is no longer used." - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - coreConfig: - description: Specifications for how to expose the Cryostat service, - which serves the Cryostat application. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - grafanaConfig: - description: Specifications for how to expose Cryostat's Grafana - service, which serves the Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - type: object - operandMetadata: - description: Options to configure the Cryostat deployments and pods - metadata - properties: - deploymentMetadata: - description: Options to configure the Cryostat deployments metadata - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the resources during its - creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the resources during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - type: object - podMetadata: - description: Options to configure the Cryostat pods metadata - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the resources during its - creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the resources during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - type: object - type: object - reportOptions: - description: Options to configure Cryostat Automated Report Analysis. - properties: - replicas: - description: The number of report sidecar replica containers to - deploy. Each replica can service one report generation request - at a time. - format: int32 - type: integer - resources: - description: The resources allocated to each sidecar replica. - A replica with more resources can handle larger input recordings - and will process them faster. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - schedulingOptions: - description: Options to configure scheduling for the reports deployment - properties: - affinity: - description: Affinity rules for scheduling Cryostat pods. - properties: - nodeAffinity: - description: 'Node affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term - matches all objects with implicit weight 0 (i.e. - it's a no-op). A null preferred scheduling term - matches no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching - the corresponding nodeSelectorTerm, in the - range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to an update), the system may or may not try - to eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector - terms. The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: 'Pod affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of - resources, in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to a pod label update), the system may or may - not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, - i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: 'Pod anti-affinity scheduling rules for a - Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to - the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of - resources, in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - anti-affinity requirements specified by this field - cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may - or may not try to eventually evict the pod from - its node. When there are multiple elements, the - lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod - to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat - pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. - type: string - key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period - of time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the value should - be empty, otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the - Cryostat report generator. - properties: - podSecurityContext: - description: Security Context to apply to the Cryostat report - generator pod. - properties: - fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow - the Kubelet to change the ownership of that volume to - be owned by the pod: \n 1. The owning GID will be the - FSGroup 2. The setgid bit is set (new files created - in the volume will be owned by FSGroup) 3. The permission - bits are OR'd with rw-rw---- \n If unset, the Kubelet - will not modify the ownership and permissions of any - volume. Note that this field cannot be set when spec.os.name - is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of - changing ownership and permission of the volume before - being exposed inside Pod. This field will only apply - to volume types which support fsGroup based ownership(and - permissions). It will have no effect on ephemeral volume - types such as: secret, configmaps and emptydir. Valid - values are "OnRootMismatch" and "Always". If not specified, - "Always" is used. Note that this field cannot be set - when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all - containers. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp 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 - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID, the fsGroup (if specified), and group memberships - defined in the container image for the uid of the container - process. If unspecified, no additional groups are added - to any container. Note that group memberships defined - in the container image for the uid of the container - process are still effective, even if they are not included - in this list. Note that this field cannot be set when - spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls - used for the pod. Pods with unsupported sysctls (by - the container runtime) might fail to launch. Note that - this field cannot be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be - set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options within a - container's SecurityContext will be used. If set in - both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - reportsSecurityContext: - description: Security Context to apply to the Cryostat report - generator container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag - will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that this - field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name - is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - type: object - subProcessMaxHeapSize: - description: When zero report sidecar replicas are requested, - SubProcessMaxHeapSize configures the maximum heap size of the - basic subprocess report generator in MiB. The default heap size - is `200` (MiB). - format: int32 - type: integer - type: object - resources: - description: Resource requirements for the Cryostat deployment. - properties: - coreResources: - description: Resource requirements for the Cryostat application. - If specifying a memory limit, at least 768MiB is recommended. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - dataSourceResources: - description: Resource requirements for the JFR Data Source container. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - grafanaResources: - description: Resource requirements for the Grafana container. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - type: object - schedulingOptions: - description: Options to configure scheduling for the Cryostat deployment - properties: - affinity: - description: Affinity rules for scheduling Cryostat pods. - properties: - nodeAffinity: - description: 'Node affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated with - the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: 'Pod affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: 'Pod anti-affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod to - a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat pods - to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the Cryostat - application. - properties: - coreSecurityContext: - description: Security Context to apply to the Cryostat application - container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - dataSourceSecurityContext: - description: Security Context to apply to the JFR Data Source - container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - grafanaSecurityContext: - description: Security Context to apply to the Grafana container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - podSecurityContext: - description: Security Context to apply to the Cryostat pod. - properties: - fsGroup: - description: "A special supplemental group that applies to - all containers in a pod. Some volume types allow the Kubelet - to change the ownership of that volume to be owned by the - pod: \n 1. The owning GID will be the FSGroup 2. The setgid - bit is set (new files created in the volume will be owned - by FSGroup) 3. The permission bits are OR'd with rw-rw---- - \n If unset, the Kubelet will not modify the ownership and - permissions of any volume. Note that this field cannot be - set when spec.os.name is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will - have no effect on ephemeral volume types such as: secret, - configmaps and emptydir. Valid values are "OnRootMismatch" - and "Always". If not specified, "Always" is used. Note that - this field cannot be set when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field - cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is - windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - SecurityContext. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp 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 defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's primary - GID, the fsGroup (if specified), and group memberships defined - in the container image for the uid of the container process. - If unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image - for the uid of the container process are still effective, - even if they are not included in this list. Note that this - field cannot be set when spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. Note that this field cannot - be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - type: object - serviceOptions: - description: Options to customize the services created for the Cryostat - application and Grafana dashboard. - properties: - coreConfig: - description: Specification for the service responsible for the - Cryostat application. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Cryostat application - service. Defaults to 8181. - format: int32 - type: integer - jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - grafanaConfig: - description: Specification for the service responsible for the - Cryostat Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Grafana dashboard service. - Defaults to 3000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - reportsConfig: - description: Specification for the service responsible for the - cryostat-reports sidecars. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the cryostat-reports service. - Defaults to 10000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - type: object - storageOptions: - description: Options to customize the storage for Flight Recordings - and Templates. - properties: - emptyDir: - description: Configuration for an EmptyDir to be created by the - operator instead of a PVC. - properties: - enabled: - description: When enabled, Cryostat will use EmptyDir volumes - instead of a Persistent Volume Claim. Any PVC configurations - will be ignored. - type: boolean - medium: - description: Unless specified, the emptyDir volume will be - mounted on the same storage medium backing the node. Setting - this field to "Memory" will mount the emptyDir on a tmpfs - (RAM-backed filesystem). - type: string - sizeLimit: - description: The maximum memory limit for the emptyDir. Default - is unbounded. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - type: string - type: object - pvc: - description: Configuration for the Persistent Volume Claim to - be created by the operator. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Persistent Volume Claim - during its creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Persistent Volume Claim - during its creation. The label with key "app" is reserved - for use by the operator. - type: object - spec: - description: Spec for a Persistent Volume Claim, whose options - will override the defaults used by the operator. Unless - overriden, the PVC will be created with the default Storage - Class and 500MiB of storage. Once the operator has created - the PVC, changes to this field have no effect. - properties: - accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the 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. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: selector is a label query over volumes to - consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: '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 - volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference to the - PersistentVolume backing this claim. - type: string - type: object - type: object - type: object - targetDiscoveryOptions: - description: Options to configure the Cryostat application's target - discovery mechanisms. - properties: - builtInDiscoveryDisabled: - description: When true, the Cryostat application will disable - the built-in discovery mechanisms. Defaults to false. - type: boolean - disableBuiltInPortNames: - description: When true, the Cryostat application will use the - default port name jfr-jmx to look for JMX connectable targets. - type: boolean - disableBuiltInPortNumbers: - description: When true, the Cryostat application will use the - default port number 9091 to look for JMX connectable targets. - type: boolean - discoveryPortNames: - description: List of port names that the Cryostat application - should look for in order to consider a target as JMX connectable. - items: - type: string - type: array - discoveryPortNumbers: - description: List of port numbers that the Cryostat application - should look for in order to consider a target as JMX connectable. - items: - format: int32 - type: integer - type: array - type: object - targetNamespaces: - description: 'List of namespaces whose workloads Cryostat should be - permitted to access and profile. Warning: All Cryostat users will - be able to create and manage recordings for workloads in the listed - namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.3.0/docs/multi-namespace.md#data-isolation' - items: - type: string - type: array - trustedCertSecrets: - description: List of TLS certificates to trust when connecting to - targets. - items: - properties: - certificateKey: - description: Key within secret containing the certificate. - type: string - secretName: - description: Name of secret in the local namespace. - type: string - required: - - secretName - type: object - type: array - required: - - installNamespace - - minimal - type: object - status: - description: ClusterCryostatStatus defines the observed state of ClusterCryostat. - properties: - applicationUrl: - description: Address of the deployed Cryostat web application. - type: string - conditions: - description: Conditions of the components managed by the Cryostat - Operator. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - grafanaSecret: - description: Name of the Secret containing the generated Grafana credentials. - type: string - targetNamespaces: - description: List of namespaces that Cryostat has been configured - and authorized to access and profile. - items: - type: string - type: array - required: - - applicationUrl - type: object - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .status.applicationUrl - name: Application URL - type: string - - jsonPath: .status.grafanaSecret - name: Grafana Secret - type: string - name: v1beta2 - schema: - openAPIV3Schema: - description: ClusterCryostat allows you to install Cryostat for multiple namespaces - or cluster-wide. It contains configuration options for controlling the Deployment - of the Cryostat application and its related components. A ClusterCryostat - or Cryostat instance must be created to instruct the operator to deploy - the Cryostat application. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ClusterCryostatSpec defines the desired state of ClusterCryostat. - properties: - authProperties: - description: Override default authorization properties for Cryostat - on OpenShift. - properties: - clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - type: string - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - clusterRoleName - - configMapName - - filename - type: object - enableCertManager: - description: Use cert-manager to secure in-cluster communication between - Cryostat components. Requires cert-manager to be installed. - type: boolean - eventTemplates: - description: List of Flight Recorder Event Templates to preconfigure - in Cryostat. - items: - description: A ConfigMap containing a .jfc template file. - properties: - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the template - file. - type: string - required: - - configMapName - - filename - type: object - type: array - installNamespace: - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - type: string - jmxCacheOptions: - description: Options to customize the JMX target connections cache - for the Cryostat application. - properties: - targetCacheSize: - description: The maximum number of JMX connections to cache. Use - `-1` for an unlimited cache size (TTL expiration only). Defaults - to `-1`. - format: int32 - minimum: -1 - type: integer - targetCacheTTL: - description: The time to live (in seconds) for cached JMX connections. - Defaults to `10`. - format: int32 - minimum: 1 - type: integer - type: object - jmxCredentialsDatabaseOptions: - description: Options to configure the Cryostat application's credentials - database. - properties: - databaseSecretName: - description: Name of the secret containing the password to encrypt - credentials database. - type: string - type: object - maxWsConnections: - description: The maximum number of WebSocket client connections allowed - (minimum 1, default unlimited). - format: int32 - minimum: 1 - type: integer - minimal: - description: Deploy a pared-down Cryostat instance with no Grafana - Dashboard or JFR Data Source. - type: boolean - networkOptions: - description: Options to control how the operator exposes the application - outside of the cluster, such as using an Ingress or Route. - properties: - commandConfig: - description: "Specifications for how to expose the Cryostat command - service, which serves the WebSocket command channel. \n Deprecated: - CommandConfig is no longer used." - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - coreConfig: - description: Specifications for how to expose the Cryostat service, - which serves the Cryostat application. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - grafanaConfig: - description: Specifications for how to expose Cryostat's Grafana - service, which serves the Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object - type: object - operandMetadata: - description: Options to configure the Cryostat deployments and pods - metadata - properties: - deploymentMetadata: - description: Options to configure the Cryostat deployments metadata - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the resources during its - creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the resources during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - type: object - podMetadata: - description: Options to configure the Cryostat pods metadata - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the resources during its - creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the resources during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - type: object - type: object - reportOptions: - description: Options to configure Cryostat Automated Report Analysis. - properties: - replicas: - description: The number of report sidecar replica containers to - deploy. Each replica can service one report generation request - at a time. - format: int32 - type: integer - resources: - description: The resources allocated to each sidecar replica. - A replica with more resources can handle larger input recordings - and will process them faster. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - schedulingOptions: - description: Options to configure scheduling for the reports deployment - properties: - affinity: - description: Affinity rules for scheduling Cryostat pods. - properties: - nodeAffinity: - description: 'Node affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term - matches all objects with implicit weight 0 (i.e. - it's a no-op). A null preferred scheduling term - matches no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching - the corresponding nodeSelectorTerm, in the - range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to an update), the system may or may not try - to eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector - terms. The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: 'Pod affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of - resources, in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to a pod label update), the system may or may - not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, - i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: 'Pod anti-affinity scheduling rules for a - Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to - the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, - associated with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of - resources, in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - anti-affinity requirements specified by this field - cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may - or may not try to eventually evict the pod from - its node. When there are multiple elements, the - lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod - to a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat - pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. - type: string - key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period - of time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the value should - be empty, otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the - Cryostat report generator. - properties: - podSecurityContext: - description: Security Context to apply to the Cryostat report - generator pod. - properties: - fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow - the Kubelet to change the ownership of that volume to - be owned by the pod: \n 1. The owning GID will be the - FSGroup 2. The setgid bit is set (new files created - in the volume will be owned by FSGroup) 3. The permission - bits are OR'd with rw-rw---- \n If unset, the Kubelet - will not modify the ownership and permissions of any - volume. Note that this field cannot be set when spec.os.name - is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of - changing ownership and permission of the volume before - being exposed inside Pod. This field will only apply - to volume types which support fsGroup based ownership(and - permissions). It will have no effect on ephemeral volume - types such as: secret, configmaps and emptydir. Valid - values are "OnRootMismatch" and "Always". If not specified, - "Always" is used. Note that this field cannot be set - when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all - containers. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp 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 - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID, the fsGroup (if specified), and group memberships - defined in the container image for the uid of the container - process. If unspecified, no additional groups are added - to any container. Note that group memberships defined - in the container image for the uid of the container - process are still effective, even if they are not included - in this list. Note that this field cannot be set when - spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls - used for the pod. Pods with unsupported sysctls (by - the container runtime) might fail to launch. Note that - this field cannot be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be - set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options within a - container's SecurityContext will be used. If set in - both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - reportsSecurityContext: - description: Security Context to apply to the Cryostat report - generator container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag - will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that this - field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name - is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of - the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - type: object - subProcessMaxHeapSize: - description: When zero report sidecar replicas are requested, - SubProcessMaxHeapSize configures the maximum heap size of the - basic subprocess report generator in MiB. The default heap size - is `200` (MiB). - format: int32 - type: integer - type: object - resources: - description: Resource requirements for the Cryostat deployment. - properties: - coreResources: - description: Resource requirements for the Cryostat application. - If specifying a memory limit, at least 768MiB is recommended. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - dataSourceResources: - description: Resource requirements for the JFR Data Source container. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - grafanaResources: - description: Resource requirements for the Grafana container. - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - type: object - schedulingOptions: - description: Options to configure scheduling for the Cryostat deployment - properties: - affinity: - description: Affinity rules for scheduling Cryostat pods. - properties: - nodeAffinity: - description: 'Node affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated with - the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: 'Pod affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: 'Pod anti-affinity scheduling rules for a Cryostat - pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-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. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod to - a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat pods - to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the Cryostat - application. - properties: - coreSecurityContext: - description: Security Context to apply to the Cryostat application - container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - dataSourceSecurityContext: - description: Security Context to apply to the JFR Data Source - container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - grafanaSecurityContext: - description: Security Context to apply to the Grafana container. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - podSecurityContext: - description: Security Context to apply to the Cryostat pod. - properties: - fsGroup: - description: "A special supplemental group that applies to - all containers in a pod. Some volume types allow the Kubelet - to change the ownership of that volume to be owned by the - pod: \n 1. The owning GID will be the FSGroup 2. The setgid - bit is set (new files created in the volume will be owned - by FSGroup) 3. The permission bits are OR'd with rw-rw---- - \n If unset, the Kubelet will not modify the ownership and - permissions of any volume. Note that this field cannot be - set when spec.os.name is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will - have no effect on ephemeral volume types such as: secret, - configmaps and emptydir. Valid values are "OnRootMismatch" - and "Always". If not specified, "Always" is used. Note that - this field cannot be set when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field - cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is - windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - SecurityContext. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp 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 defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's primary - GID, the fsGroup (if specified), and group memberships defined - in the container image for the uid of the container process. - If unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image - for the uid of the container process are still effective, - even if they are not included in this list. Note that this - field cannot be set when spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. Note that this field cannot - be set when spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - type: object - serviceOptions: - description: Options to customize the services created for the Cryostat - application and Grafana dashboard. - properties: - coreConfig: - description: Specification for the service responsible for the - Cryostat application. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Cryostat application - service. Defaults to 8181. - format: int32 - type: integer - jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - grafanaConfig: - description: Specification for the service responsible for the - Cryostat Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Grafana dashboard service. - Defaults to 3000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - reportsConfig: - description: Specification for the service responsible for the - cryostat-reports sidecars. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the cryostat-reports service. - Defaults to 10000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object - type: object - storageOptions: - description: Options to customize the storage for Flight Recordings - and Templates. - properties: - emptyDir: - description: Configuration for an EmptyDir to be created by the - operator instead of a PVC. - properties: - enabled: - description: When enabled, Cryostat will use EmptyDir volumes - instead of a Persistent Volume Claim. Any PVC configurations - will be ignored. - type: boolean - medium: - description: Unless specified, the emptyDir volume will be - mounted on the same storage medium backing the node. Setting - this field to "Memory" will mount the emptyDir on a tmpfs - (RAM-backed filesystem). - type: string - sizeLimit: - description: The maximum memory limit for the emptyDir. Default - is unbounded. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - type: string - type: object - pvc: - description: Configuration for the Persistent Volume Claim to - be created by the operator. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Persistent Volume Claim - during its creation. - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Persistent Volume Claim - during its creation. The label with key "app" is reserved - for use by the operator. - type: object - spec: - description: Spec for a Persistent Volume Claim, whose options - will override the defaults used by the operator. Unless - overriden, the PVC will be created with the default Storage - Class and 500MiB of storage. Once the operator has created - the PVC, changes to this field have no effect. - properties: - accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the 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. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n 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: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: selector is a label query over volumes to - consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: '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 - volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference to the - PersistentVolume backing this claim. - type: string - type: object - type: object - type: object - targetDiscoveryOptions: - description: Options to configure the Cryostat application's target - discovery mechanisms. - properties: - builtInDiscoveryDisabled: - description: When true, the Cryostat application will disable - the built-in discovery mechanisms. Defaults to false - type: boolean - disableBuiltInPortNames: - description: When true, the Cryostat application will use the - default port name jfr-jmx to look for JMX connectable targets. - type: boolean - disableBuiltInPortNumbers: - description: When true, the Cryostat application will use the - default port number 9091 to look for JMX connectable targets. - type: boolean - discoveryPortNames: - description: List of port names that the Cryostat application - should look for in order to consider a target as JMX connectable. - items: - type: string - type: array - discoveryPortNumbers: - description: List of port numbers that the Cryostat application - should look for in order to consider a target as JMX connectable. - items: - format: int32 - type: integer - type: array - type: object - targetNamespaces: - description: 'List of namespaces whose workloads Cryostat should be - permitted to access and profile. Defaults to this Cryostat''s namespace. - Warning: All Cryostat users will be able to create and manage recordings - for workloads in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' - items: - type: string - type: array - trustedCertSecrets: - description: List of TLS certificates to trust when connecting to - targets. - items: - properties: - certificateKey: - description: Key within secret containing the certificate. - type: string - secretName: - description: Name of secret in the local namespace. - type: string - required: - - secretName - type: object - type: array - required: - - installNamespace - - minimal - type: object - status: - description: ClusterCryostatStatus defines the observed state of ClusterCryostat. - properties: - applicationUrl: - description: Address of the deployed Cryostat web application. - type: string - conditions: - description: Conditions of the components managed by the Cryostat - Operator. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - grafanaSecret: - description: Name of the Secret containing the generated Grafana credentials. - type: string - targetNamespaces: - description: List of namespaces that Cryostat has been configured - and authorized to access and profile. - items: - type: string - type: array - required: - - applicationUrl - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index af307be48..694eaaa07 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -4742,11 +4742,11 @@ spec: name: v1beta2 schema: openAPIV3Schema: - description: Cryostat allows you to install Cryostat for a single namespace. - It contains configuration options for controlling the Deployment of the - Cryostat application and its related components. A ClusterCryostat or Cryostat - instance must be created to instruct the operator to deploy the Cryostat - application. + description: Cryostat allows you to install Cryostat for a single namespace, + or multiple namespaces. It contains configuration options for controlling + the Deployment of the Cryostat application and its related components. A + Cryostat instance must be created to instruct the operator to deploy the + Cryostat application. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index bd3981702..6825207d6 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -3,20 +3,17 @@ # It should be run by config/default resources: - bases/operator.cryostat.io_cryostats.yaml -- bases/operator.cryostat.io_clustercryostats.yaml # +kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD - patches/webhook_in_cryostats.yaml -- patches/webhook_in_clustercryostats.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD - patches/cainjection_in_cryostats.yaml -- patches/cainjection_in_clustercryostats.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/cainjection_in_clustercryostats.yaml b/config/crd/patches/cainjection_in_clustercryostats.yaml deleted file mode 100644 index 8a74c61fe..000000000 --- a/config/crd/patches/cainjection_in_clustercryostats.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: clustercryostats.operator.cryostat.io diff --git a/config/crd/patches/webhook_in_clustercryostats.yaml b/config/crd/patches/webhook_in_clustercryostats.yaml deleted file mode 100644 index 2c578d24d..000000000 --- a/config/crd/patches/webhook_in_clustercryostats.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: clustercryostats.operator.cryostat.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 42891093d..6b5b54117 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -35,844 +35,10 @@ spec: apiservicedefinitions: {} customresourcedefinitions: owned: - - description: ClusterCryostat allows you to install Cryostat for multiple namespaces - or cluster-wide. It contains configuration options for controlling the Deployment - of the Cryostat application and its related components. A ClusterCryostat - or Cryostat instance must be created to instruct the operator to deploy the - Cryostat application. - displayName: Cluster Cryostat - kind: ClusterCryostat - name: clustercryostats.operator.cryostat.io - resources: - - kind: ConsoleLink - name: "" - version: v1 - - kind: Deployment - name: "" - version: v1 - - kind: Ingress - name: "" - version: v1 - - kind: PersistentVolumeClaim - name: "" - version: v1 - - kind: Route - name: "" - version: v1 - - kind: Secret - name: "" - version: v1 - - kind: Service - name: "" - version: v1 - specDescriptors: - - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - displayName: Install Namespace - path: installNamespace - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - - description: 'List of namespaces whose workloads Cryostat should be permitted - to access and profile. Defaults to this Cryostat''s namespace. Warning: - All Cryostat users will be able to create and manage recordings for workloads - in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' - displayName: Target Namespaces - path: targetNamespaces - - description: Use cert-manager to secure in-cluster communication between Cryostat - components. Requires cert-manager to be installed. - displayName: Enable cert-manager Integration - path: enableCertManager - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard - or JFR Data Source. - displayName: Minimal Deployment - path: minimal - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Override default authorization properties for Cryostat on OpenShift. - displayName: Authorization Properties - path: authProperties - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped - OAuth token. This ClusterRole should contain permissions for all Kubernetes - objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: ClusterRole Name - path: authProperties.clusterRoleName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ClusterRole - - description: Name of config map in the local namespace. - displayName: ConfigMap Name - path: authProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Filename within config map containing the resource mapping. - displayName: Filename - path: authProperties.filename - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. - displayName: Event Templates - path: eventTemplates - - description: Name of config map in the local namespace. - displayName: Config Map Name - path: eventTemplates[0].configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Options to customize the JMX target connections cache for the - Cryostat application. - displayName: JMX Connections Cache Options - path: jmxCacheOptions - - description: The maximum number of JMX connections to cache. Use `-1` for - an unlimited cache size (TTL expiration only). Defaults to `-1`. - displayName: Target Cache Size - path: jmxCacheOptions.targetCacheSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: The time to live (in seconds) for cached JMX connections. Defaults - to `10`. - displayName: Target Cache TTL - path: jmxCacheOptions.targetCacheTTL - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to configure the Cryostat application's credentials database. - displayName: Credentials Database Options - path: jmxCredentialsDatabaseOptions - - description: Name of the secret containing the password to encrypt credentials - database. - displayName: Database Secret Name - path: jmxCredentialsDatabaseOptions.databaseSecretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: The maximum number of WebSocket client connections allowed (minimum - 1, default unlimited). - displayName: Max WebSocket Connections - path: maxWsConnections - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to control how the operator exposes the application outside - of the cluster, such as using an Ingress or Route. - displayName: Network Options - path: networkOptions - - description: "Specifications for how to expose the Cryostat command service, - which serves the WebSocket command channel. \n Deprecated: CommandConfig - is no longer used." - displayName: Command Config - path: networkOptions.commandConfig - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:hidden - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.commandConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.commandConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.commandConfig.labels - - description: Specifications for how to expose the Cryostat service, which - serves the Cryostat application. - displayName: Core Config - path: networkOptions.coreConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.coreConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.coreConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.coreConfig.labels - - description: Specifications for how to expose Cryostat's Grafana service, - which serves the Grafana dashboard. - displayName: Grafana Config - path: networkOptions.grafanaConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.grafanaConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.grafanaConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.grafanaConfig.labels - - description: Options to configure the Cryostat deployments and pods metadata - displayName: Operand metadata - path: operandMetadata - - description: Options to configure the Cryostat deployments metadata - displayName: Deployments metadata - path: operandMetadata.deploymentMetadata - - description: Options to configure the Cryostat pods metadata - displayName: Pods metadata - path: operandMetadata.podMetadata - - description: Options to configure Cryostat Automated Report Analysis. - displayName: Report Options - path: reportOptions - - description: The number of report sidecar replica containers to deploy. Each - replica can service one report generation request at a time. - displayName: Replicas - path: reportOptions.replicas - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podCount - - description: The resources allocated to each sidecar replica. A replica with - more resources can handle larger input recordings and will process them - faster. - displayName: Resources - path: reportOptions.resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Options to configure scheduling for the reports deployment - displayName: Scheduling Options - path: reportOptions.schedulingOptions - - description: Affinity rules for scheduling Cryostat pods. - displayName: Affinity - path: reportOptions.schedulingOptions.affinity - - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - displayName: Node Affinity - path: reportOptions.schedulingOptions.affinity.nodeAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:nodeAffinity - - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - displayName: Pod Affinity - path: reportOptions.schedulingOptions.affinity.podAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAffinity - - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: - https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - displayName: Pod Anti Affinity - path: reportOptions.schedulingOptions.affinity.podAntiAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity - - description: 'Label selector used to schedule a Cryostat pod to a node. See: - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - displayName: Node Selector - path: reportOptions.schedulingOptions.nodeSelector - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node - - description: 'Tolerations to allow scheduling of Cryostat pods to tainted - nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - displayName: Tolerations - path: reportOptions.schedulingOptions.tolerations - - description: Options to configure the Security Contexts for the Cryostat report - generator. - displayName: Security Options - path: reportOptions.securityOptions - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: Security Context to apply to the Cryostat report generator pod. - displayName: Pod Security Context - path: reportOptions.securityOptions.podSecurityContext - - description: Security Context to apply to the Cryostat report generator container. - displayName: Reports Security Context - path: reportOptions.securityOptions.reportsSecurityContext - - description: When zero report sidecar replicas are requested, SubProcessMaxHeapSize - configures the maximum heap size of the basic subprocess report generator - in MiB. The default heap size is `200` (MiB). - displayName: Sub Process Max Heap Size - path: reportOptions.subProcessMaxHeapSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Resource requirements for the Cryostat deployment. - displayName: Resources - path: resources - - description: Resource requirements for the Cryostat application. If specifying - a memory limit, at least 768MiB is recommended. - displayName: Core Resources - path: resources.coreResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Resource requirements for the JFR Data Source container. - displayName: Data Source Resources - path: resources.dataSourceResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Resource requirements for the Grafana container. - displayName: Grafana Resources - path: resources.grafanaResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Options to configure scheduling for the Cryostat deployment - displayName: Scheduling Options - path: schedulingOptions - - description: Affinity rules for scheduling Cryostat pods. - displayName: Affinity - path: schedulingOptions.affinity - - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - displayName: Node Affinity - path: schedulingOptions.affinity.nodeAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:nodeAffinity - - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - displayName: Pod Affinity - path: schedulingOptions.affinity.podAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAffinity - - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: - https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - displayName: Pod Anti Affinity - path: schedulingOptions.affinity.podAntiAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity - - description: 'Label selector used to schedule a Cryostat pod to a node. See: - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - displayName: Node Selector - path: schedulingOptions.nodeSelector - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node - - description: 'Tolerations to allow scheduling of Cryostat pods to tainted - nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - displayName: Tolerations - path: schedulingOptions.tolerations - - description: Options to configure the Security Contexts for the Cryostat application. - displayName: Security Options - path: securityOptions - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: Security Context to apply to the Cryostat application container. - displayName: Core Security Context - path: securityOptions.coreSecurityContext - - description: Security Context to apply to the JFR Data Source container. - displayName: Data Source Security Context - path: securityOptions.dataSourceSecurityContext - - description: Security Context to apply to the Grafana container. - displayName: Grafana Security Context - path: securityOptions.grafanaSecurityContext - - description: Security Context to apply to the Cryostat pod. - displayName: Pod Security Context - path: securityOptions.podSecurityContext - - description: Options to customize the services created for the Cryostat application - and Grafana dashboard. - displayName: Service Options - path: serviceOptions - - description: Options to customize the storage for Flight Recordings and Templates. - displayName: Storage Options - path: storageOptions - - description: Configuration for an EmptyDir to be created by the operator instead - of a PVC. - displayName: Empty Dir - path: storageOptions.emptyDir - - description: When enabled, Cryostat will use EmptyDir volumes instead of a - Persistent Volume Claim. Any PVC configurations will be ignored. - displayName: Enabled - path: storageOptions.emptyDir.enabled - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Unless specified, the emptyDir volume will be mounted on the - same storage medium backing the node. Setting this field to "Memory" will - mount the emptyDir on a tmpfs (RAM-backed filesystem). - displayName: Medium - path: storageOptions.emptyDir.medium - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true - - description: The maximum memory limit for the emptyDir. Default is unbounded. - displayName: Size Limit - path: storageOptions.emptyDir.sizeLimit - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true - - description: Configuration for the Persistent Volume Claim to be created by - the operator. - displayName: PVC - path: storageOptions.pvc - - description: Spec for a Persistent Volume Claim, whose options will override - the defaults used by the operator. Unless overriden, the PVC will be created - with the default Storage Class and 500MiB of storage. Once the operator - has created the PVC, changes to this field have no effect. - displayName: Spec - path: storageOptions.pvc.spec - - description: Options to configure the Cryostat application's target discovery - mechanisms. - displayName: Target Discovery Options - path: targetDiscoveryOptions - - description: When true, the Cryostat application will disable the built-in - discovery mechanisms. Defaults to false - displayName: Disable Built-in Discovery - path: targetDiscoveryOptions.builtInDiscoveryDisabled - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - name jfr-jmx to look for JMX connectable targets. - displayName: Disable Built-in Port Names - path: targetDiscoveryOptions.disableBuiltInPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - number 9091 to look for JMX connectable targets. - displayName: Disable Built-in Port Numbers - path: targetDiscoveryOptions.disableBuiltInPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: List of port names that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Names - path: targetDiscoveryOptions.discoveryPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true - - description: List of port numbers that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Numbers - path: targetDiscoveryOptions.discoveryPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - - description: List of TLS certificates to trust when connecting to targets. - displayName: Trusted TLS Certificates - path: trustedCertSecrets - - description: Name of secret in the local namespace. - displayName: Secret Name - path: trustedCertSecrets[0].secretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - statusDescriptors: - - description: Address of the deployed Cryostat web application. - displayName: Application URL - path: applicationUrl - x-descriptors: - - urn:alm:descriptor:org.w3:link - - description: Name of the Secret containing the generated Grafana credentials. - displayName: Grafana Secret - path: grafanaSecret - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: List of namespaces that Cryostat has been configured and authorized - to access and profile. - displayName: Target Namespaces - path: targetNamespaces - - description: Conditions of the components managed by the Cryostat Operator. - displayName: Cryostat Conditions - path: conditions - x-descriptors: - - urn:alm:descriptor:io.kubernetes.conditions - version: v1beta2 - - description: ClusterCryostat allows you to install Cryostat for multiple namespaces - or cluster-wide. It contains configuration options for controlling the Deployment - of the Cryostat application and its related components. A ClusterCryostat - or Cryostat instance must be created to instruct the operator to deploy the - Cryostat application. - displayName: Cluster Cryostat - kind: ClusterCryostat - name: clustercryostats.operator.cryostat.io - resources: - - kind: ConsoleLink - name: "" - version: v1 - - kind: Deployment - name: "" - version: v1 - - kind: Ingress - name: "" - version: v1 - - kind: PersistentVolumeClaim - name: "" - version: v1 - - kind: Route - name: "" - version: v1 - - kind: Secret - name: "" - version: v1 - - kind: Service - name: "" - version: v1 - specDescriptors: - - description: Namespace where Cryostat should be installed. On multi-tenant - clusters, we strongly suggest installing Cryostat into its own namespace. - displayName: Install Namespace - path: installNamespace - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Namespace - - description: 'List of namespaces whose workloads Cryostat should be permitted - to access and profile. Warning: All Cryostat users will be able to create - and manage recordings for workloads in the listed namespaces. More details: - https://github.com/cryostatio/cryostat-operator/blob/v2.3.0/docs/multi-namespace.md#data-isolation' - displayName: Target Namespaces - path: targetNamespaces - - description: Use cert-manager to secure in-cluster communication between Cryostat - components. Requires cert-manager to be installed. - displayName: Enable cert-manager Integration - path: enableCertManager - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard - or JFR Data Source. - displayName: Minimal Deployment - path: minimal - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Override default authorization properties for Cryostat on OpenShift. - displayName: Authorization Properties - path: authProperties - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped - OAuth token. This ClusterRole should contain permissions for all Kubernetes - objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: ClusterRole Name - path: authProperties.clusterRoleName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ClusterRole - - description: Name of config map in the local namespace. - displayName: ConfigMap Name - path: authProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Filename within config map containing the resource mapping. - displayName: Filename - path: authProperties.filename - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. - displayName: Event Templates - path: eventTemplates - - description: Name of config map in the local namespace. - displayName: Config Map Name - path: eventTemplates[0].configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Options to customize the JMX target connections cache for the - Cryostat application. - displayName: JMX Connections Cache Options - path: jmxCacheOptions - - description: The maximum number of JMX connections to cache. Use `-1` for - an unlimited cache size (TTL expiration only). Defaults to `-1`. - displayName: Target Cache Size - path: jmxCacheOptions.targetCacheSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: The time to live (in seconds) for cached JMX connections. Defaults - to `10`. - displayName: Target Cache TTL - path: jmxCacheOptions.targetCacheTTL - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to configure the Cryostat application's credentials database. - displayName: Credentials Database Options - path: jmxCredentialsDatabaseOptions - - description: Name of the secret containing the password to encrypt credentials - database. - displayName: Database Secret Name - path: jmxCredentialsDatabaseOptions.databaseSecretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: The maximum number of WebSocket client connections allowed (minimum - 1, default unlimited). - displayName: Max WebSocket Connections - path: maxWsConnections - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to control how the operator exposes the application outside - of the cluster, such as using an Ingress or Route. - displayName: Network Options - path: networkOptions - - description: "Specifications for how to expose the Cryostat command service, - which serves the WebSocket command channel. \n Deprecated: CommandConfig - is no longer used." - displayName: Command Config - path: networkOptions.commandConfig - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:hidden - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.commandConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.commandConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.commandConfig.labels - - description: Specifications for how to expose the Cryostat service, which - serves the Cryostat application. - displayName: Core Config - path: networkOptions.coreConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.coreConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.coreConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.coreConfig.labels - - description: Specifications for how to expose Cryostat's Grafana service, - which serves the Grafana dashboard. - displayName: Grafana Config - path: networkOptions.grafanaConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.grafanaConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.grafanaConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.grafanaConfig.labels - - description: Options to configure the Cryostat deployments and pods metadata - displayName: Operand metadata - path: operandMetadata - - description: Options to configure the Cryostat deployments metadata - displayName: Deployments metadata - path: operandMetadata.deploymentMetadata - - description: Options to configure the Cryostat pods metadata - displayName: Pods metadata - path: operandMetadata.podMetadata - - description: Options to configure Cryostat Automated Report Analysis. - displayName: Report Options - path: reportOptions - - description: The number of report sidecar replica containers to deploy. Each - replica can service one report generation request at a time. - displayName: Replicas - path: reportOptions.replicas - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podCount - - description: The resources allocated to each sidecar replica. A replica with - more resources can handle larger input recordings and will process them - faster. - displayName: Resources - path: reportOptions.resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Options to configure scheduling for the reports deployment - displayName: Scheduling Options - path: reportOptions.schedulingOptions - - description: Affinity rules for scheduling Cryostat pods. - displayName: Affinity - path: reportOptions.schedulingOptions.affinity - - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - displayName: Node Affinity - path: reportOptions.schedulingOptions.affinity.nodeAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:nodeAffinity - - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - displayName: Pod Affinity - path: reportOptions.schedulingOptions.affinity.podAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAffinity - - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: - https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - displayName: Pod Anti Affinity - path: reportOptions.schedulingOptions.affinity.podAntiAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity - - description: 'Label selector used to schedule a Cryostat pod to a node. See: - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - displayName: Node Selector - path: reportOptions.schedulingOptions.nodeSelector - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node - - description: 'Tolerations to allow scheduling of Cryostat pods to tainted - nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - displayName: Tolerations - path: reportOptions.schedulingOptions.tolerations - - description: Options to configure the Security Contexts for the Cryostat report - generator. - displayName: Security Options - path: reportOptions.securityOptions - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: Security Context to apply to the Cryostat report generator pod. - displayName: Pod Security Context - path: reportOptions.securityOptions.podSecurityContext - - description: Security Context to apply to the Cryostat report generator container. - displayName: Reports Security Context - path: reportOptions.securityOptions.reportsSecurityContext - - description: When zero report sidecar replicas are requested, SubProcessMaxHeapSize - configures the maximum heap size of the basic subprocess report generator - in MiB. The default heap size is `200` (MiB). - displayName: Sub Process Max Heap Size - path: reportOptions.subProcessMaxHeapSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Resource requirements for the Cryostat deployment. - displayName: Resources - path: resources - - description: Resource requirements for the Cryostat application. If specifying - a memory limit, at least 768MiB is recommended. - displayName: Core Resources - path: resources.coreResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Resource requirements for the JFR Data Source container. - displayName: Data Source Resources - path: resources.dataSourceResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Resource requirements for the Grafana container. - displayName: Grafana Resources - path: resources.grafanaResources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Options to configure scheduling for the Cryostat deployment - displayName: Scheduling Options - path: schedulingOptions - - description: Affinity rules for scheduling Cryostat pods. - displayName: Affinity - path: schedulingOptions.affinity - - description: 'Node affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' - displayName: Node Affinity - path: schedulingOptions.affinity.nodeAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:nodeAffinity - - description: 'Pod affinity scheduling rules for a Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' - displayName: Pod Affinity - path: schedulingOptions.affinity.podAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAffinity - - description: 'Pod anti-affinity scheduling rules for a Cryostat pod. See: - https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' - displayName: Pod Anti Affinity - path: schedulingOptions.affinity.podAntiAffinity - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podAntiAffinity - - description: 'Label selector used to schedule a Cryostat pod to a node. See: - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - displayName: Node Selector - path: schedulingOptions.nodeSelector - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Node - - description: 'Tolerations to allow scheduling of Cryostat pods to tainted - nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - displayName: Tolerations - path: schedulingOptions.tolerations - - description: Options to configure the Security Contexts for the Cryostat application. - displayName: Security Options - path: securityOptions - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: Security Context to apply to the Cryostat application container. - displayName: Core Security Context - path: securityOptions.coreSecurityContext - - description: Security Context to apply to the JFR Data Source container. - displayName: Data Source Security Context - path: securityOptions.dataSourceSecurityContext - - description: Security Context to apply to the Grafana container. - displayName: Grafana Security Context - path: securityOptions.grafanaSecurityContext - - description: Security Context to apply to the Cryostat pod. - displayName: Pod Security Context - path: securityOptions.podSecurityContext - - description: Options to customize the services created for the Cryostat application - and Grafana dashboard. - displayName: Service Options - path: serviceOptions - - description: Options to customize the storage for Flight Recordings and Templates. - displayName: Storage Options - path: storageOptions - - description: Configuration for an EmptyDir to be created by the operator instead - of a PVC. - displayName: Empty Dir - path: storageOptions.emptyDir - - description: When enabled, Cryostat will use EmptyDir volumes instead of a - Persistent Volume Claim. Any PVC configurations will be ignored. - displayName: Enabled - path: storageOptions.emptyDir.enabled - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Unless specified, the emptyDir volume will be mounted on the - same storage medium backing the node. Setting this field to "Memory" will - mount the emptyDir on a tmpfs (RAM-backed filesystem). - displayName: Medium - path: storageOptions.emptyDir.medium - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true - - description: The maximum memory limit for the emptyDir. Default is unbounded. - displayName: Size Limit - path: storageOptions.emptyDir.sizeLimit - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:storageOptions.emptyDir.enabled:true - - description: Configuration for the Persistent Volume Claim to be created by - the operator. - displayName: PVC - path: storageOptions.pvc - - description: Spec for a Persistent Volume Claim, whose options will override - the defaults used by the operator. Unless overriden, the PVC will be created - with the default Storage Class and 500MiB of storage. Once the operator - has created the PVC, changes to this field have no effect. - displayName: Spec - path: storageOptions.pvc.spec - - description: Options to configure the Cryostat application's target discovery - mechanisms. - displayName: Target Discovery Options - path: targetDiscoveryOptions - - description: When true, the Cryostat application will disable the built-in - discovery mechanisms. Defaults to false. - displayName: Disable Built-in Discovery - path: targetDiscoveryOptions.builtInDiscoveryDisabled - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - name jfr-jmx to look for JMX connectable targets. - displayName: Disable Built-in Port Names - path: targetDiscoveryOptions.disableBuiltInPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - number 9091 to look for JMX connectable targets. - displayName: Disable Built-in Port Numbers - path: targetDiscoveryOptions.disableBuiltInPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: List of port names that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Names - path: targetDiscoveryOptions.discoveryPortNames - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true - - description: List of port numbers that the Cryostat application should look - for in order to consider a target as JMX connectable. - displayName: Discovery Port Numbers - path: targetDiscoveryOptions.discoveryPortNumbers - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNumbers:true - - description: List of TLS certificates to trust when connecting to targets. - displayName: Trusted TLS Certificates - path: trustedCertSecrets - - description: Name of secret in the local namespace. - displayName: Secret Name - path: trustedCertSecrets[0].secretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - statusDescriptors: - - description: Address of the deployed Cryostat web application. - displayName: Application URL - path: applicationUrl - x-descriptors: - - urn:alm:descriptor:org.w3:link - - description: Name of the Secret containing the generated Grafana credentials. - displayName: Grafana Secret - path: grafanaSecret - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - - description: List of namespaces that Cryostat has been configured and authorized - to access and profile. - displayName: Target Namespaces - path: targetNamespaces - - description: Conditions of the components managed by the Cryostat Operator. - displayName: Cryostat Conditions - path: conditions - x-descriptors: - - urn:alm:descriptor:io.kubernetes.conditions - version: v1beta1 - - description: Cryostat allows you to install Cryostat for a single namespace. - It contains configuration options for controlling the Deployment of the Cryostat - application and its related components. A ClusterCryostat or Cryostat instance - must be created to instruct the operator to deploy the Cryostat application. + - description: Cryostat allows you to install Cryostat for a single namespace, + or multiple namespaces. It contains configuration options for controlling + the Deployment of the Cryostat application and its related components. A Cryostat + instance must be created to instruct the operator to deploy the Cryostat application. displayName: Cryostat kind: Cryostat name: cryostats.operator.cryostat.io diff --git a/config/manifests/targetNamespaces_patch.yaml b/config/manifests/targetNamespaces_patch.yaml index 640710b6a..b669249d4 100644 --- a/config/manifests/targetNamespaces_patch.yaml +++ b/config/manifests/targetNamespaces_patch.yaml @@ -15,35 +15,3 @@ path: targetNamespaces[0] x-descriptors: - "urn:alm:descriptor:io.kubernetes:Namespace" -- op: add - path: /spec/customresourcedefinitions/owned/1/specDescriptors/- - value: - description: "A namespace whose workloads Cryostat should be able to connect and record" - displayName: "Target Namespace" - path: targetNamespaces[0] - x-descriptors: - - "urn:alm:descriptor:io.kubernetes:Namespace" -- op: add - path: /spec/customresourcedefinitions/owned/1/statusDescriptors/- - value: - description: "A namespace whose workloads Cryostat should be able to connect and record" - displayName: "Target Namespace" - path: targetNamespaces[0] - x-descriptors: - - "urn:alm:descriptor:io.kubernetes:Namespace" -- op: add - path: /spec/customresourcedefinitions/owned/2/specDescriptors/- - value: - description: "A namespace whose workloads Cryostat should be able to connect and record" - displayName: "Target Namespace" - path: targetNamespaces[0] - x-descriptors: - - "urn:alm:descriptor:io.kubernetes:Namespace" -- op: add - path: /spec/customresourcedefinitions/owned/2/statusDescriptors/- - value: - description: "A namespace whose workloads Cryostat should be able to connect and record" - displayName: "Target Namespace" - path: targetNamespaces[0] - x-descriptors: - - "urn:alm:descriptor:io.kubernetes:Namespace" diff --git a/config/rbac/clustercryostat_editor_role.yaml b/config/rbac/clustercryostat_editor_role.yaml deleted file mode 100644 index f095d6ca5..000000000 --- a/config/rbac/clustercryostat_editor_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# permissions for end users to edit clustercryostats. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: clustercryostat-editor-role -rules: -- apiGroups: - - operator.cryostat.io - resources: - - clustercryostats - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - operator.cryostat.io - resources: - - clustercryostats/status - verbs: - - get diff --git a/config/rbac/clustercryostat_viewer_role.yaml b/config/rbac/clustercryostat_viewer_role.yaml deleted file mode 100644 index fa35fed19..000000000 --- a/config/rbac/clustercryostat_viewer_role.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# permissions for end users to view clustercryostats. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: clustercryostat-viewer-role -rules: -- apiGroups: - - operator.cryostat.io - resources: - - clustercryostats - verbs: - - get - - list - - watch -- apiGroups: - - operator.cryostat.io - resources: - - clustercryostats/status - verbs: - - get diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 0ca288fce..ed997e797 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -134,26 +134,6 @@ rules: verbs: - delete - list -- apiGroups: - - operator.cryostat.io - resources: - - clustercryostats - verbs: - - '*' -- apiGroups: - - operator.cryostat.io - resources: - - clustercryostats/finalizers - verbs: - - update -- apiGroups: - - operator.cryostat.io - resources: - - clustercryostats/status - verbs: - - get - - patch - - update - apiGroups: - operator.cryostat.io resources: diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 08a69bad7..08962986b 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -1,7 +1,5 @@ ## Append samples you want in your CSV to this file as resources ## resources: - operator_v1beta1_cryostat.yaml -- operator_v1beta1_clustercryostat.yaml - operator_v1beta2_cryostat.yaml -- operator_v1beta2_clustercryostat.yaml # +kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/operator_v1beta1_clustercryostat.yaml b/config/samples/operator_v1beta1_clustercryostat.yaml deleted file mode 100644 index d2dcfd741..000000000 --- a/config/samples/operator_v1beta1_clustercryostat.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: operator.cryostat.io/v1beta1 -kind: ClusterCryostat -metadata: - name: clustercryostat-sample -spec: - minimal: false - enableCertManager: true - trustedCertSecrets: [] - eventTemplates: [] - storageOptions: - pvc: - labels: {} - annotations: {} - spec: {} - reportOptions: - replicas: 0 diff --git a/config/samples/operator_v1beta2_clustercryostat.yaml b/config/samples/operator_v1beta2_clustercryostat.yaml deleted file mode 100644 index b4b656843..000000000 --- a/config/samples/operator_v1beta2_clustercryostat.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: operator.cryostat.io/v1beta2 -kind: ClusterCryostat -metadata: - name: clustercryostat-sample -spec: - minimal: false - enableCertManager: true - trustedCertSecrets: [] - eventTemplates: [] - storageOptions: - pvc: - labels: {} - annotations: {} - spec: {} - reportOptions: - replicas: 0 diff --git a/docs/config.md b/docs/config.md index 0d1639067..a57840b0c 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,6 +1,25 @@ ## Configuring Cryostat The operator creates and manages a Deployment of [Cryostat](https://github.com/cryostatio/cryostat) when the user creates or updates a `Cryostat` object. Only one `Cryostat` object should exist in the operator's namespace at a time. There are a few options available in the `Cryostat` spec that control how Cryostat is deployed. +### Target Namespaces +Specify the list of namespaces containing your workloads that you want your multi-namespace Cryostat installation to work with under the `spec.targetNamespaces` property. The resulting Cryostat will have permissions to access workloads only within these specified namespaces. If not specified, `spec.targetNamespaces` will default to the namespace of the `Cryostat` object. + +```yaml +apiVersion: operator.cryostat.io/v1beta2 +kind: Cryostat +metadata: + name: cryostat-sample +spec: + targetNamespaces: + - my-app-namespace + - my-other-app-namespace +``` + +#### Data Isolation +When installed in a multi-namespace manner, all users with access to a Cryostat instance have the same visibility and privileges to all data available to that Cryostat instance. Administrators deploying Cryostat instances must ensure that the users who have access to a Cryostat instance also have equivalent access to all the applications that can be monitored by that Cryostat instance. Otherwise, underprivileged users may use Cryostat to escalate permissions to start recordings and collect JFR data from applications that they do not otherwise have access to. + +For now, all authorization checks are done against the namespace where Cryostat is installed. For a user to use Cryostat with workloads in a target namespace, that user must have the necessary Kubernetes permissions in the namespace where Cryostat is installed. + ### Minimal Deployment The `spec.minimal` property determines what is deployed alongside Cryostat. This value is set to `false` by default, which tells the operator to deploy Cryostat, with a [customized Grafana](https://github.com/cryostatio/cryostat-grafana-dashboard) and a [Grafana Data Source for JFR files](https://github.com/cryostatio/jfr-datasource) as 3 containers within a Pod. When `minimal` is set to `true`, the Deployment consists of only the Cryostat container. ```yaml diff --git a/docs/multi-namespace.md b/docs/multi-namespace.md deleted file mode 100644 index 35e8e9479..000000000 --- a/docs/multi-namespace.md +++ /dev/null @@ -1,72 +0,0 @@ -## Configuring a Multi-Namespace Cryostat -In addition to installing [Cryostat](https://github.com/cryostatio/cryostat) into a single namespace, the Cryostat Operator also allows you to create a Cryostat installation that can work across multiple namespaces. This can be done using the `ClusterCryostat` API. The `ClusterCryostat` API contains all the same [configuration properties](config.md) as the `Cryostat` API does, but has some key differences to enable multi-namespace support that we'll outline below. - -```yaml -apiVersion: operator.cryostat.io/v1beta1 -kind: ClusterCryostat -metadata: - name: clustercryostat-sample -spec: - installNamespace: my-cryostat-namespace - targetNamespaces: - - my-app-namespace - - my-other-app-namespace - minimal: false - enableCertManager: true -``` -### Cluster Scoped -In contrast to the namespaced `Cryostat` API, the `ClusterCryostat` API is [cluster-scoped](https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-uris). This distinction was made to prevent privilege escalation situation where a user authorized to install Cryostat into a single namespace would be able to configure that Cryostat to connect to other namespaces where the user does not have access. In order to create a `ClusterCryostat`, a user must be authorized to do so for the entire cluster using a [Cluster Role Binding](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding). - -```yaml -apiVersion: operator.cryostat.io/v1beta1 -kind: ClusterCryostat -metadata: - name: clustercryostat-sample - namespace: "" # No namespace -``` - -### Data Isolation -When installed in a cluster-wide, multi-namespace manner, all users with access to a Cryostat instance have the same visibility and privileges to all data available to that Cryostat instance. Administrators deploying Cryostat instances must ensure that the users who have access to a Cryostat instance also have equivalent access to all the applications that can be monitored by that Cryostat instance. Otherwise, underprivileged users may use Cryostat to escalate permissions to start recordings and collect JFR data from applications that they do not otherwise have access to. - -For now, all authorization checks are done against the namespace where Cryostat is installed. For a user to use Cryostat with workloads in a target namespace, that user must have the necessary Kubernetes permissions in the namespace where Cryostat is installed. - -### Installation Namespace -Since the `ClusterCryostat` API is cluster-scoped, we cannot use the `metadata.namespace` property to determine where Cryostat should be installed. You must instead provide the namespace where Cryostat should be installed into using the `spec.installNamespace` property. - -For optimal security, we suggest using a different installation namespace than the namespace where the operator is installed, and a different namespace from where your target workloads will be. This is because the operator uses a larger set of permissions compared to Cryostat itself, and Cryostat may have more permissions than your target workloads. It is considered good practice to isolate more privileged Service Accounts from less privileged users, since a user authorized to create workloads can [access any Service Account](https://kubernetes.io/docs/concepts/security/rbac-good-practices/#workload-creation) in that namespace. - -```yaml -apiVersion: operator.cryostat.io/v1beta1 -kind: ClusterCryostat -metadata: - name: clustercryostat-sample -spec: - installNamespace: my-cryostat-namespace -``` - -### Target Namespaces -Specify the list of namespaces containing your workloads that you want your multi-namespace Cryostat installation to work with under the `spec.targetNamespaces` property. The resulting Cryostat will have permissions to access workloads only within these specified namespaces. Cryostat's own namespace (`spec.installNamespace`) is not implicitly included. - -```yaml -apiVersion: operator.cryostat.io/v1beta1 -kind: ClusterCryostat -metadata: - name: clustercryostat-sample -spec: - targetNamespaces: - - my-app-namespace - - my-other-app-namespace -``` - -### Other Configuration -All the [configuration options](config.md) available to the `Cryostat` API are also applicable to the `ClusterCryostat` API. - -```yaml -apiVersion: operator.cryostat.io/v1beta1 -kind: ClusterCryostat -metadata: - name: clustercryostat-sample -spec: - minimal: false - enableCertManager: true -``` diff --git a/internal/controllers/clustercryostat_controller.go b/internal/controllers/clustercryostat_controller.go deleted file mode 100644 index a33b23a62..000000000 --- a/internal/controllers/clustercryostat_controller.go +++ /dev/null @@ -1,104 +0,0 @@ -// 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 controllers - -import ( - "context" - - ctrl "sigs.k8s.io/controller-runtime" - - operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" - "github.com/cryostatio/cryostat-operator/internal/controllers/model" - - kerrors "k8s.io/apimachinery/pkg/api/errors" - "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 *ClusterCryostatReconciler implements CommonReconciler. -var _ CommonReconciler = (*ClusterCryostatReconciler)(nil) - -// CryostatReconciler reconciles a Cryostat object -type ClusterCryostatReconciler struct { - delegate *Reconciler - *ReconcilerConfig -} - -func NewClusterCryostatReconciler(config *ReconcilerConfig) (*ClusterCryostatReconciler, error) { - delegate, err := newReconciler(config, &operatorv1beta2.ClusterCryostat{}, false) - if err != nil { - return nil, err - } - return &ClusterCryostatReconciler{ - ReconcilerConfig: config, - delegate: delegate, - }, nil -} - -// +kubebuilder:rbac:groups="",resources=pods;services;services/finalizers;endpoints;persistentvolumeclaims;events;configmaps;secrets;serviceaccounts,verbs=* -// +kubebuilder:rbac:groups="",resources=replicationcontrollers,verbs=get -// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=create;get;list;update;watch;delete -// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=create;get;list;update;watch;delete -// +kubebuilder:rbac:groups=authentication.k8s.io,resources=tokenreviews,verbs=create -// +kubebuilder:rbac:groups=authorization.k8s.io,resources=selfsubjectaccessreviews,verbs=create -// +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch -// +kubebuilder:rbac:groups=oauth.openshift.io,resources=oauthaccesstokens,verbs=list;delete -// +kubebuilder:rbac:groups=config.openshift.io,resources=apiservers,verbs=get;list;update;watch -// +kubebuilder:rbac:groups=route.openshift.io,resources=routes;routes/custom-host,verbs=* -// +kubebuilder:rbac:groups=apps.openshift.io,resources=deploymentconfigs,verbs=get -// +kubebuilder:rbac:groups=apps,resources=deployments;daemonsets;replicasets;statefulsets,verbs=* -// +kubebuilder:rbac:namespace=system,groups=monitoring.coreos.com,resources=servicemonitors,verbs=get;create -// +kubebuilder:rbac:groups=cert-manager.io,resources=issuers;certificates,verbs=create;get;list;update;watch;delete -// +kubebuilder:rbac:groups=operator.cryostat.io,resources=clustercryostats,verbs=* -// +kubebuilder:rbac:groups=operator.cryostat.io,resources=clustercryostats/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=operator.cryostat.io,resources=clustercryostats/finalizers,verbs=update -// +kubebuilder:rbac:groups=console.openshift.io,resources=consolelinks,verbs=get;create;list;update;delete -// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=* - -// Reconcile processes a ClusterCryostat CR and manages a Cryostat installation accordingly -func (r *ClusterCryostatReconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { - reqLogger := r.Log.WithValues("Request.Name", request.Name) - - reqLogger.Info("Reconciling ClusterCryostat") - - // Fetch the Cryostat instance - cr := &operatorv1beta2.ClusterCryostat{} - err := r.Client.Get(ctx, request.NamespacedName, cr) - if err != nil { - if kerrors.IsNotFound(err) { - // Request object not found, could have been deleted after reconcile request. - // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. - // Return and don't requeue - reqLogger.Info("ClusterCryostat instance not found") - return reconcile.Result{}, nil - } - reqLogger.Error(err, "Error reading ClusterCryostat instance") - return reconcile.Result{}, err - } - - instance := model.FromClusterCryostat(cr) - return r.delegate.reconcileCryostat(ctx, instance) -} - -// SetupWithManager sets up the controller with the Manager. -func (r *ClusterCryostatReconciler) SetupWithManager(mgr ctrl.Manager) error { - return r.delegate.setupWithManager(mgr, r) -} - -func (r *ClusterCryostatReconciler) GetConfig() *ReconcilerConfig { - return r.ReconcilerConfig -} diff --git a/internal/controllers/clustercryostat_controller_test.go b/internal/controllers/clustercryostat_controller_test.go deleted file mode 100644 index 249d55e87..000000000 --- a/internal/controllers/clustercryostat_controller_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// 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 controllers_test - -import ( - "github.com/cryostatio/cryostat-operator/internal/controllers" - . "github.com/onsi/ginkgo/v2" -) - -var _ = Describe("ClusterCryostatController", func() { - c := controllerTest{ - clusterScoped: true, - constructorFunc: newClusterCryostatController, - } - - c.commonTests() -}) - -func newClusterCryostatController(config *controllers.ReconcilerConfig) (controllers.CommonReconciler, error) { - return controllers.NewClusterCryostatReconciler(config) -} diff --git a/internal/controllers/cryostat_controller.go b/internal/controllers/cryostat_controller.go index 97125870b..e32027d23 100644 --- a/internal/controllers/cryostat_controller.go +++ b/internal/controllers/cryostat_controller.go @@ -49,6 +49,22 @@ func NewCryostatReconciler(config *ReconcilerConfig) (*CryostatReconciler, error // +kubebuilder:rbac:groups=operator.cryostat.io,resources=cryostats,verbs=* // +kubebuilder:rbac:groups=operator.cryostat.io,resources=cryostats/status,verbs=get;update;patch // +kubebuilder:rbac:groups=operator.cryostat.io,resources=cryostats/finalizers,verbs=update +// +kubebuilder:rbac:groups="",resources=pods;services;services/finalizers;endpoints;persistentvolumeclaims;events;configmaps;secrets;serviceaccounts,verbs=* +// +kubebuilder:rbac:groups="",resources=replicationcontrollers,verbs=get +// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=create;get;list;update;watch;delete +// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=create;get;list;update;watch;delete +// +kubebuilder:rbac:groups=authentication.k8s.io,resources=tokenreviews,verbs=create +// +kubebuilder:rbac:groups=authorization.k8s.io,resources=selfsubjectaccessreviews,verbs=create +// +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch +// +kubebuilder:rbac:groups=oauth.openshift.io,resources=oauthaccesstokens,verbs=list;delete +// +kubebuilder:rbac:groups=config.openshift.io,resources=apiservers,verbs=get;list;update;watch +// +kubebuilder:rbac:groups=route.openshift.io,resources=routes;routes/custom-host,verbs=* +// +kubebuilder:rbac:groups=apps.openshift.io,resources=deploymentconfigs,verbs=get +// +kubebuilder:rbac:groups=apps,resources=deployments;daemonsets;replicasets;statefulsets,verbs=* +// +kubebuilder:rbac:namespace=system,groups=monitoring.coreos.com,resources=servicemonitors,verbs=get;create +// +kubebuilder:rbac:groups=cert-manager.io,resources=issuers;certificates,verbs=create;get;list;update;watch;delete +// +kubebuilder:rbac:groups=console.openshift.io,resources=consolelinks,verbs=get;create;list;update;delete +// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=* // Reconcile processes a Cryostat CR and manages a Cryostat installation accordingly func (r *CryostatReconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index 2530f4edd..5f70b4763 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -21,7 +21,6 @@ import ( var _ = Describe("CryostatController", func() { c := &controllerTest{ - clusterScoped: false, constructorFunc: newCryostatController, } diff --git a/internal/controllers/model/instance.go b/internal/controllers/model/instance.go index 04bcf50cf..80c3962f3 100644 --- a/internal/controllers/model/instance.go +++ b/internal/controllers/model/instance.go @@ -19,24 +19,22 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -// CryostatInstance is an abstraction to work with both cluster-scoped -// and namespace-scoped Cryostat CRDs. +// CryostatInstance is an abstraction to work with Cryostat CRDs. type CryostatInstance struct { // Name of the Cryostat CR. Name string // Namespace to install Cryostat into. For Cryostat, this comes from the - // CR's namespace. For ClusterCryostat, this comes from spec.InstallNamespace. + // CR's namespace. InstallNamespace string - // Namespaces that Cryostat should look for targets. For Cryostat, this is - // always the CR's namespace. For ClusterCryostat, this comes from spec.TargetNamespaces. + // Namespaces that Cryostat should look for targets. For Cryostat, this + // comes from spec.TargetNamespaces. TargetNamespaces []string // Namespaces that the operator has successfully set up RBAC for Cryostat to monitor targets - // in that namespace. For Cryostat, this is always the CR's namespace. - // For ClusterCryostat, this is a reference to status.TargetNamespaces. + // in that namespace. For Cryostat, this is a reference to status.TargetNamespaces. TargetNamespaceStatus *[]string - // Reference to the common Spec properties to both CRD types. + // Reference to the Cryostat Spec properties. Spec *operatorv1beta2.CryostatSpec - // Reference to the common Status properties to both CRD types. + // Reference to the Cryostat Status properties. Status *operatorv1beta2.CryostatStatus // The actual CR instance as a generic Kubernetes object. Object client.Object @@ -56,19 +54,3 @@ func FromCryostat(cr *operatorv1beta2.Cryostat) *CryostatInstance { Object: cr, } } - -// FromClusterCryostat creates a CryostatInstance from a ClusterCryostat CR -func FromClusterCryostat(cr *operatorv1beta2.ClusterCryostat) *CryostatInstance { - // TODO Remove this CRD - return &CryostatInstance{ - Name: cr.Name, - InstallNamespace: cr.Spec.InstallNamespace, - TargetNamespaces: cr.Spec.TargetNamespaces, - TargetNamespaceStatus: &cr.Status.TargetNamespaces, - - Spec: &cr.Spec.CryostatSpec, - Status: &cr.Status.CryostatStatus, - - Object: cr, - } -} diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index f15d4d3d5..812da566f 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -64,8 +64,7 @@ type ReconcilerConfig struct { common.ReconcilerTLS } -// CommonReconciler is an interface for shared behaviour -// between the ClusterCryostat and Cryostat reconcilers +// CommonReconciler is an interface for behaviour of the Cryostat reconciler type CommonReconciler interface { reconcile.Reconciler SetupWithManager(mgr ctrl.Manager) error @@ -137,11 +136,6 @@ func newReconciler(config *ReconcilerConfig, objType client.Object, isNamespaced } func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatInstance) (ctrl.Result, error) { - result, err := r.reconcile(ctx, cr) - return result, r.checkConflicts(cr, err) -} - -func (r *Reconciler) reconcile(ctx context.Context, cr *model.CryostatInstance) (ctrl.Result, error) { reqLogger := r.Log.WithValues("Request.Namespace", cr.InstallNamespace, "Request.Name", cr.Name) // Check if this Cryostat is being deleted @@ -522,31 +516,6 @@ func (r *Reconciler) deleteDeployment(ctx context.Context, deploy *appsv1.Deploy return nil } -const eventNameConflictReason = "CryostatNameConflict" - -func (r *Reconciler) checkConflicts(cr *model.CryostatInstance, err error) error { - if err == nil { - return nil - } - alreadyOwned, ok := err.(*controllerutil.AlreadyOwnedError) - if !ok { - return err - } - r.Log.Error(err, "Could not process custom resource") - metaType, err := meta.TypeAccessor(alreadyOwned.Object) - if err != nil { - return err - } - msg := fmt.Sprintf("This instance needs to manage the %s %s in namespace %s, but it is already owned by %s %s. "+ - "Please choose a different name for your instance.", - metaType.GetKind(), alreadyOwned.Object.GetName(), alreadyOwned.Object.GetNamespace(), - alreadyOwned.Owner.Kind, alreadyOwned.Owner.Name) - r.EventRecorder.Event(cr.Object, corev1.EventTypeWarning, eventNameConflictReason, msg) - // Log the event message as well - r.Log.Info(msg) - return alreadyOwned -} - func requeueIfIngressNotReady(log logr.Logger, err error) (reconcile.Result, error) { if err == ErrIngressNotReady { return reconcile.Result{RequeueAfter: 5 * time.Second}, nil diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index ec636d386..306455510 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -53,7 +53,6 @@ import ( ) type controllerTest struct { - clusterScoped bool constructorFunc func(*controllers.ReconcilerConfig) (controllers.CommonReconciler, error) } @@ -70,12 +69,11 @@ func (c *controllerTest) commonBeforeEach() *cryostatTestInput { GeneratedPasswords: []string{"grafana", "credentials_database", "jmx", "keystore"}, }, TestResources: &test.TestResources{ - Name: "cryostat", - Namespace: "test", - TLS: true, - ExternalTLS: true, - OpenShift: true, - ClusterScoped: c.clusterScoped, + Name: "cryostat", + Namespace: "test", + TLS: true, + ExternalTLS: true, + OpenShift: true, }, } t.objs = []ctrlclient.Object{ @@ -105,7 +103,7 @@ func (c *controllerTest) commonJustAfterEach(t *cryostatTestInput) { } func (t *cryostatTestInput) newReconcilerConfig(scheme *runtime.Scheme, client ctrlclient.Client) *controllers.ReconcilerConfig { - logger := zap.New().WithValues("cluster-scoped", t.ClusterScoped) + logger := zap.New() logf.SetLogger(logger) // Set InsightsURL in config, if provided @@ -1243,6 +1241,27 @@ func (c *controllerTest) commonTests() { t.expectNoCryostat() }) }) + Context("RoleBinding exists", func() { + JustBeforeEach(func() { + t.reconcileDeletedCryostat() + }) + It("should delete the RoleBinding", func() { + t.checkRoleBindingsDeleted() + }) + It("should delete Cryostat", func() { + t.expectNoCryostat() + }) + }) + Context("RoleBinding does not exist", func() { + JustBeforeEach(func() { + err := t.Client.Delete(context.Background(), t.NewRoleBinding(t.Namespace)) + Expect(err).ToNot(HaveOccurred()) + t.reconcileDeletedCryostat() + }) + It("should delete Cryostat", func() { + t.expectNoCryostat() + }) + }) }) Context("on OpenShift", func() { BeforeEach(func() { @@ -1784,26 +1803,20 @@ func (c *controllerTest) commonTests() { }) }) }) - Context("with a conflicting Cryostat CR", func() { - var other *controllerTest + Context("with an existing Cryostat CR", func() { var otherInput *cryostatTestInput - var reconcileErr error BeforeEach(func() { - other = &controllerTest{ - clusterScoped: !c.clusterScoped, - constructorFunc: getControllerFunc(!c.clusterScoped), - } - otherInput = other.commonBeforeEach() + otherInput = c.commonBeforeEach() }) JustBeforeEach(func() { - other.commonJustBeforeEach(otherInput) + c.commonJustBeforeEach(otherInput) // Controllers need to share client to have shared view of objects otherInput.Client = t.Client config := otherInput.newReconcilerConfig(otherInput.Client.Scheme(), otherInput.Client) - controller, err := other.constructorFunc(config) + controller, err := c.constructorFunc(config) Expect(err).ToNot(HaveOccurred()) otherInput.controller = controller @@ -1812,78 +1825,54 @@ func (c *controllerTest) commonTests() { }) JustAfterEach(func() { - other.commonJustAfterEach(otherInput) + c.commonJustAfterEach(otherInput) }) - Context("in the install namespace", func() { + Context("installing into its target namespace", func() { BeforeEach(func() { + // Set up the CRs so the Cryostat's namespace conflicts with the target + // namespace of the existing Cryostat + otherNS := "other-test" + otherInput.Namespace = otherNS + otherInput.TargetNamespaces = []string{otherNS, t.Namespace} t.TargetNamespaces = []string{t.Namespace} - otherInput.TargetNamespaces = t.TargetNamespaces - t.objs = append(t.objs, t.NewCryostat().Object, otherInput.NewCryostat().Object) + t.objs = append(t.objs, otherInput.NewNamespace(), t.NewCryostat().Object, otherInput.NewCryostat().Object) otherInput.objs = t.objs }) JustBeforeEach(func() { - // Try reconciling ClusterCryostat - reconcileErr = t.reconcileCryostatFullyWithError() - }) - - It("should fail to reconcile", func() { - t.expectAlreadyOwnedError(reconcileErr, "ConfigMap", t.NewLockConfigMap(), otherInput) - }) - - It("should emit a CryostatNameConflict event", func() { - t.expectNameConflictEvent() + // Try reconciling the new Cryostat + t.reconcileCryostatFully() }) - It("should not affect the existing installation", func() { - otherInput.expectResourcesUnaffected() + // Existing Cryostat installation should be unaffected + Context("existing installation", func() { + expectSuccessful(&otherInput) }) - Context("when deleted", func() { - JustBeforeEach(func() { - t.reconcileDeletedCryostat() - }) - - It("should not affect the existing installation", func() { - otherInput.expectResourcesUnaffected() - }) - - Context("on OpenShift", func() { - It("should not delete exisiting ConsoleLink", func() { - otherInput.expectConsoleLink() - }) - }) + // New installation should also be unaffected + Context("new installation", func() { + expectSuccessful(&t) }) }) - Context("in a target namespace", func() { - // We need to also distinguish which input is cluster-scoped - var clusterInput, nsInput *cryostatTestInput + Context("with a common target namespace", func() { BeforeEach(func() { - // Set up the CRs so the Cryostat conflicts with the target - // namespace of the ClusterCryostat, but not the install namespace - installNS := t.Namespace - targetNS := "other-test" - if otherInput.ClusterScoped { - clusterInput = otherInput - nsInput = t - } else { - clusterInput = t - nsInput = otherInput - } - clusterInput.Namespace = installNS - clusterInput.TargetNamespaces = []string{targetNS} - nsInput.Namespace = targetNS - nsInput.TargetNamespaces = t.TargetNamespaces - - t.objs = append(t.objs, nsInput.NewNamespace(), t.NewCryostat().Object, otherInput.NewCryostat().Object) + // Set up the CRs so the Cryostat's target namespace conflicts with the target + // namespace of another Cryostat + targetNS := "other-test-target" + otherNS := "other-test" + otherInput.Namespace = otherNS + otherInput.TargetNamespaces = []string{otherNS, targetNS} + t.TargetNamespaces = []string{t.Namespace, targetNS} + + t.objs = append(t.objs, t.NewOtherNamespace(targetNS), otherInput.NewNamespace(), t.NewCryostat().Object, otherInput.NewCryostat().Object) otherInput.objs = t.objs }) JustBeforeEach(func() { - // Try reconciling ClusterCryostat + // Try reconciling the new Cryostat t.reconcileCryostatFully() }) @@ -1894,7 +1883,7 @@ func (c *controllerTest) commonTests() { // New installation should also be unaffected Context("new installation", func() { - expectSuccessful(&otherInput) + expectSuccessful(&t) }) }) }) @@ -1934,6 +1923,30 @@ func (c *controllerTest) commonTests() { It("should update the target namespaces in Status", func() { t.expectTargetNamespaces() }) + + Context("when deleted", func() { + Context("RoleBindings exist", func() { + JustBeforeEach(func() { + t.reconcileDeletedCryostat() + }) + It("should delete the RoleBindings", func() { + t.checkRoleBindingsDeleted() + }) + It("should delete Cryostat", func() { + t.expectNoCryostat() + }) + }) + Context("RoleBinding does not exist", func() { + JustBeforeEach(func() { + err := t.Client.Delete(context.Background(), t.NewRoleBinding(targetNamespaces[0])) + Expect(err).ToNot(HaveOccurred()) + t.reconcileDeletedCryostat() + }) + It("should delete Cryostat", func() { + t.expectNoCryostat() + }) + }) + }) }) Context("with removed target namespaces", func() { @@ -2506,6 +2519,15 @@ func (t *cryostatTestInput) checkClusterRoleBindingDeleted() { Expect(kerrors.IsNotFound(err)).To(BeTrue()) } +func (t *cryostatTestInput) checkRoleBindingsDeleted() { + for _, ns := range t.TargetNamespaces { + expected := t.NewRoleBinding(ns) + binding := &rbacv1.RoleBinding{} + err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, binding) + Expect(kerrors.IsNotFound(err)).To(BeTrue()) + } +} + func (t *cryostatTestInput) expectNoRoutes() { svc := &openshiftv1.Route{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, svc) @@ -3119,21 +3141,12 @@ func (t *cryostatTestInput) getCryostatInstance() *model.CryostatInstance { } func (t *cryostatTestInput) lookupCryostatInstance() (*model.CryostatInstance, error) { - if t.ClusterScoped { - cr := &operatorv1beta2.ClusterCryostat{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name}, cr) - if err != nil { - return nil, err - } - return t.ConvertClusterToModel(cr), nil - } else { - cr := &operatorv1beta2.Cryostat{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, cr) - if err != nil { - return nil, err - } - return t.ConvertNamespacedToModel(cr), nil + cr := &operatorv1beta2.Cryostat{} + err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, cr) + if err != nil { + return nil, err } + return t.ConvertNamespacedToModel(cr), nil } func (t *cryostatTestInput) updateCryostatInstance(cr *model.CryostatInstance) { @@ -3146,40 +3159,11 @@ func (t *cryostatTestInput) reconcile() (reconcile.Result, error) { } func (t *cryostatTestInput) reconcileWithName(name string) (reconcile.Result, error) { - nsName := types.NamespacedName{Name: name} - if !t.ClusterScoped { - nsName.Namespace = t.Namespace - } + nsName := types.NamespacedName{Name: name, Namespace: t.Namespace} req := reconcile.Request{NamespacedName: nsName} return t.controller.Reconcile(context.Background(), req) } -func (t *cryostatTestInput) expectAlreadyOwnedError(reconcileErr error, expectedKind string, expected metav1.Object, otherInput *cryostatTestInput) { - Expect(reconcileErr).ToNot(BeNil()) - Expect(reconcileErr).To(BeAssignableToTypeOf(&controllerutil.AlreadyOwnedError{})) - - // Check identity of conflicting owner and conflicting object - alreadyOwned := reconcileErr.(*controllerutil.AlreadyOwnedError) - typeMeta, err := meta.TypeAccessor(alreadyOwned.Object) - Expect(err).ToNot(HaveOccurred()) - Expect(typeMeta.GetKind()).To(Equal(expectedKind)) - Expect(alreadyOwned.Object.GetName()).To(Equal(expected.GetName())) - Expect(alreadyOwned.Object.GetNamespace()).To(Equal(expected.GetNamespace())) - if otherInput.ClusterScoped { - Expect(alreadyOwned.Owner.Kind).To(Equal("ClusterCryostat")) - } else { - Expect(alreadyOwned.Owner.Kind).To(Equal("Cryostat")) - } - Expect(alreadyOwned.Owner.Name).To(Equal(otherInput.Name)) -} - -func (t *cryostatTestInput) expectNameConflictEvent() { - recorder := t.controller.GetConfig().EventRecorder.(*record.FakeRecorder) - var eventMsg string - Expect(recorder.Events).To(Receive(&eventMsg)) - Expect(eventMsg).To(ContainSubstring("CryostatNameConflict")) -} - func (t *cryostatTestInput) expectConsoleLink() { link := &consolev1.ConsoleLink{} expectedLink := t.NewConsoleLink() @@ -3198,10 +3182,3 @@ func (t *cryostatTestInput) expectTargetNamespaces() { cr := t.getCryostatInstance() Expect(*cr.TargetNamespaceStatus).To(ConsistOf(t.TargetNamespaces)) } - -func getControllerFunc(clusterScoped bool) func(*controllers.ReconcilerConfig) (controllers.CommonReconciler, error) { - if clusterScoped { - return newClusterCryostatController - } - return newCryostatController -} diff --git a/internal/main.go b/internal/main.go index b5d4c2fd4..6c51865af 100644 --- a/internal/main.go +++ b/internal/main.go @@ -152,18 +152,7 @@ func main() { } } - config := newReconcilerConfig(mgr, "ClusterCryostat", "clustercryostat-controller", openShift, - certManager, insightsURL) - clusterController, err := controllers.NewClusterCryostatReconciler(config) - if err != nil { - setupLog.Error(err, "unable to create controller", "controller", "ClusterCryostat") - os.Exit(1) - } - if err = clusterController.SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to add controller to manager", "controller", "ClusterCryostat") - os.Exit(1) - } - config = newReconcilerConfig(mgr, "Cryostat", "cryostat-controller", openShift, certManager, + config := newReconcilerConfig(mgr, "Cryostat", "cryostat-controller", openShift, certManager, insightsURL) controller, err := controllers.NewCryostatReconciler(config) if err != nil { diff --git a/internal/test/resources.go b/internal/test/resources.go index e12902889..1f4e16889 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -49,7 +49,6 @@ type TestResources struct { ExternalTLS bool OpenShift bool ReportReplicas int32 - ClusterScoped bool TargetNamespaces []string InsightsURL string } @@ -84,23 +83,7 @@ func NewTESTRESTMapper() meta.RESTMapper { } func (r *TestResources) NewCryostat() *model.CryostatInstance { - if r.ClusterScoped { - return r.ConvertClusterToModel(r.newClusterCryostat()) - } else { - return r.ConvertNamespacedToModel(r.newCryostat()) - } -} - -func (r *TestResources) newClusterCryostat() *operatorv1beta2.ClusterCryostat { - return &operatorv1beta2.ClusterCryostat{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name, - }, - Spec: operatorv1beta2.ClusterCryostatSpec{ - InstallNamespace: r.Namespace, - CryostatSpec: r.newCryostatSpec(), - }, - } + return r.ConvertNamespacedToModel(r.newCryostat()) } func (r *TestResources) newCryostat() *operatorv1beta2.Cryostat { @@ -141,18 +124,6 @@ func (r *TestResources) ConvertNamespacedToModel(cr *operatorv1beta2.Cryostat) * } } -func (r *TestResources) ConvertClusterToModel(cr *operatorv1beta2.ClusterCryostat) *model.CryostatInstance { - return &model.CryostatInstance{ - Name: cr.Name, - InstallNamespace: cr.Spec.InstallNamespace, - TargetNamespaces: cr.Spec.TargetNamespaces, - TargetNamespaceStatus: &cr.Status.TargetNamespaces, - Spec: &cr.Spec.CryostatSpec, - Status: &cr.Status.CryostatStatus, - Object: cr, - } -} - func (r *TestResources) NewCryostatWithSecrets() *model.CryostatInstance { cr := r.NewCryostat() key := "test.crt" @@ -2909,17 +2880,9 @@ func (r *TestResources) NewLockConfigMap() *corev1.ConfigMap { } func (r *TestResources) getClusterUniqueName() string { - prefix := "cryostat-" - if r.ClusterScoped { - prefix = "clustercryostat-" - } - return prefix + r.clusterUniqueSuffix() + return "cryostat-" + r.clusterUniqueSuffix() } func (r *TestResources) getClusterUniqueNameForCA() string { - prefix := "cryostat-ca-" - if r.ClusterScoped { - prefix = "clustercryostat-ca-" - } - return prefix + r.clusterUniqueSuffix() + return "cryostat-ca-" + r.clusterUniqueSuffix() } From 830046db5cfde32606ed4da6718fbc958c1ccde9 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:16:20 -0500 Subject: [PATCH 06/53] add scorecard test/suite selection (#746) (#747) (cherry picked from commit 2af4362802fd7389c18e40c82ee155df61485c33) Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> --- Makefile | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index df9c88915..81dc3a4ea 100644 --- a/Makefile +++ b/Makefile @@ -134,6 +134,14 @@ else KUSTOMIZE_DIR ?= config/default endif +# Specify which scorecard tests/suites to run +ifneq ($(SCORECARD_TEST_SELECTION),) +SCORECARD_TEST_SELECTOR := --selector='test in ($(SCORECARD_TEST_SELECTION))' +endif +ifneq ($(SCORECARD_TEST_SUITE),) +SCORECARD_TEST_SELECTOR := --selector=suite=$(SCORECARD_TEST_SUITE) +endif + ##@ General .PHONY: all @@ -158,9 +166,9 @@ endif test-scorecard: check_cert_manager kustomize operator-sdk ## Run scorecard tests. ifneq ($(SKIP_TESTS), true) $(call scorecard-setup) - $(call scorecard-cleanup); \ - trap cleanup EXIT; \ - $(OPERATOR_SDK) scorecard -n $(SCORECARD_NAMESPACE) -s cryostat-scorecard -w 20m $(BUNDLE_IMG) --pod-security=restricted + $(call scorecard-cleanup) ; \ + trap cleanup EXIT ; \ + $(OPERATOR_SDK) scorecard -n $(SCORECARD_NAMESPACE) -s cryostat-scorecard -w 20m $(BUNDLE_IMG) --pod-security=restricted $(SCORECARD_TEST_SELECTOR) endif .PHONY: clean-scorecard From f204ab3e56da72a0a1f6aa18c0d2e07562400e7f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:17:18 -0500 Subject: [PATCH 07/53] ci(gh): add comment when /build_test is finished (#745) (#748) (cherry picked from commit 6b2e997d823a5ffbc744423591f7ade1e376691f) Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> --- .github/workflows/test-ci-command.yml | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.github/workflows/test-ci-command.yml b/.github/workflows/test-ci-command.yml index d8e45a85d..2e1ffce2b 100644 --- a/.github/workflows/test-ci-command.yml +++ b/.github/workflows/test-ci-command.yml @@ -95,3 +95,40 @@ jobs: ref: ${{ needs.checkout-branch.outputs.PR_head_ref }} tag: ${{ needs.get-test-image-tag.outputs.tag }} sha: ${{ needs.checkout-branch.outputs.PR_head_sha }} + + successful-test: + runs-on: ubuntu-latest + needs: [run-test-jobs] + permissions: + pull-requests: write + steps: + - name: Leave Actions Run Comment + uses: actions/github-script@v6 + with: + script: | + const runURL = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${{ github.run_id }}`; + const commentBody = `\`/build_test\` completed successfully ✅. \n[View Actions Run](${runURL}).`; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + + cancelled-test: + if: (always() && contains(needs.*.result, 'failure')) + runs-on: ubuntu-latest + needs: [run-test-jobs] + steps: + - name: Leave Actions Run Comment + uses: actions/github-script@v6 + with: + script: | + const runURL = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${{ github.run_id }}`; + const commentBody = `\`/build_test\` : At least one test failed ❌. \n[View Actions Run](${runURL}).`; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); From 46c70ce9254c99fa9a8845534637b422470dd67c Mon Sep 17 00:00:00 2001 From: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:55:06 -0500 Subject: [PATCH 08/53] chore(api): remove MaxWsConnections (#742) * remove MaxWsConnections * keep v1beta1 spec * add test v1->v2 --- api/v1beta1/cryostat_conversion.go | 2 -- api/v1beta1/cryostat_conversion_test.go | 15 +++++++++++---- api/v1beta2/cryostat_types.go | 5 ----- .../cryostat-operator.clusterserviceversion.yaml | 12 ------------ .../manifests/operator.cryostat.io_cryostats.yaml | 12 ------------ .../crd/bases/operator.cryostat.io_cryostats.yaml | 12 ------------ .../cryostat-operator.clusterserviceversion.yaml | 12 ------------ docs/config.md | 12 ------------ .../resource_definitions/resource_definitions.go | 11 ----------- internal/controllers/reconciler_test.go | 8 -------- internal/test/resources.go | 15 --------------- 11 files changed, 11 insertions(+), 105 deletions(-) diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index fd818f608..bb56a27cd 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -50,7 +50,6 @@ func convertSpecTo(src *CryostatSpec, dst *operatorv1beta2.CryostatSpec) { dst.ServiceOptions = convertServiceOptionsTo(src.ServiceOptions) dst.NetworkOptions = convertNetworkOptionsTo(src.NetworkOptions) dst.ReportOptions = convertReportOptionsTo(src.ReportOptions) - dst.MaxWsConnections = src.MaxWsConnections dst.JmxCacheOptions = convertJmxCacheOptionsTo(src.JmxCacheOptions) dst.Resources = convertResourceOptionsTo(src.Resources) dst.AuthProperties = convertAuthPropertiesTo(src.AuthProperties) @@ -336,7 +335,6 @@ func convertSpecFrom(src *operatorv1beta2.CryostatSpec, dst *CryostatSpec) { dst.ServiceOptions = convertServiceOptionsFrom(src.ServiceOptions) dst.NetworkOptions = convertNetworkOptionsFrom(src.NetworkOptions) dst.ReportOptions = convertReportOptionsFrom(src.ReportOptions) - dst.MaxWsConnections = src.MaxWsConnections dst.JmxCacheOptions = convertJmxCacheOptionsFrom(src.JmxCacheOptions) dst.Resources = convertResourceOptionsFrom(src.Resources) dst.AuthProperties = convertAuthPropertiesFrom(src.AuthProperties) diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go index ae9129692..80a7dc41b 100644 --- a/api/v1beta1/cryostat_conversion_test.go +++ b/api/v1beta1/cryostat_conversion_test.go @@ -55,7 +55,7 @@ var _ = Describe("Cryostat", func() { Expect(converted).To(Equal(newCR)) }, - tableEntries(), + tableEntriesTo(), ) DescribeTable("converting from v1beta2 to v1beta1", @@ -71,11 +71,20 @@ var _ = Describe("Cryostat", func() { Expect(converted).To(Equal(oldCR)) }, - tableEntries(), + tableEntriesFrom(), ) }) +func tableEntriesTo() []TableEntry { + return append(tableEntries(), Entry("WS connections", (*test.TestResources).NewCryostatWithWsConnectionsSpecV1Beta1, + (*test.TestResources).NewCryostat)) +} + +func tableEntriesFrom() []TableEntry { + return tableEntries() +} + func tableEntries() []TableEntry { return []TableEntry{ Entry("defaults", (*test.TestResources).NewCryostatV1Beta1, @@ -134,8 +143,6 @@ func tableEntries() []TableEntry { (*test.TestResources).NewCryostatWithBuiltInPortConfigDisabled), Entry("JMX cache options", (*test.TestResources).NewCryostatWithJmxCacheOptionsSpecV1Beta1, (*test.TestResources).NewCryostatWithJmxCacheOptionsSpec), - Entry("WS connections", (*test.TestResources).NewCryostatWithWsConnectionsSpecV1Beta1, - (*test.TestResources).NewCryostatWithWsConnectionsSpec), Entry("subprocess heap", (*test.TestResources).NewCryostatWithReportSubprocessHeapSpecV1Beta1, (*test.TestResources).NewCryostatWithReportSubprocessHeapSpec), Entry("security", (*test.TestResources).NewCryostatWithSecurityOptionsV1Beta1, diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index e0e1f5279..5bd3a8584 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -64,11 +64,6 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec ReportOptions *ReportConfiguration `json:"reportOptions,omitempty"` - // The maximum number of WebSocket client connections allowed (minimum 1, default unlimited). - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Max WebSocket Connections",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} - // +kubebuilder:validation:Minimum=1 - MaxWsConnections int32 `json:"maxWsConnections,omitempty"` // Options to customize the JMX target connections cache for the Cryostat application. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="JMX Connections Cache Options" diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 5cb15f3da..80c9c28d2 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -182,12 +182,6 @@ spec: path: jmxCredentialsDatabaseOptions.databaseSecretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret - - description: The maximum number of WebSocket client connections allowed (minimum - 1, default unlimited). - displayName: Max WebSocket Connections - path: maxWsConnections - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options @@ -588,12 +582,6 @@ spec: path: jmxCredentialsDatabaseOptions.databaseSecretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret - - description: The maximum number of WebSocket client connections allowed (minimum - 1, default unlimited). - displayName: Max WebSocket Connections - path: maxWsConnections - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 26a20df2b..cf3940874 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -127,12 +127,6 @@ spec: credentials database. type: string type: object - maxWsConnections: - description: The maximum number of WebSocket client connections allowed - (minimum 1, default unlimited). - format: int32 - minimum: 1 - type: integer minimal: description: Deploy a pared-down Cryostat instance with no Grafana Dashboard or JFR Data Source. @@ -4844,12 +4838,6 @@ spec: credentials database. type: string type: object - maxWsConnections: - description: The maximum number of WebSocket client connections allowed - (minimum 1, default unlimited). - format: int32 - minimum: 1 - type: integer minimal: description: Deploy a pared-down Cryostat instance with no Grafana Dashboard or JFR Data Source. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 694eaaa07..11de5de7c 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -117,12 +117,6 @@ spec: credentials database. type: string type: object - maxWsConnections: - description: The maximum number of WebSocket client connections allowed - (minimum 1, default unlimited). - format: int32 - minimum: 1 - type: integer minimal: description: Deploy a pared-down Cryostat instance with no Grafana Dashboard or JFR Data Source. @@ -4834,12 +4828,6 @@ spec: credentials database. type: string type: object - maxWsConnections: - description: The maximum number of WebSocket client connections allowed - (minimum 1, default unlimited). - format: int32 - minimum: 1 - type: integer minimal: description: Deploy a pared-down Cryostat instance with no Grafana Dashboard or JFR Data Source. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 6b5b54117..a53b0a9f5 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -138,12 +138,6 @@ spec: path: jmxCredentialsDatabaseOptions.databaseSecretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret - - description: The maximum number of WebSocket client connections allowed (minimum - 1, default unlimited). - displayName: Max WebSocket Connections - path: maxWsConnections - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options @@ -542,12 +536,6 @@ spec: path: jmxCredentialsDatabaseOptions.databaseSecretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret - - description: The maximum number of WebSocket client connections allowed (minimum - 1, default unlimited). - displayName: Max WebSocket Connections - path: maxWsConnections - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options diff --git a/docs/config.md b/docs/config.md index a57840b0c..afb374637 100644 --- a/docs/config.md +++ b/docs/config.md @@ -281,18 +281,6 @@ spec: When running on OpenShift, labels and annotations specified in `coreConfig` and `grafanaConfig` will be applied to the coresponding Routes created by the operator. -### Cryostat Client Options -The `maxWsConnections` property optionally specifies the maximum number of WebSocket client connections allowed. -The default number of `maxWsConnections` is unlimited. -```yaml -apiVersion: operator.cryostat.io/v1beta1 -kind: Cryostat -metadata: - name: cryostat-sample -spec: - maxWsConnections: 2 -``` - ### JMX Cache Configuration Options Cryostat's target JMX connection cache can be optionally configured with `targetCacheSize` and `targetCacheTTL`. `targetCacheSize` sets the maximum number of JMX connections cached by Cryostat. diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 5386aea96..06c1a9d65 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -737,17 +737,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag envs = append(envs, insightsEnvs...) } - if cr.Spec.MaxWsConnections != 0 { - maxWsConnections := strconv.Itoa(int(cr.Spec.MaxWsConnections)) - maxWsConnectionsEnv := []corev1.EnvVar{ - { - Name: "CRYOSTAT_MAX_WS_CONNECTIONS", - Value: maxWsConnections, - }, - } - envs = append(envs, maxWsConnectionsEnv...) - } - targetCacheSize := "-1" targetCacheTTL := "10" if cr.Spec.JmxCacheOptions != nil { diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 306455510..b6e2657ba 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -1622,14 +1622,6 @@ func (c *controllerTest) commonTests() { JustBeforeEach(func() { t.reconcileCryostatFully() }) - Context("containing MaxWsConnections", func() { - BeforeEach(func() { - t.objs = append(t.objs, t.NewCryostatWithWsConnectionsSpec().Object) - }) - It("should set max WebSocket connections", func() { - t.checkCoreHasEnvironmentVariables(t.NewWsConnectionsEnv()) - }) - }) Context("containing SubProcessMaxHeapSize", func() { BeforeEach(func() { t.objs = append(t.objs, t.NewCryostatWithReportSubprocessHeapSpec().Object) diff --git a/internal/test/resources.go b/internal/test/resources.go index 1f4e16889..d94ac5403 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -560,12 +560,6 @@ func (r *TestResources) NewCryostatWithJmxCacheOptionsSpec() *model.CryostatInst return cr } -func (r *TestResources) NewCryostatWithWsConnectionsSpec() *model.CryostatInstance { - cr := r.NewCryostat() - cr.Spec.MaxWsConnections = 10 - return cr -} - func (r *TestResources) NewCryostatWithReportSubprocessHeapSpec() *model.CryostatInstance { cr := r.NewCryostat() if cr.Spec.ReportOptions == nil { @@ -1578,15 +1572,6 @@ func (r *TestResources) NewGrafanaEnvFromSource() []corev1.EnvFromSource { } } -func (r *TestResources) NewWsConnectionsEnv() []corev1.EnvVar { - return []corev1.EnvVar{ - { - Name: "CRYOSTAT_MAX_WS_CONNECTIONS", - Value: "10", - }, - } -} - func (r *TestResources) NewReportSubprocessHeapEnv() []corev1.EnvVar { return []corev1.EnvVar{ { From fcf7a8c50493ee4de3036fd766e4c19137a8966a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 16:28:43 -0500 Subject: [PATCH 09/53] test(scorecard): scorecard tests for recording management (backport #698) (#752) * test(scorecard): scorecard tests for recording management (#698) * test(scorecard): scorecard tests for recording management Signed-off-by: Thuan Vo * fixup(scorecard): fix cr cleanup func * test(scorecard): registry recording test to suite * chore(scorecard): reorganize client def * chore(scorecard): clean up common setup func * chore(bundle): regenerate bundle with scorecard tag * chore(bundle): correct image tag in bundle * fix(bundle): add missing scorecard test config patch * feat(scorecard): scaffold cryostat API client * chore(scorecard): clean up API client * test(scorecard): implement recording scorecard test * fixup(scorecard): correctly add scorecard test via hack templates * fix(client): ignore unverified tls certs and base64 oauth token * chore(bundle): split cryostat tests to separate stage * fix(scorecard): extend default transport instead of overwriting * chore(scorecard): refactor client to support multi-part * fixup(client): fix request verb * fix(client): fix recording create form format * fix(scorecard): create stored credentials for target JVM * fix(scorecard): fix 502 status error * chore(scorecard): simplify client def * chore(scorecard): fetch recordings to ensure action is correctly performed * test(scorecard): test generating report for a recording * chore(scorecard): clean up * test(scorecard): list archives in tests * ci(scorecard): reconfigure ingress for kind * ci(k8s): correct cluster name * test(scorecard): use role instead of clusterrole for oauth rules * test(scorecard): parse health response for additional checks * chore(scorecard): add missing newline in logs * chore(scorecard): check status code before parsing body in health check * test(scorecard): add custom target discovery to recording scorecard test * add EOF wait and resp headers * add resp headers * chore(client): configure all clients to send safe requests * fix(clients): add missing content-type header * fix(scorecard): add missing test name in help message * chore(client): create new http requests when retrying * chore(bundle): update scorecard image tags --------- Signed-off-by: Thuan Vo Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Co-authored-by: Ming Wang (cherry picked from commit cfcbfc74fab65b78bf5fb63a8c5abe658d65fe6a) # Conflicts: # bundle/manifests/cryostat-operator.clusterserviceversion.yaml * Fix conflicts --------- Co-authored-by: Thuan Vo Co-authored-by: Elliott Baron --- .github/workflows/test-ci-reusable.yml | 26 +- ...yostat-operator.clusterserviceversion.yaml | 8 +- .../operator.cryostat.io_cryostats.yaml | 6 + bundle/tests/scorecard/config.yaml | 15 +- .../bases/operator.cryostat.io_cryostats.yaml | 6 + ...yostat-operator.clusterserviceversion.yaml | 6 + config/rbac/oauth_client.yaml | 1 - config/scorecard/bases/config.yaml | 4 +- config/scorecard/patches/custom.config.yaml | 18 +- hack/custom.config.yaml.in | 14 +- .../images/custom-scorecard-tests/main.go | 4 + .../rbac/scorecard_role.yaml | 49 ++ internal/test/scorecard/clients.go | 512 ++++++++++++++++-- internal/test/scorecard/common_utils.go | 399 ++++++++++++++ internal/test/scorecard/openshift.go | 7 + internal/test/scorecard/tests.go | 367 ++++--------- internal/test/scorecard/types.go | 146 +++++ 17 files changed, 1282 insertions(+), 306 deletions(-) create mode 100644 internal/test/scorecard/common_utils.go create mode 100644 internal/test/scorecard/types.go diff --git a/.github/workflows/test-ci-reusable.yml b/.github/workflows/test-ci-reusable.yml index a1c9be76f..860971ac5 100644 --- a/.github/workflows/test-ci-reusable.yml +++ b/.github/workflows/test-ci-reusable.yml @@ -118,11 +118,29 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Kind cluster + uses: helm/kind-action@v1.8.0 + with: + config: .github/kind-config.yaml + cluster_name: ci-${{ github.run_id }} + wait: 1m + ignore_failed_clean: true + - name: Set up Ingress Controller run: | - kind create cluster --config=".github/kind-config.yaml" -n ci-${{ github.run_id }} - # Enabling Ingress + # Install nginx ingress controller kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml - kubectl rollout status -w deployment/ingress-nginx-controller -n ingress-nginx --timeout 5m + kubectl rollout status -w \ + deployment/ingress-nginx-controller \ + -n ingress-nginx --timeout 5m + + # Lower the number of worker processes + kubectl patch cm/ingress-nginx-controller \ + --type merge \ + -p '{"data":{"worker-processes":"1"}}' \ + -n ingress-nginx + + # Modify /etc/hosts to resolve hostnames + ip_address=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ci-${{ github.run_id }}-control-plane) + echo "$ip_address testing.cryostat" | sudo tee -a /etc/hosts - name: Install Operator Lifecycle Manager run: curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.24.0/install.sh | bash -s v0.24.0 - name: Install Cert Manager @@ -140,8 +158,6 @@ jobs: SCORECARD_REGISTRY_PASSWORD="${{ secrets.GITHUB_TOKEN }}" \ BUNDLE_IMG="${{ steps.push-bundle-to-ghcr.outputs.registry-path }}" \ make test-scorecard - - name: Clean up Kind cluster - run: kind delete cluster -n ci-${{ github.run_id }} - name: Set latest commit status as ${{ job.status }} uses: myrotvorets/set-commit-status-action@master if: always() diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 80c9c28d2..04a0f5f58 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -54,7 +54,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-02-15T20:45:48Z" + createdAt: "2024-03-06T21:13:39Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -182,6 +182,12 @@ spec: path: jmxCredentialsDatabaseOptions.databaseSecretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret + - description: The maximum number of WebSocket client connections allowed (minimum + 1, default unlimited). + displayName: Max WebSocket Connections + path: maxWsConnections + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index cf3940874..13918ffcc 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -127,6 +127,12 @@ spec: credentials database. type: string type: object + maxWsConnections: + description: The maximum number of WebSocket client connections allowed + (minimum 1, default unlimited). + format: int32 + minimum: 1 + type: integer minimal: description: Deploy a pared-down Cryostat instance with no Grafana Dashboard or JFR Data Source. diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml index ba7284c76..12b393613 100644 --- a/bundle/tests/scorecard/config.yaml +++ b/bundle/tests/scorecard/config.yaml @@ -66,10 +66,11 @@ stages: storage: spec: mountPath: {} +- tests: - entrypoint: - cryostat-scorecard-tests - operator-install - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20231011144522 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416 labels: suite: cryostat test: operator-install @@ -79,13 +80,23 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20231011144522 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416 labels: suite: cryostat test: cryostat-cr storage: spec: mountPath: {} + - entrypoint: + - cryostat-scorecard-tests + - cryostat-recording + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416 + labels: + suite: cryostat + test: cryostat-recording + storage: + spec: + mountPath: {} storage: spec: mountPath: {} diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 11de5de7c..afa2befdd 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -117,6 +117,12 @@ spec: credentials database. type: string type: object + maxWsConnections: + description: The maximum number of WebSocket client connections allowed + (minimum 1, default unlimited). + format: int32 + minimum: 1 + type: integer minimal: description: Deploy a pared-down Cryostat instance with no Grafana Dashboard or JFR Data Source. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index a53b0a9f5..17d9dda93 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -536,6 +536,12 @@ spec: path: jmxCredentialsDatabaseOptions.databaseSecretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret + - description: The maximum number of WebSocket client connections allowed (minimum + 1, default unlimited). + displayName: Max WebSocket Connections + path: maxWsConnections + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options diff --git a/config/rbac/oauth_client.yaml b/config/rbac/oauth_client.yaml index d8c6693c8..b1c50771e 100644 --- a/config/rbac/oauth_client.yaml +++ b/config/rbac/oauth_client.yaml @@ -3,7 +3,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: oauth-client rules: - apiGroups: diff --git a/config/scorecard/bases/config.yaml b/config/scorecard/bases/config.yaml index c77047841..7924d1df6 100644 --- a/config/scorecard/bases/config.yaml +++ b/config/scorecard/bases/config.yaml @@ -3,5 +3,7 @@ kind: Configuration metadata: name: config stages: -- parallel: true +- parallel: true # Build-in Tests + tests: [] +- parallel: false # Cryostat Custom Tests tests: [] diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 786cf388c..527eac9ad 100644 --- a/config/scorecard/patches/custom.config.yaml +++ b/config/scorecard/patches/custom.config.yaml @@ -3,22 +3,32 @@ path: /serviceaccount value: cryostat-scorecard - op: add - path: /stages/0/tests/- + path: /stages/1/tests/- value: entrypoint: - cryostat-scorecard-tests - operator-install - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20231011144522" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416" labels: suite: cryostat test: operator-install - op: add - path: /stages/0/tests/- + path: /stages/1/tests/- value: entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20231011144522" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416" labels: suite: cryostat test: cryostat-cr +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-recording + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416" + labels: + suite: cryostat + test: cryostat-recording diff --git a/hack/custom.config.yaml.in b/hack/custom.config.yaml.in index d6bc3e714..487462006 100644 --- a/hack/custom.config.yaml.in +++ b/hack/custom.config.yaml.in @@ -2,7 +2,7 @@ path: /serviceaccount value: cryostat-scorecard - op: add - path: /stages/0/tests/- + path: /stages/1/tests/- value: entrypoint: - cryostat-scorecard-tests @@ -12,7 +12,7 @@ suite: cryostat test: operator-install - op: add - path: /stages/0/tests/- + path: /stages/1/tests/- value: entrypoint: - cryostat-scorecard-tests @@ -21,3 +21,13 @@ labels: suite: cryostat test: cryostat-cr +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-recording + image: "${CUSTOM_SCORECARD_IMG}" + labels: + suite: cryostat + test: cryostat-recording diff --git a/internal/images/custom-scorecard-tests/main.go b/internal/images/custom-scorecard-tests/main.go index 310ea1ef9..62808a82f 100644 --- a/internal/images/custom-scorecard-tests/main.go +++ b/internal/images/custom-scorecard-tests/main.go @@ -79,6 +79,7 @@ func printValidTests() []scapiv1alpha3.TestResult { str := fmt.Sprintf("valid tests for this image include: %s", strings.Join([]string{ tests.OperatorInstallTestName, tests.CryostatCRTestName, + tests.CryostatRecordingTestName, }, ",")) result.Errors = append(result.Errors, str) @@ -90,6 +91,7 @@ func validateTests(testNames []string) bool { switch testName { case tests.OperatorInstallTestName: case tests.CryostatCRTestName: + case tests.CryostatRecordingTestName: default: return false } @@ -108,6 +110,8 @@ func runTests(testNames []string, bundle *apimanifests.Bundle, namespace string, results = append(results, tests.OperatorInstallTest(bundle, namespace)) case tests.CryostatCRTestName: results = append(results, tests.CryostatCRTest(bundle, namespace, openShiftCertManager)) + case tests.CryostatRecordingTestName: + results = append(results, tests.CryostatRecordingTest(bundle, namespace, openShiftCertManager)) default: log.Fatalf("unknown test found: %s", testName) } diff --git a/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml b/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml index de76f86d7..d350e6464 100644 --- a/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml +++ b/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml @@ -53,6 +53,55 @@ rules: - cryostats/status verbs: - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - get +# Permissions for default OAuth configurations +- apiGroups: + - operator.cryostat.io + resources: + - cryostats + verbs: + - create + - patch + - delete + - get +- apiGroups: + - "" + resources: + - pods + - pods/exec + - services + verbs: + - create + - patch + - delete + - get +- apiGroups: + - "" + resources: + - replicationcontrollers + - endpoints + verbs: + - get +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - get +- apiGroups: + - apps + resources: + - daemonsets + - replicasets + - statefulsets + verbs: + - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 2cf994c34..ffe3ad79e 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -16,16 +16,25 @@ package scorecard import ( "context" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/wait" + + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" - ctrl "sigs.k8s.io/controller-runtime" ) // CryostatClientset is a Kubernetes Clientset that can also @@ -35,10 +44,15 @@ type CryostatClientset struct { operatorClient *OperatorCRDClient } +// OperatorCRDs returns a OperatorCRDClient +func (c *CryostatClientset) OperatorCRDs() *OperatorCRDClient { + return c.operatorClient +} + // NewClientset creates a CryostatClientset func NewClientset() (*CryostatClientset, error) { // Get in-cluster REST config from pod - config, err := ctrl.GetConfig() + config, err := rest.InClusterConfig() if err != nil { return nil, err } @@ -60,9 +74,19 @@ func NewClientset() (*CryostatClientset, error) { }, nil } -// OperatorCRDs returns a OperatorCRDClient -func (c *CryostatClientset) OperatorCRDs() *OperatorCRDClient { - return c.operatorClient +// OperatorCRDClient is a Kubernetes REST client for performing operations on +// Cryostat Operator custom resources +type OperatorCRDClient struct { + client *rest.RESTClient +} + +// Cryostats returns a CryostatClient configured to a specific namespace +func (c *OperatorCRDClient) Cryostats(namespace string) *CryostatClient { + return &CryostatClient{ + restClient: c.client, + namespace: namespace, + resource: "cryostats", + } } func newOperatorCRDClient(config *rest.Config) (*OperatorCRDClient, error) { @@ -75,19 +99,21 @@ func newOperatorCRDClient(config *rest.Config) (*OperatorCRDClient, error) { }, nil } -// OperatorCRDClient is a Kubernetes REST client for performing operations on -// Cryostat Operator custom resources -type OperatorCRDClient struct { - client *rest.RESTClient +func newCRDClient(config *rest.Config) (*rest.RESTClient, error) { + scheme := runtime.NewScheme() + if err := operatorv1beta1.AddToScheme(scheme); err != nil { + return nil, err + } + return newRESTClientForGV(config, scheme, &operatorv1beta1.GroupVersion) } -// Cryostats returns a CryostatClient configured to a specific namespace -func (c *OperatorCRDClient) Cryostats(namespace string) *CryostatClient { - return &CryostatClient{ - restClient: c.client, - namespace: namespace, - resource: "cryostats", - } +func newRESTClientForGV(config *rest.Config, scheme *runtime.Scheme, gv *schema.GroupVersion) (*rest.RESTClient, error) { + configCopy := *config + configCopy.GroupVersion = gv + configCopy.APIPath = "/apis" + configCopy.ContentType = runtime.ContentTypeJSON + configCopy.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: serializer.NewCodecFactory(scheme)} + return rest.RESTClientFor(&configCopy) } // CryostatClient contains methods to perform operations on @@ -118,23 +144,6 @@ func (c *CryostatClient) Delete(ctx context.Context, name string, options *metav return delete(ctx, c.restClient, c.resource, c.namespace, name, options) } -func newCRDClient(config *rest.Config) (*rest.RESTClient, error) { - scheme := runtime.NewScheme() - if err := operatorv1beta1.AddToScheme(scheme); err != nil { - return nil, err - } - return newRESTClientForGV(config, scheme, &operatorv1beta1.GroupVersion) -} - -func newRESTClientForGV(config *rest.Config, scheme *runtime.Scheme, gv *schema.GroupVersion) (*rest.RESTClient, error) { - configCopy := *config - configCopy.GroupVersion = gv - configCopy.APIPath = "/apis" - configCopy.ContentType = runtime.ContentTypeJSON - configCopy.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: serializer.NewCodecFactory(scheme)} - return rest.RESTClientFor(&configCopy) -} - func get[r runtime.Object](ctx context.Context, c rest.Interface, res string, ns string, name string, result r) (r, error) { err := c.Get(). Namespace(ns).Resource(res). @@ -162,3 +171,436 @@ func delete(ctx context.Context, c rest.Interface, res string, ns string, name s Name(name).Body(opts).Do(ctx). Error() } + +// CryostatRESTClientset contains methods to interact with +// the Cryostat API +type CryostatRESTClientset struct { + TargetClient *TargetClient + RecordingClient *RecordingClient + CredentialClient *CredentialClient +} + +func (c *CryostatRESTClientset) Targets() *TargetClient { + return c.TargetClient +} + +func (c *CryostatRESTClientset) Recordings() *RecordingClient { + return c.RecordingClient +} + +func (c *CryostatRESTClientset) Credential() *CredentialClient { + return c.CredentialClient +} + +func NewCryostatRESTClientset(base *url.URL) *CryostatRESTClientset { + commonClient := &commonCryostatRESTClient{ + Base: base, + Client: NewHttpClient(), + } + + return &CryostatRESTClientset{ + TargetClient: &TargetClient{ + commonCryostatRESTClient: commonClient, + }, + RecordingClient: &RecordingClient{ + commonCryostatRESTClient: commonClient, + }, + CredentialClient: &CredentialClient{ + commonCryostatRESTClient: commonClient, + }, + } +} + +type commonCryostatRESTClient struct { + Base *url.URL + *http.Client +} + +// Client for Cryostat Target resources +type TargetClient struct { + *commonCryostatRESTClient +} + +func (client *TargetClient) List(ctx context.Context) ([]Target, error) { + url := client.Base.JoinPath("/api/v1/targets") + header := make(http.Header) + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodGet, url.String(), nil, header) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return nil, fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + targets := make([]Target, 0) + err = ReadJSON(resp, &targets) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return targets, nil +} + +func (client *TargetClient) Create(ctx context.Context, options *Target) (*Target, error) { + url := client.Base.JoinPath("/api/v2/targets") + header := make(http.Header) + header.Add("Content-Type", "application/x-www-form-urlencoded") + header.Add("Accept", "*/*") + body := options.ToFormData() + + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), &body, header) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return nil, fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + targetResp := &CustomTargetResponse{} + err = ReadJSON(resp, targetResp) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return targetResp.Data.Result, nil +} + +// Client for Cryostat Recording resources +type RecordingClient struct { + *commonCryostatRESTClient +} + +func (client *RecordingClient) List(ctx context.Context, connectUrl string) ([]Recording, error) { + url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings", url.PathEscape(connectUrl))) + header := make(http.Header) + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodGet, url.String(), nil, header) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return nil, fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + recordings := make([]Recording, 0) + err = ReadJSON(resp, &recordings) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return recordings, nil +} + +func (client *RecordingClient) Get(ctx context.Context, connectUrl string, recordingName string) (*Recording, error) { + recordings, err := client.List(ctx, connectUrl) + if err != nil { + return nil, err + } + + for _, rec := range recordings { + if rec.Name == recordingName { + return &rec, nil + } + } + + return nil, fmt.Errorf("recording %s does not exist for target %s", recordingName, connectUrl) +} + +func (client *RecordingClient) Create(ctx context.Context, connectUrl string, options *RecordingCreateOptions) (*Recording, error) { + url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings", url.PathEscape(connectUrl))) + body := options.ToFormData() + header := make(http.Header) + header.Add("Content-Type", "application/x-www-form-urlencoded") + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), &body, header) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return nil, fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + recording := &Recording{} + err = ReadJSON(resp, recording) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return recording, err +} + +func (client *RecordingClient) Archive(ctx context.Context, connectUrl string, recordingName string) (string, error) { + url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings/%s", url.PathEscape(connectUrl), url.PathEscape(recordingName))) + body := "SAVE" + header := make(http.Header) + header.Add("Content-Type", "text/plain") + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodPatch, url.String(), &body, header) + if err != nil { + return "", err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return "", fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + bodyAsString, err := ReadString(resp) + if err != nil { + return "", fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return bodyAsString, nil +} + +func (client *RecordingClient) Stop(ctx context.Context, connectUrl string, recordingName string) error { + url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings/%s", url.PathEscape(connectUrl), url.PathEscape(recordingName))) + body := "STOP" + header := make(http.Header) + header.Add("Content-Type", "text/plain") + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodPatch, url.String(), &body, header) + if err != nil { + return err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + return nil +} + +func (client *RecordingClient) Delete(ctx context.Context, connectUrl string, recordingName string) error { + url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings/%s", url.PathEscape(connectUrl), url.PathEscape(recordingName))) + header := make(http.Header) + + resp, err := SendRequest(ctx, client.Client, http.MethodDelete, url.String(), nil, header) + if err != nil { + return err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + return nil +} + +func (client *RecordingClient) GenerateReport(ctx context.Context, connectUrl string, recordingName *Recording) (map[string]interface{}, error) { + reportURL := recordingName.ReportURL + + if len(reportURL) < 1 { + return nil, fmt.Errorf("report URL is not available") + } + + header := make(http.Header) + header.Add("Accept", "application/json") + + resp, err := SendRequest(ctx, client.Client, http.MethodGet, reportURL, nil, header) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return nil, fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + report := make(map[string]interface{}, 0) + err = ReadJSON(resp, &report) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return report, nil +} + +func (client *RecordingClient) ListArchives(ctx context.Context, connectUrl string) ([]Archive, error) { + url := client.Base.JoinPath("/api/v2.2/graphql") + + query := &GraphQLQuery{ + Query: ` + query ArchivedRecordingsForTarget($connectUrl: String) { + archivedRecordings(filter: { sourceTarget: $connectUrl }) { + data { + name + downloadUrl + reportUrl + metadata { + labels + } + size + } + } + } + `, + Variables: map[string]string{ + connectUrl: connectUrl, + }, + } + queryJSON, err := query.ToJSON() + if err != nil { + return nil, fmt.Errorf("failed to construct graph query: %s", err.Error()) + } + body := string(queryJSON) + + header := make(http.Header) + header.Add("Content-Type", "application/json") + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), &body, header) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return nil, fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + graphQLResponse := &ArchiveGraphQLResponse{} + err = ReadJSON(resp, graphQLResponse) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return graphQLResponse.Data.ArchivedRecordings.Data, nil +} + +type CredentialClient struct { + *commonCryostatRESTClient +} + +func (client *CredentialClient) Create(ctx context.Context, credential *Credential) error { + url := client.Base.JoinPath("/api/v2.2/credentials") + body := credential.ToFormData() + header := make(http.Header) + header.Add("Content-Type", "application/x-www-form-urlencoded") + + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), &body, header) + if err != nil { + return err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + return nil +} + +func ReadJSON(resp *http.Response, result interface{}) error { + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + err = json.Unmarshal(body, result) + if err != nil { + return err + } + return nil +} + +func ReadString(resp *http.Response) (string, error) { + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + return string(body), nil +} + +func ReadHeader(resp *http.Response) string { + header := "" + for name, value := range resp.Header { + for _, h := range value { + header += fmt.Sprintf("%s: %s\n", name, h) + } + } + return header +} + +func ReadError(resp *http.Response) string { + body, _ := ReadString(resp) + return body +} + +func NewHttpClient() *http.Client { + client := &http.Client{ + Timeout: testTimeout, + } + + transport := http.DefaultTransport.(*http.Transport).Clone() + // Ignore verifying certs + transport.TLSClientConfig.InsecureSkipVerify = true + + client.Transport = transport + return client +} + +func NewHttpRequest(ctx context.Context, method string, url string, body *string, header http.Header) (*http.Request, error) { + var reqBody io.Reader + if body != nil { + reqBody = strings.NewReader(*body) + } + req, err := http.NewRequestWithContext(ctx, method, url, reqBody) + if err != nil { + return nil, err + } + if header != nil { + req.Header = header + } + // Authentication is only enabled on OCP. Ignored on k8s. + config, err := rest.InClusterConfig() + if err != nil { + return nil, fmt.Errorf("failed to get in-cluster configurations: %s", err.Error()) + } + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", base64.StdEncoding.EncodeToString([]byte(config.BearerToken)))) + return req, nil +} + +func StatusOK(statusCode int) bool { + return statusCode >= 200 && statusCode < 300 +} + +func SendRequest(ctx context.Context, httpClient *http.Client, method string, url string, body *string, header http.Header) (*http.Response, error) { + var response *http.Response + err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + // Create a new request + req, err := NewHttpRequest(ctx, method, url, body, header) + if err != nil { + return false, fmt.Errorf("failed to create a Cryostat REST request: %s", err.Error()) + } + + resp, err := httpClient.Do(req) + if err != nil { + // Retry when connection is closed. + if errors.Is(err, io.EOF) { + return false, nil + } + return false, err + } + response = resp + return true, nil + }) + + return response, err +} diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go new file mode 100644 index 000000000..0b8daa582 --- /dev/null +++ b/internal/test/scorecard/common_utils.go @@ -0,0 +1,399 @@ +// 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 scorecard + +import ( + "context" + "fmt" + "net/http" + "net/url" + "time" + + operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + netv1 "k8s.io/api/networking/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes/scheme" +) + +const ( + operatorDeploymentName string = "cryostat-operator-controller-manager" + testTimeout time.Duration = time.Minute * 10 +) + +type TestResources struct { + OpenShift bool + Client *CryostatClientset + *scapiv1alpha3.TestResult +} + +func waitForDeploymentAvailability(ctx context.Context, client *CryostatClientset, namespace string, + name string, r *scapiv1alpha3.TestResult) error { + err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + deploy, err := client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + r.Log += fmt.Sprintf("deployment %s is not yet found\n", name) + return false, nil // Retry + } + return false, fmt.Errorf("failed to get deployment: %s", err.Error()) + } + // Check for Available condition + for _, condition := range deploy.Status.Conditions { + if condition.Type == appsv1.DeploymentAvailable && + condition.Status == corev1.ConditionTrue { + r.Log += fmt.Sprintf("deployment %s is available\n", deploy.Name) + return true, nil + } + if condition.Type == appsv1.DeploymentReplicaFailure && + condition.Status == corev1.ConditionTrue { + r.Log += fmt.Sprintf("deployment %s is failing, %s: %s\n", deploy.Name, + condition.Reason, condition.Message) + } + } + r.Log += fmt.Sprintf("deployment %s is not yet available\n", deploy.Name) + return false, nil + }) + if err != nil { + logErr := logWorkloadEvents(r, client, namespace, name) + if logErr != nil { + r.Log += fmt.Sprintf("failed to look up deployment errors: %s\n", logErr.Error()) + } + } + return err +} + +func logError(r *scapiv1alpha3.TestResult, message string) { + r.State = scapiv1alpha3.FailState + r.Errors = append(r.Errors, message) +} + +func fail(r scapiv1alpha3.TestResult, message string) scapiv1alpha3.TestResult { + r.State = scapiv1alpha3.FailState + r.Errors = append(r.Errors, message) + return r +} + +func logWorkloadEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string, name string) error { + ctx := context.Background() + deploy, err := client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return err + } + // Log deployment conditions and events + r.Log += fmt.Sprintf("deployment %s conditions:\n", deploy.Name) + for _, condition := range deploy.Status.Conditions { + r.Log += fmt.Sprintf("\t%s == %s, %s: %s\n", condition.Type, + condition.Status, condition.Reason, condition.Message) + } + + r.Log += fmt.Sprintf("deployment %s warning events:\n", deploy.Name) + err = logEvents(r, client, namespace, scheme.Scheme, deploy) + if err != nil { + return err + } + + // Look up replica sets for deployment and log conditions and events + selector, err := metav1.LabelSelectorAsSelector(deploy.Spec.Selector) + if err != nil { + return err + } + replicaSets, err := client.AppsV1().ReplicaSets(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: selector.String(), + }) + if err != nil { + return err + } + for _, rs := range replicaSets.Items { + r.Log += fmt.Sprintf("replica set %s conditions:\n", rs.Name) + for _, condition := range rs.Status.Conditions { + r.Log += fmt.Sprintf("\t%s == %s, %s: %s\n", condition.Type, condition.Status, + condition.Reason, condition.Message) + } + r.Log += fmt.Sprintf("replica set %s warning events:\n", rs.Name) + err = logEvents(r, client, namespace, scheme.Scheme, &rs) + if err != nil { + return err + } + } + + // Look up pods for deployment and log conditions and events + pods, err := client.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: selector.String(), + }) + if err != nil { + return err + } + for _, pod := range pods.Items { + r.Log += fmt.Sprintf("pod %s phase: %s\n", pod.Name, pod.Status.Phase) + r.Log += fmt.Sprintf("pod %s conditions:\n", pod.Name) + for _, condition := range pod.Status.Conditions { + r.Log += fmt.Sprintf("\t%s == %s, %s: %s\n", condition.Type, condition.Status, + condition.Reason, condition.Message) + } + r.Log += fmt.Sprintf("pod %s warning events:\n", pod.Name) + err = logEvents(r, client, namespace, scheme.Scheme, &pod) + if err != nil { + return err + } + } + return nil +} + +func logEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string, + scheme *runtime.Scheme, obj runtime.Object) error { + events, err := client.CoreV1().Events(namespace).Search(scheme, obj) + if err != nil { + return err + } + for _, event := range events.Items { + if event.Type == corev1.EventTypeWarning { + r.Log += fmt.Sprintf("\t%s: %s\n", event.Reason, event.Message) + } + } + return nil +} + +func newEmptyTestResult(testName string) *scapiv1alpha3.TestResult { + return &scapiv1alpha3.TestResult{ + Name: testName, + State: scapiv1alpha3.PassState, + Errors: make([]string, 0), + Suggestions: make([]string, 0), + } +} + +func newTestResources(testName string) *TestResources { + return &TestResources{ + TestResult: newEmptyTestResult(testName), + } +} + +func setupCRTestResources(tr *TestResources, openShiftCertManager bool) error { + r := tr.TestResult + + // Create a new Kubernetes REST client for this test + client, err := NewClientset() + if err != nil { + logError(r, fmt.Sprintf("failed to create client: %s", err.Error())) + return err + } + tr.Client = client + + openshift, err := isOpenShift(client) + if err != nil { + logError(r, fmt.Sprintf("could not determine whether platform is OpenShift: %s", err.Error())) + return err + } + tr.OpenShift = openshift + + if openshift && openShiftCertManager { + err := installOpenShiftCertManager(r) + if err != nil { + logError(r, fmt.Sprintf("failed to install cert-manager Operator for Red Hat OpenShift: %s", err.Error())) + return err + } + } + return nil +} + +func newCryostatCR(name string, namespace string, withIngress bool) *operatorv1beta1.Cryostat { + cr := &operatorv1beta1.Cryostat{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: operatorv1beta1.CryostatSpec{ + Minimal: false, + EnableCertManager: &[]bool{true}[0], + }, + } + + if withIngress { + pathType := netv1.PathTypePrefix + cr.Spec.NetworkOptions = &operatorv1beta1.NetworkConfigurationList{ + CoreConfig: &operatorv1beta1.NetworkConfiguration{ + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", + }, + IngressSpec: &netv1.IngressSpec{ + TLS: []netv1.IngressTLS{{}}, + Rules: []netv1.IngressRule{ + { + Host: "testing.cryostat", + IngressRuleValue: netv1.IngressRuleValue{ + HTTP: &netv1.HTTPIngressRuleValue{ + Paths: []netv1.HTTPIngressPath{ + { + Path: "/", + PathType: &pathType, + Backend: netv1.IngressBackend{ + Service: &netv1.IngressServiceBackend{ + Name: name, + Port: netv1.ServiceBackendPort{ + Number: 8181, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + GrafanaConfig: &operatorv1beta1.NetworkConfiguration{ + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", + }, + IngressSpec: &netv1.IngressSpec{ + TLS: []netv1.IngressTLS{{}}, + Rules: []netv1.IngressRule{ + { + Host: "testing.cryostat-grafana", + IngressRuleValue: netv1.IngressRuleValue{ + HTTP: &netv1.HTTPIngressRuleValue{ + Paths: []netv1.HTTPIngressPath{ + { + Path: "/", + PathType: &pathType, + Backend: netv1.IngressBackend{ + Service: &netv1.IngressServiceBackend{ + Name: fmt.Sprintf("%s-grafana", name), + Port: netv1.ServiceBackendPort{ + Number: 3000, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + } + return cr +} + +func createAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources *TestResources) (*operatorv1beta1.Cryostat, error) { + client := resources.Client + r := resources.TestResult + + cr, err := client.OperatorCRDs().Cryostats(cr.Namespace).Create(context.Background(), cr) + if err != nil { + logError(r, fmt.Sprintf("failed to create Cryostat CR: %s", err.Error())) + return nil, err + } + + // Poll the deployment until it becomes available or we timeout + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + err = waitForDeploymentAvailability(ctx, client, cr.Namespace, cr.Name, r) + if err != nil { + logError(r, fmt.Sprintf("Cryostat main deployment did not become available: %s", err.Error())) + return nil, err + } + + err = wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + cr, err = client.OperatorCRDs().Cryostats(cr.Namespace).Get(ctx, cr.Name) + if err != nil { + return false, fmt.Errorf("failed to get Cryostat CR: %s", err.Error()) + } + if len(cr.Status.ApplicationURL) > 0 { + return true, nil + } + r.Log += "application URL is not yet available\n" + return false, nil + }) + if err != nil { + logError(r, fmt.Sprintf("application URL not found in CR: %s", err.Error())) + return nil, err + } + r.Log += fmt.Sprintf("application is available at %s\n", cr.Status.ApplicationURL) + + return cr, nil +} + +func waitTillCryostatReady(base *url.URL, resources *TestResources) error { + client := NewHttpClient() + r := resources.TestResult + + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + + err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + url := base.JoinPath("/health") + req, err := NewHttpRequest(ctx, http.MethodGet, url.String(), nil, make(http.Header)) + if err != nil { + return false, fmt.Errorf("failed to create a Cryostat REST request: %s", err.Error()) + } + req.Header.Add("Accept", "*/*") + + resp, err := client.Do(req) + if err != nil { + return false, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + if resp.StatusCode == http.StatusServiceUnavailable { + r.Log += fmt.Sprintf("application is not yet reachable at %s\n", base.String()) + return false, nil // Try again + } + return false, fmt.Errorf("API request failed with status code %d: %s", resp.StatusCode, ReadError(resp)) + } + + health := &HealthResponse{} + err = ReadJSON(resp, health) + if err != nil { + return false, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + if err = health.Ready(); err != nil { + r.Log += fmt.Sprintf("application is not yet ready: %s\n", err.Error()) + return false, nil // Try again + } + + r.Log += fmt.Sprintf("application is ready at %s\n", base.String()) + return true, nil + }) + + return err +} + +func cleanupCryostat(r *scapiv1alpha3.TestResult, client *CryostatClientset, name string, namespace string) { + cr := &operatorv1beta1.Cryostat{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + ctx := context.Background() + err := client.OperatorCRDs().Cryostats(cr.Namespace).Delete(ctx, + cr.Name, &metav1.DeleteOptions{}) + if err != nil { + r.Log += fmt.Sprintf("failed to delete Cryostat: %s\n", err.Error()) + } +} diff --git a/internal/test/scorecard/openshift.go b/internal/test/scorecard/openshift.go index dee12c4d3..247068a48 100644 --- a/internal/test/scorecard/openshift.go +++ b/internal/test/scorecard/openshift.go @@ -27,12 +27,15 @@ import ( ctrl "sigs.k8s.io/controller-runtime" configv1 "github.com/openshift/api/config/v1" + routev1 "github.com/openshift/api/route/v1" corev1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/discovery" corev1client "k8s.io/client-go/kubernetes/typed/core/v1" ) @@ -202,3 +205,7 @@ func installOpenShiftCertManager(r *scapiv1alpha3.TestResult) error { return false, nil }) } + +func isOpenShift(client discovery.DiscoveryInterface) (bool, error) { + return discovery.IsResourceEnabled(client, routev1.GroupVersion.WithResource("routes")) +} diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index b2aab776a..2860aa65e 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -17,338 +17,195 @@ package scorecard import ( "context" "fmt" + "net/url" "time" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" - - routev1 "github.com/openshift/api/route/v1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - netv1 "k8s.io/api/networking/v1" - kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/discovery" - "k8s.io/client-go/kubernetes/scheme" ) const ( - OperatorInstallTestName string = "operator-install" - CryostatCRTestName string = "cryostat-cr" - operatorDeploymentName string = "cryostat-operator-controller-manager" - testTimeout time.Duration = time.Minute * 10 + OperatorInstallTestName string = "operator-install" + CryostatCRTestName string = "cryostat-cr" + CryostatRecordingTestName string = "cryostat-recording" ) // OperatorInstallTest checks that the operator installed correctly func OperatorInstallTest(bundle *apimanifests.Bundle, namespace string) scapiv1alpha3.TestResult { - r := scapiv1alpha3.TestResult{} - r.Name = OperatorInstallTestName - r.State = scapiv1alpha3.PassState - r.Errors = make([]string, 0) - r.Suggestions = make([]string, 0) + r := newEmptyTestResult(OperatorInstallTestName) // Create a new Kubernetes REST client for this test client, err := NewClientset() if err != nil { - return fail(r, fmt.Sprintf("failed to create client: %s", err.Error())) + return fail(*r, fmt.Sprintf("failed to create client: %s", err.Error())) } // Poll the deployment until it becomes available or we timeout ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err = waitForDeploymentAvailability(ctx, client, namespace, operatorDeploymentName, &r) + err = waitForDeploymentAvailability(ctx, client, namespace, operatorDeploymentName, r) if err != nil { - return fail(r, fmt.Sprintf("operator deployment did not become available: %s", err.Error())) + return fail(*r, fmt.Sprintf("operator deployment did not become available: %s", err.Error())) } - return r + return *r } // CryostatCRTest checks that the operator installs Cryostat in response to a Cryostat CR func CryostatCRTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { - r := scapiv1alpha3.TestResult{} - r.Name = CryostatCRTestName - r.State = scapiv1alpha3.PassState - r.Errors = make([]string, 0) - r.Suggestions = make([]string, 0) + tr := newTestResources(CryostatCRTestName) + r := tr.TestResult - // Create a new Kubernetes REST client for this test - client, err := NewClientset() + err := setupCRTestResources(tr, openShiftCertManager) if err != nil { - return fail(r, fmt.Sprintf("failed to create client: %s", err.Error())) + return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatCRTestName, err.Error())) } - defer cleanupCryostat(&r, client, namespace) - openshift, err := isOpenShift(client.DiscoveryClient) + // Create a default Cryostat CR + _, err = createAndWaitTillCryostatAvailable(newCryostatCR(CryostatCRTestName, namespace, !tr.OpenShift), tr) if err != nil { - return fail(r, fmt.Sprintf("could not determine whether platform is OpenShift: %s", err.Error())) + return fail(*r, fmt.Sprintf("%s test failed: %s", CryostatCRTestName, err.Error())) } + defer cleanupCryostat(r, tr.Client, CryostatCRTestName, namespace) - if openshift && openShiftCertManager { - err := installOpenShiftCertManager(&r) - if err != nil { - return fail(r, fmt.Sprintf("failed to install cert-manager Operator for Red Hat OpenShift: %s", err.Error())) - } - } + return *r +} - // Create a default Cryostat CR - cr := newCryostatCR(namespace, !openshift) +// TODO add a built in discovery test too +func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { + tr := newTestResources(CryostatRecordingTestName) + r := tr.TestResult - ctx := context.Background() - cr, err = client.OperatorCRDs().Cryostats(namespace).Create(ctx, cr) + err := setupCRTestResources(tr, openShiftCertManager) if err != nil { - return fail(r, fmt.Sprintf("failed to create Cryostat CR: %s", err.Error())) + return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatRecordingTestName, err.Error())) } - // Poll the deployment until it becomes available or we timeout - ctx, cancel := context.WithTimeout(context.Background(), testTimeout) - defer cancel() - err = waitForDeploymentAvailability(ctx, client, cr.Namespace, cr.Name, &r) + // Create a default Cryostat CR + cr, err := createAndWaitTillCryostatAvailable(newCryostatCR(CryostatRecordingTestName, namespace, !tr.OpenShift), tr) if err != nil { - return fail(r, fmt.Sprintf("Cryostat main deployment did not become available: %s", err.Error())) + return fail(*r, fmt.Sprintf("failed to determine application URL: %s", err.Error())) } + defer cleanupCryostat(r, tr.Client, CryostatRecordingTestName, namespace) - err = wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { - cr, err = client.OperatorCRDs().Cryostats(namespace).Get(ctx, cr.Name) - if err != nil { - return false, fmt.Errorf("failed to get Cryostat CR: %s", err.Error()) - } - if len(cr.Status.ApplicationURL) > 0 { - return true, nil - } - r.Log += "Application URL is not yet available\n" - return false, nil - }) + base, err := url.Parse(cr.Status.ApplicationURL) if err != nil { - return fail(r, fmt.Sprintf("Application URL not found in CR: %s", err.Error())) + return fail(*r, fmt.Sprintf("application URL is invalid: %s", err.Error())) } - r.Log += fmt.Sprintf("Application is ready at %s\n", cr.Status.ApplicationURL) - - return r -} -func waitForDeploymentAvailability(ctx context.Context, client *CryostatClientset, namespace string, - name string, r *scapiv1alpha3.TestResult) error { - err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { - deploy, err := client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) - if err != nil { - if kerrors.IsNotFound(err) { - r.Log += fmt.Sprintf("deployment %s is not yet found\n", name) - return false, nil // Retry - } - return false, fmt.Errorf("failed to get deployment: %s", err.Error()) - } - // Check for Available condition - for _, condition := range deploy.Status.Conditions { - if condition.Type == appsv1.DeploymentAvailable && - condition.Status == corev1.ConditionTrue { - r.Log += fmt.Sprintf("deployment %s is available\n", deploy.Name) - return true, nil - } - if condition.Type == appsv1.DeploymentReplicaFailure && - condition.Status == corev1.ConditionTrue { - r.Log += fmt.Sprintf("deployment %s is failing, %s: %s\n", deploy.Name, - condition.Reason, condition.Message) - } - } - r.Log += fmt.Sprintf("deployment %s is not yet available\n", deploy.Name) - return false, nil - }) + err = waitTillCryostatReady(base, tr) if err != nil { - logErr := logErrors(r, client, namespace, name) - if logErr != nil { - r.Log += fmt.Sprintf("failed to look up deployment errors: %s\n", logErr.Error()) - } + return fail(*r, fmt.Sprintf("failed to reach the application: %s", err.Error())) } - return err -} -func fail(r scapiv1alpha3.TestResult, message string) scapiv1alpha3.TestResult { - r.State = scapiv1alpha3.FailState - r.Errors = append(r.Errors, message) - return r -} + apiClient := NewCryostatRESTClientset(base) -func cleanupCryostat(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string) { - cr := &operatorv1beta1.Cryostat{ - ObjectMeta: metav1.ObjectMeta{ - Name: "cryostat-cr-test", - Namespace: namespace, - }, + // Create a custom target for test + targetOptions := &Target{ + ConnectUrl: "service:jmx:rmi:///jndi/rmi://localhost:0/jmxrmi", + Alias: "customTarget", } - ctx := context.Background() - err := client.OperatorCRDs().Cryostats(cr.Namespace).Delete(ctx, - cr.Name, &metav1.DeleteOptions{}) + target, err := apiClient.Targets().Create(context.Background(), targetOptions) if err != nil { - r.Log += fmt.Sprintf("failed to delete Cryostat: %s\n", err.Error()) + return fail(*r, fmt.Sprintf("failed to create a target: %s", err.Error())) } -} + r.Log += fmt.Sprintf("created a custom target: %+v\n", target) + connectUrl := target.ConnectUrl -func logErrors(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string, name string) error { - ctx := context.Background() - deploy, err := client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) + jmxSecretName := CryostatRecordingTestName + "-jmx-auth" + secret, err := tr.Client.CoreV1().Secrets(namespace).Get(context.Background(), jmxSecretName, metav1.GetOptions{}) if err != nil { - return err + return fail(*r, fmt.Sprintf("failed to get jmx credentials: %s", err.Error())) } - // Log deployment conditions and events - r.Log += fmt.Sprintf("deployment %s conditions:\n", deploy.Name) - for _, condition := range deploy.Status.Conditions { - r.Log += fmt.Sprintf("\t%s == %s, %s: %s\n", condition.Type, - condition.Status, condition.Reason, condition.Message) + + credential := &Credential{ + UserName: string(secret.Data["CRYOSTAT_RJMX_USER"]), + Password: string(secret.Data["CRYOSTAT_RJMX_PASS"]), + MatchExpression: fmt.Sprintf("target.alias==\"%s\"", target.Alias), } - r.Log += fmt.Sprintf("deployment %s warning events:\n", deploy.Name) - err = logEvents(r, client, namespace, scheme.Scheme, deploy) + err = apiClient.CredentialClient.Create(context.Background(), credential) if err != nil { - return err + return fail(*r, fmt.Sprintf("failed to create stored credential: %s", err.Error())) } + r.Log += fmt.Sprintf("created stored credential with match expression: %s\n", credential.MatchExpression) + + // Wait for Cryostat to update the discovery tree + time.Sleep(2 * time.Second) - // Look up replica sets for deployment and log conditions and events - selector, err := metav1.LabelSelectorAsSelector(deploy.Spec.Selector) + // Create a recording + options := &RecordingCreateOptions{ + RecordingName: "scorecard_test_rec", + Events: "template=ALL", + Duration: 0, // Continuous + ToDisk: true, + MaxSize: 0, + MaxAge: 0, + } + rec, err := apiClient.Recordings().Create(context.Background(), connectUrl, options) if err != nil { - return err + return fail(*r, fmt.Sprintf("failed to create a recording: %s", err.Error())) } - replicaSets, err := client.AppsV1().ReplicaSets(namespace).List(ctx, metav1.ListOptions{ - LabelSelector: selector.String(), - }) + r.Log += fmt.Sprintf("created a recording: %+v\n", rec) + + // View the current recording list after creating one + recs, err := apiClient.Recordings().List(context.Background(), connectUrl) if err != nil { - return err + return fail(*r, fmt.Sprintf("failed to list recordings: %s", err.Error())) } - for _, rs := range replicaSets.Items { - r.Log += fmt.Sprintf("replica set %s conditions:\n", rs.Name) - for _, condition := range rs.Status.Conditions { - r.Log += fmt.Sprintf("\t%s == %s, %s: %s\n", condition.Type, condition.Status, - condition.Reason, condition.Message) - } - r.Log += fmt.Sprintf("replica set %s warning events:\n", rs.Name) - err = logEvents(r, client, namespace, scheme.Scheme, &rs) - if err != nil { - return err - } + r.Log += fmt.Sprintf("current list of recordings: %+v\n", recs) + + // Allow the recording to run for 10s + time.Sleep(30 * time.Second) + + // Archive the recording + archiveName, err := apiClient.Recordings().Archive(context.Background(), connectUrl, rec.Name) + if err != nil { + return fail(*r, fmt.Sprintf("failed to archive the recording: %s", err.Error())) } + r.Log += fmt.Sprintf("archived the recording %s at: %s\n", rec.Name, archiveName) - // Look up pods for deployment and log conditions and events - pods, err := client.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ - LabelSelector: selector.String(), - }) + archives, err := apiClient.Recordings().ListArchives(context.Background(), connectUrl) if err != nil { - return err + return fail(*r, fmt.Sprintf("failed to list archives: %s", err.Error())) } - for _, pod := range pods.Items { - r.Log += fmt.Sprintf("pod %s phase: %s\n", pod.Name, pod.Status.Phase) - r.Log += fmt.Sprintf("pod %s conditions:\n", pod.Name) - for _, condition := range pod.Status.Conditions { - r.Log += fmt.Sprintf("\t%s == %s, %s: %s\n", condition.Type, condition.Status, - condition.Reason, condition.Message) - } - r.Log += fmt.Sprintf("pod %s warning events:\n", pod.Name) - err = logEvents(r, client, namespace, scheme.Scheme, &pod) - if err != nil { - return err - } + r.Log += fmt.Sprintf("current list of archives: %+v\n", archives) + + report, err := apiClient.Recordings().GenerateReport(context.Background(), connectUrl, rec) + if err != nil { + return fail(*r, fmt.Sprintf("failed to generate report for the recording: %s", err.Error())) } - return nil -} + r.Log += fmt.Sprintf("generated report for the recording %s: %+v\n", rec.Name, report) -func logEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string, - scheme *runtime.Scheme, obj runtime.Object) error { - events, err := client.CoreV1().Events(namespace).Search(scheme, obj) + // Stop the recording + err = apiClient.Recordings().Stop(context.Background(), connectUrl, rec.Name) if err != nil { - return err + return fail(*r, fmt.Sprintf("failed to stop the recording %s: %s", rec.Name, err.Error())) } - for _, event := range events.Items { - if event.Type == corev1.EventTypeWarning { - r.Log += fmt.Sprintf("\t%s: %s\n", event.Reason, event.Message) - } + // Get the recording to verify its state + rec, err = apiClient.Recordings().Get(context.Background(), connectUrl, rec.Name) + if err != nil { + return fail(*r, fmt.Sprintf("failed to get the recordings: %s", err.Error())) } - return nil -} + if rec.State != "STOPPED" { + return fail(*r, fmt.Sprintf("recording %s failed to stop: %s", rec.Name, err.Error())) + } + r.Log += fmt.Sprintf("stopped the recording: %s\n", rec.Name) -func newCryostatCR(namespace string, withIngress bool) *operatorv1beta1.Cryostat { - cr := &operatorv1beta1.Cryostat{ - ObjectMeta: metav1.ObjectMeta{ - Name: "cryostat-cr-test", - Namespace: namespace, - }, - Spec: operatorv1beta1.CryostatSpec{ - Minimal: false, - EnableCertManager: &[]bool{true}[0], - }, + // Delete the recording + err = apiClient.Recordings().Delete(context.Background(), connectUrl, rec.Name) + if err != nil { + return fail(*r, fmt.Sprintf("failed to delete the recording %s: %s", rec.Name, err.Error())) } + r.Log += fmt.Sprintf("deleted the recording: %s\n", rec.Name) - if withIngress { - pathType := netv1.PathTypePrefix - cr.Spec.NetworkOptions = &operatorv1beta1.NetworkConfigurationList{ - CoreConfig: &operatorv1beta1.NetworkConfiguration{ - Annotations: map[string]string{ - "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", - }, - IngressSpec: &netv1.IngressSpec{ - TLS: []netv1.IngressTLS{{}}, - Rules: []netv1.IngressRule{ - { - Host: "testing.cryostat", - IngressRuleValue: netv1.IngressRuleValue{ - HTTP: &netv1.HTTPIngressRuleValue{ - Paths: []netv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathType, - Backend: netv1.IngressBackend{ - Service: &netv1.IngressServiceBackend{ - Name: "cryostat-cr-test", - Port: netv1.ServiceBackendPort{ - Number: 8181, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - GrafanaConfig: &operatorv1beta1.NetworkConfiguration{ - Annotations: map[string]string{ - "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", - }, - IngressSpec: &netv1.IngressSpec{ - TLS: []netv1.IngressTLS{{}}, - Rules: []netv1.IngressRule{ - { - Host: "testing.cryostat-grafana", - IngressRuleValue: netv1.IngressRuleValue{ - HTTP: &netv1.HTTPIngressRuleValue{ - Paths: []netv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathType, - Backend: netv1.IngressBackend{ - Service: &netv1.IngressServiceBackend{ - Name: "cryostat-cr-test-grafana", - Port: netv1.ServiceBackendPort{ - Number: 3000, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } + // View the current recording list after deleting one + recs, err = apiClient.Recordings().List(context.Background(), connectUrl) + if err != nil { + return fail(*r, fmt.Sprintf("failed to list recordings: %s", err.Error())) } - return cr -} + r.Log += fmt.Sprintf("current list of recordings: %+v\n", recs) -func isOpenShift(client discovery.DiscoveryInterface) (bool, error) { - return discovery.IsResourceEnabled(client, routev1.GroupVersion.WithResource("routes")) + return *r } diff --git a/internal/test/scorecard/types.go b/internal/test/scorecard/types.go new file mode 100644 index 000000000..7e34ff4a0 --- /dev/null +++ b/internal/test/scorecard/types.go @@ -0,0 +1,146 @@ +// 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 scorecard + +import ( + "encoding/json" + "errors" + "net/url" + "strconv" +) + +type HealthResponse struct { + CryostatVersion string `json:"cryostatVersion"` + DashboardAvailable bool `json:"dashboardAvailable"` + DashboardConfigured bool `json:"dashboardConfigured"` + DataSourceAvailable bool `json:"datasourceAvailable"` + DataSourceConfigured bool `json:"datasourceConfigured"` + ReportsAvailable bool `json:"reportsAvailable"` + ReportsConfigured bool `json:"reportsConfigured"` +} + +func (health *HealthResponse) Ready() error { + if !health.DashboardAvailable { + return errors.New("dashboard is not available") + } + + if !health.DataSourceAvailable { + return errors.New("datasource is not available") + } + + if !health.ReportsAvailable { + return errors.New("report is not available") + } + return nil +} + +type RecordingCreateOptions struct { + RecordingName string + Events string + Duration int32 + ToDisk bool + MaxSize int32 + MaxAge int32 +} + +func (opts *RecordingCreateOptions) ToFormData() string { + formData := &url.Values{} + + formData.Add("recordingName", opts.RecordingName) + formData.Add("events", opts.Events) + formData.Add("duration", strconv.Itoa(int(opts.Duration))) + formData.Add("toDisk", strconv.FormatBool(opts.ToDisk)) + formData.Add("maxSize", strconv.Itoa(int(opts.MaxSize))) + formData.Add("maxAge", strconv.Itoa(int(opts.MaxAge))) + + return formData.Encode() +} + +type Credential struct { + UserName string + Password string + MatchExpression string +} + +func (cred *Credential) ToFormData() string { + formData := &url.Values{} + + formData.Add("username", cred.UserName) + formData.Add("password", cred.Password) + formData.Add("matchExpression", cred.MatchExpression) + + return formData.Encode() +} + +type Recording struct { + DownloadURL string `json:"downloadUrl"` + ReportURL string `json:"reportUrl"` + Id uint32 `json:"id"` + Name string `json:"name"` + StartTime uint64 `json:"startTime"` + State string `json:"state"` + Duration int32 `json:"duration"` + Continuous bool `json:"continuous"` + ToDisk bool `json:"toDisk"` + MaxSize int32 `json:"maxSize"` + MaxAge int32 `json:"maxAge"` +} + +type Archive struct { + Name string + DownloadUrl string + ReportUrl string + Metadata struct { + Labels map[string]interface{} + } + Size int32 +} + +type CustomTargetResponse struct { + Data struct { + Result *Target `json:"result"` + } `json:"data"` +} + +type Target struct { + ConnectUrl string `json:"connectUrl"` + Alias string `json:"alias,omitempty"` +} + +func (target *Target) ToFormData() string { + formData := &url.Values{} + + formData.Add("connectUrl", target.ConnectUrl) + formData.Add("alias", target.Alias) + + return formData.Encode() +} + +type GraphQLQuery struct { + Query string `json:"query"` + Variables map[string]string `json:"variables,omitempty"` +} + +func (query *GraphQLQuery) ToJSON() ([]byte, error) { + return json.Marshal(query) +} + +type ArchiveGraphQLResponse struct { + Data struct { + ArchivedRecordings struct { + Data []Archive `json:"data"` + } `json:"archivedRecordings"` + } `json:"data"` +} From 385f81e2f21feac09454414dfe124cbd8727a739 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 13:36:15 -0500 Subject: [PATCH 10/53] test(scorecard): scorecard test for Cryostat CR configuration changes (backport #739) (#756) * test(scorecard): scorecard test for Cryostat CR configuration changes (#739) * CR config scorecard * reformat * reviews * add kubectl license (cherry picked from commit bf8df159a12fb448d9c371da3807562a64523952) # Conflicts: # bundle/manifests/cryostat-operator.clusterserviceversion.yaml * Fix conflicts --------- Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Co-authored-by: Elliott Baron --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 16 +++- config/scorecard/patches/custom.config.yaml | 16 +++- go-license.yml | 20 +++++ hack/custom.config.yaml.in | 10 +++ .../images/custom-scorecard-tests/main.go | 4 + internal/test/scorecard/clients.go | 6 +- internal/test/scorecard/common_utils.go | 67 +++++++++++++++++ internal/test/scorecard/tests.go | 75 ++++++++++++++++++- 9 files changed, 203 insertions(+), 13 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 04a0f5f58..0d959bbe2 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -54,7 +54,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-03-06T21:13:39Z" + createdAt: "2024-03-08T17:20:54Z" 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 12b393613..7b8e524fc 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:2.5.0-20240305020416 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322 labels: suite: cryostat test: cryostat-cr @@ -90,13 +90,23 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322 labels: suite: cryostat test: cryostat-recording storage: spec: mountPath: {} + - entrypoint: + - cryostat-scorecard-tests + - cryostat-config-change + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322 + labels: + suite: cryostat + test: cryostat-config-change + storage: + spec: + mountPath: {} storage: spec: mountPath: {} diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 527eac9ad..59b597ef0 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:2.5.0-20240305020416" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,17 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240305020416" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322" labels: suite: cryostat test: cryostat-recording +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-config-change + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322" + labels: + suite: cryostat + test: cryostat-config-change diff --git a/go-license.yml b/go-license.yml index 2a9d2d95a..f5d6506c9 100644 --- a/go-license.yml +++ b/go-license.yml @@ -13,6 +13,26 @@ header: | // See the License for the specific language governing permissions and // limitations under the License. +custom-headers: + - name: kubectl + header: | + // Copyright The Cryostat Authors. + // Copyright 2016 The Kubernetes 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. + paths: + - internal/test/scorecard/common_utils.go + exclude: names: - '.*generated.*' diff --git a/hack/custom.config.yaml.in b/hack/custom.config.yaml.in index 487462006..b707766ac 100644 --- a/hack/custom.config.yaml.in +++ b/hack/custom.config.yaml.in @@ -31,3 +31,13 @@ labels: suite: cryostat test: cryostat-recording +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-config-change + image: "${CUSTOM_SCORECARD_IMG}" + labels: + suite: cryostat + test: cryostat-config-change diff --git a/internal/images/custom-scorecard-tests/main.go b/internal/images/custom-scorecard-tests/main.go index 62808a82f..6faed656e 100644 --- a/internal/images/custom-scorecard-tests/main.go +++ b/internal/images/custom-scorecard-tests/main.go @@ -80,6 +80,7 @@ func printValidTests() []scapiv1alpha3.TestResult { tests.OperatorInstallTestName, tests.CryostatCRTestName, tests.CryostatRecordingTestName, + tests.CryostatConfigChangeTestName, }, ",")) result.Errors = append(result.Errors, str) @@ -92,6 +93,7 @@ func validateTests(testNames []string) bool { case tests.OperatorInstallTestName: case tests.CryostatCRTestName: case tests.CryostatRecordingTestName: + case tests.CryostatConfigChangeTestName: default: return false } @@ -112,6 +114,8 @@ func runTests(testNames []string, bundle *apimanifests.Bundle, namespace string, results = append(results, tests.CryostatCRTest(bundle, namespace, openShiftCertManager)) case tests.CryostatRecordingTestName: results = append(results, tests.CryostatRecordingTest(bundle, namespace, openShiftCertManager)) + case tests.CryostatConfigChangeTestName: + results = append(results, tests.CryostatConfigChangeTest(bundle, namespace, openShiftCertManager)) default: log.Fatalf("unknown test found: %s", testName) } diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index ffe3ad79e..8f78d7a05 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -136,7 +136,7 @@ func (c *CryostatClient) Create(ctx context.Context, obj *operatorv1beta1.Cryost // Update updates the provided Cryostat CR func (c *CryostatClient) Update(ctx context.Context, obj *operatorv1beta1.Cryostat) (*operatorv1beta1.Cryostat, error) { - return update(ctx, c.restClient, c.resource, c.namespace, obj, &operatorv1beta1.Cryostat{}) + return update(ctx, c.restClient, c.resource, c.namespace, obj, &operatorv1beta1.Cryostat{}, obj.Name) } // Delete deletes the Cryostat CR with the given name @@ -158,9 +158,9 @@ func create[r runtime.Object](ctx context.Context, c rest.Interface, res string, return result, err } -func update[r runtime.Object](ctx context.Context, c rest.Interface, res string, ns string, obj r, result r) (r, error) { +func update[r runtime.Object](ctx context.Context, c rest.Interface, res string, ns string, obj r, result r, name string) (r, error) { err := c.Put(). - Namespace(ns).Resource(res). + Namespace(ns).Resource(res).Name(name). Body(obj).Do(ctx).Into(result) return result, err } diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index 0b8daa582..c36dc720a 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -1,4 +1,5 @@ // Copyright The Cryostat Authors. +// Copyright 2016 The Kubernetes Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -383,6 +384,72 @@ func waitTillCryostatReady(base *url.URL, resources *TestResources) error { return err } +func updateAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources *TestResources) error { + client := resources.Client + r := resources.TestResult + + cr, err := client.OperatorCRDs().Cryostats(cr.Namespace).Update(context.Background(), cr) + if err != nil { + r.Log += fmt.Sprintf("failed to update Cryostat CR: %s", err.Error()) + return err + } + + // Poll the deployment until it becomes available or we timeout + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + err = wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + deploy, err := client.AppsV1().Deployments(cr.Namespace).Get(ctx, cr.Name, metav1.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + r.Log += fmt.Sprintf("deployment %s is not yet found\n", cr.Name) + return false, nil // Retry + } + return false, fmt.Errorf("failed to get deployment: %s", err.Error()) + } + + // Wait for deployment to update by verifying Cryostat has PVC configured + for _, volume := range deploy.Spec.Template.Spec.Volumes { + if volume.VolumeSource.EmptyDir != nil { + r.Log += fmt.Sprintf("Cryostat deployment is still updating. Storage: %s\n", volume.VolumeSource.EmptyDir) + return false, nil // Retry + } + if volume.VolumeSource.PersistentVolumeClaim != nil { + break + } + } + + // Derived from kubectl: https://github.com/kubernetes/kubectl/blob/24d21a0/pkg/polymorphichelpers/rollout_status.go#L75-L91 + // Check for deployment condition + if deploy.Generation <= deploy.Status.ObservedGeneration { + for _, condition := range deploy.Status.Conditions { + if condition.Type == appsv1.DeploymentProgressing && condition.Status == corev1.ConditionFalse && condition.Reason == "ProgressDeadlineExceeded" { + return false, fmt.Errorf("deployment %s exceeded its progress deadline", deploy.Name) // Don't Retry + } + } + if deploy.Spec.Replicas != nil && deploy.Status.UpdatedReplicas < *deploy.Spec.Replicas { + r.Log += fmt.Sprintf("Waiting for deployment %s rollout to finish: %d out of %d new replicas have been updated... \n", deploy.Name, deploy.Status.UpdatedReplicas, *deploy.Spec.Replicas) + return false, nil + } + if deploy.Status.Replicas > deploy.Status.UpdatedReplicas { + r.Log += fmt.Sprintf("Waiting for deployment %s rollout to finish: %d old replicas are pending termination... \n", deploy.Name, deploy.Status.Replicas-deploy.Status.UpdatedReplicas) + return false, nil + } + if deploy.Status.AvailableReplicas < deploy.Status.UpdatedReplicas { + r.Log += fmt.Sprintf("Waiting for deployment %s rollout to finish: %d out of %d updated replicas are available... \n", deploy.Name, deploy.Status.AvailableReplicas, deploy.Status.UpdatedReplicas) + return false, nil + } + r.Log += fmt.Sprintf("deployment %s successfully rolled out\n", deploy.Name) + return true, nil + } + r.Log += "Waiting for deployment spec update to be observed...\n" + return false, nil + }) + if err != nil { + return fmt.Errorf("failed to look up deployment errors: %s", err.Error()) + } + return err +} + func cleanupCryostat(r *scapiv1alpha3.TestResult, client *CryostatClientset, name string, namespace string) { cr := &operatorv1beta1.Cryostat{ ObjectMeta: metav1.ObjectMeta{ diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 2860aa65e..72bb48f1a 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -20,15 +20,19 @@ import ( "net/url" "time" + operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( - OperatorInstallTestName string = "operator-install" - CryostatCRTestName string = "cryostat-cr" - CryostatRecordingTestName string = "cryostat-recording" + OperatorInstallTestName string = "operator-install" + CryostatCRTestName string = "cryostat-cr" + CryostatRecordingTestName string = "cryostat-recording" + CryostatConfigChangeTestName string = "cryostat-config-change" ) // OperatorInstallTest checks that the operator installed correctly @@ -72,6 +76,71 @@ func CryostatCRTest(bundle *apimanifests.Bundle, namespace string, openShiftCert return *r } +func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { + tr := newTestResources(CryostatConfigChangeTestName) + r := tr.TestResult + + err := setupCRTestResources(tr, openShiftCertManager) + if err != nil { + return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatConfigChangeTestName, err.Error())) + } + + // Create a default Cryostat CR with default empty dir + cr := newCryostatCR(CryostatConfigChangeTestName, namespace, !tr.OpenShift) + cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ + EmptyDir: &operatorv1beta1.EmptyDirConfig{ + Enabled: true, + }, + } + + _, err = createAndWaitTillCryostatAvailable(cr, tr) + if err != nil { + return fail(*r, fmt.Sprintf("failed to determine application URL: %s", err.Error())) + } + defer cleanupCryostat(r, tr.Client, CryostatRecordingTestName, namespace) + + // Switch Cryostat CR to PVC for redeployment + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + client := tr.Client + + cr, err = client.OperatorCRDs().Cryostats(namespace).Get(ctx, CryostatConfigChangeTestName) + if err != nil { + return fail(*r, fmt.Sprintf("failed to get Cryostat CR: %s", err.Error())) + } + cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ + PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ + Spec: &corev1.PersistentVolumeClaimSpec{ + StorageClassName: nil, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceStorage: resource.MustParse("1Gi"), + }, + }, + }, + }, + } + + // Wait for redeployment of Cryostat CR + err = updateAndWaitTillCryostatAvailable(cr, tr) + if err != nil { + return fail(*r, fmt.Sprintf("Cryostat redeployment did not become available: %s", err.Error())) + } + r.Log += "Cryostat deployment has successfully updated with new spec template" + + base, err := url.Parse(cr.Status.ApplicationURL) + if err != nil { + return fail(*r, fmt.Sprintf("application URL is invalid: %s", err.Error())) + } + + err = waitTillCryostatReady(base, tr) + if err != nil { + return fail(*r, fmt.Sprintf("failed to reach the application: %s", err.Error())) + } + + return *r +} + // TODO add a built in discovery test too func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { tr := newTestResources(CryostatRecordingTestName) From 5917c22f503627ed7a60a10ed5f817d5f292e8ec Mon Sep 17 00:00:00 2001 From: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Date: Fri, 15 Mar 2024 16:30:20 -0400 Subject: [PATCH 11/53] chore(api): remove CommandConfig from NetworkOptions (#743) * remove CommandConfig * udpate * make bundle * correct test --- api/v1beta1/cryostat_conversion.go | 2 - api/v1beta1/cryostat_conversion_test.go | 7 +- api/v1beta2/cryostat_types.go | 7 - api/v1beta2/zz_generated.deepcopy.go | 5 - ...yostat-operator.clusterserviceversion.yaml | 21 +- .../operator.cryostat.io_cryostats.yaml | 315 ------------------ .../bases/operator.cryostat.io_cryostats.yaml | 315 ------------------ ...yostat-operator.clusterserviceversion.yaml | 19 -- internal/test/conversion.go | 15 + internal/test/resources.go | 37 ++ 10 files changed, 58 insertions(+), 685 deletions(-) diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index bb56a27cd..99a4af703 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -157,7 +157,6 @@ func convertNetworkOptionsTo(srcOpts *NetworkConfigurationList) *operatorv1beta2 dstOpts = &operatorv1beta2.NetworkConfigurationList{ CoreConfig: convertNetworkConfigTo(srcOpts.CoreConfig), GrafanaConfig: convertNetworkConfigTo(srcOpts.GrafanaConfig), - CommandConfig: convertNetworkConfigTo(srcOpts.CommandConfig), // TODO Remove this from v1beta2 API } } return dstOpts @@ -442,7 +441,6 @@ func convertNetworkOptionsFrom(srcOpts *operatorv1beta2.NetworkConfigurationList dstOpts = &NetworkConfigurationList{ CoreConfig: convertNetworkConfigFrom(srcOpts.CoreConfig), GrafanaConfig: convertNetworkConfigFrom(srcOpts.GrafanaConfig), - CommandConfig: convertNetworkConfigFrom(srcOpts.CommandConfig), // TODO Remove this from v1beta2 API } } return dstOpts diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go index 80a7dc41b..5a60d5e73 100644 --- a/api/v1beta1/cryostat_conversion_test.go +++ b/api/v1beta1/cryostat_conversion_test.go @@ -77,8 +77,11 @@ var _ = Describe("Cryostat", func() { }) func tableEntriesTo() []TableEntry { - return append(tableEntries(), Entry("WS connections", (*test.TestResources).NewCryostatWithWsConnectionsSpecV1Beta1, - (*test.TestResources).NewCryostat)) + return append(tableEntries(), + Entry("WS connections", (*test.TestResources).NewCryostatWithWsConnectionsSpecV1Beta1, + (*test.TestResources).NewCryostat), + Entry("command config", (*test.TestResources).NewCryostatWithCommandConfigV1Beta1, + (*test.TestResources).NewCryostatWithIngress)) } func tableEntriesFrom() []TableEntry { diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 5bd3a8584..6facea387 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -351,13 +351,6 @@ type NetworkConfigurationList struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec CoreConfig *NetworkConfiguration `json:"coreConfig,omitempty"` - // Specifications for how to expose the Cryostat command service, - // which serves the WebSocket command channel. - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:hidden"} - // - // Deprecated: CommandConfig is no longer used. - CommandConfig *NetworkConfiguration `json:"commandConfig,omitempty"` // Specifications for how to expose Cryostat's Grafana service, // which serves the Grafana dashboard. // +optional diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index a8111e005..96818377e 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -413,11 +413,6 @@ func (in *NetworkConfigurationList) DeepCopyInto(out *NetworkConfigurationList) *out = new(NetworkConfiguration) (*in).DeepCopyInto(*out) } - if in.CommandConfig != nil { - in, out := &in.CommandConfig, &out.CommandConfig - *out = new(NetworkConfiguration) - (*in).DeepCopyInto(*out) - } if in.GrafanaConfig != nil { in, out := &in.GrafanaConfig, &out.GrafanaConfig *out = new(NetworkConfiguration) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 0d959bbe2..9c7321459 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -54,7 +54,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-03-08T17:20:54Z" + createdAt: "2024-03-12T21:00:17Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -592,25 +592,6 @@ spec: of the cluster, such as using an Ingress or Route. displayName: Network Options path: networkOptions - - description: "Specifications for how to expose the Cryostat command service, - which serves the WebSocket command channel. \n Deprecated: CommandConfig - is no longer used." - displayName: Command Config - path: networkOptions.commandConfig - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:hidden - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.commandConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.commandConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.commandConfig.labels - description: Specifications for how to expose the Cryostat service, which serves the Cryostat application. displayName: Core Config diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 13918ffcc..44f3e7098 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -4852,321 +4852,6 @@ spec: description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. properties: - commandConfig: - description: "Specifications for how to expose the Cryostat command - service, which serves the WebSocket command channel. \n Deprecated: - CommandConfig is no longer used." - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object coreConfig: description: Specifications for how to expose the Cryostat service, which serves the Cryostat application. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index afa2befdd..558887e1a 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -4842,321 +4842,6 @@ spec: description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. properties: - commandConfig: - description: "Specifications for how to expose the Cryostat command - service, which serves the WebSocket command channel. \n Deprecated: - CommandConfig is no longer used." - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: DefaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: Resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a Service as a Backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: Name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: Port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: IngressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "Host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If Host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: A collection of paths that map - requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: Backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: Resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: Service references a - Service as a Backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: Name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: Port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: Name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: Number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: Path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'PathType determines the - interpretation of the Path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object coreConfig: description: Specifications for how to expose the Cryostat service, which serves the Cryostat application. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 17d9dda93..f119d07de 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -142,25 +142,6 @@ spec: of the cluster, such as using an Ingress or Route. displayName: Network Options path: networkOptions - - description: "Specifications for how to expose the Cryostat command service, - which serves the WebSocket command channel. \n Deprecated: CommandConfig - is no longer used." - displayName: Command Config - path: networkOptions.commandConfig - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:hidden - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.commandConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.commandConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.commandConfig.labels - description: Specifications for how to expose the Cryostat service, which serves the Cryostat application. displayName: Core Config diff --git a/internal/test/conversion.go b/internal/test/conversion.go index ab123ddd3..246e9ca6a 100644 --- a/internal/test/conversion.go +++ b/internal/test/conversion.go @@ -478,6 +478,21 @@ func (r *TestResources) NewCryostatWithWsConnectionsSpecV1Beta1() *operatorv1bet return cr } +func (r *TestResources) NewCryostatWithCommandConfigV1Beta1() *operatorv1beta1.Cryostat { + commandSVC := r.NewCommandService() + commandIng := r.newNetworkConfigurationV1Beta1(commandSVC.Name, commandSVC.Spec.Ports[0].Port) + commandIng.Annotations["command"] = "annotation" + commandIng.Labels["command"] = "label" + + cr := r.NewCryostatWithIngressV1Beta1() + cr.Spec.NetworkOptions = &operatorv1beta1.NetworkConfigurationList{ + CoreConfig: cr.Spec.NetworkOptions.CoreConfig, + GrafanaConfig: cr.Spec.NetworkOptions.GrafanaConfig, + CommandConfig: &commandIng, + } + return cr +} + func (r *TestResources) NewCryostatWithReportSubprocessHeapSpecV1Beta1() *operatorv1beta1.Cryostat { cr := r.NewCryostatV1Beta1() if cr.Spec.ReportOptions == nil { diff --git a/internal/test/resources.go b/internal/test/resources.go index d94ac5403..da76eaed0 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -761,6 +761,43 @@ func (r *TestResources) NewGrafanaService() *corev1.Service { } } +func (r *TestResources) NewCommandService() *corev1.Service { + c := true + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name + "-command", + Namespace: r.Namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: operatorv1beta2.GroupVersion.String(), + Kind: "Cryostat", + Name: r.Name, + UID: "", + Controller: &c, + }, + }, + Labels: map[string]string{ + "app": r.Name, + "component": "cryostat", + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeClusterIP, + Selector: map[string]string{ + "app": r.Name, + "component": "cryostat", + }, + Ports: []corev1.ServicePort{ + { + Name: "http", + Port: 10001, + TargetPort: intstr.FromInt(10001), + }, + }, + }, + } +} + func (r *TestResources) NewReportsService() *corev1.Service { c := true return &corev1.Service{ From 8f807ef91fdc0098a905ed1b8f452c76941b2a2b Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:51:51 -0400 Subject: [PATCH 12/53] test(scorecard): scorecard test for report generator (backport #753) (#767) * test(scorecard): scorecard test for report generator (#753) * deploy reports sidecar * report scorecard test * update * rebase fix * query health (cherry picked from commit 96ea4cb7ae2c219eb37cf5583a2607c31d7889a7) # Conflicts: # bundle/manifests/cryostat-operator.clusterserviceversion.yaml # bundle/tests/scorecard/config.yaml * Fix conflicts --------- Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Co-authored-by: Elliott Baron --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 18 +++-- config/scorecard/patches/custom.config.yaml | 18 +++-- hack/custom.config.yaml.in | 10 +++ .../images/custom-scorecard-tests/main.go | 4 ++ internal/test/scorecard/clients.go | 2 +- internal/test/scorecard/common_utils.go | 65 ++++++++++++++----- internal/test/scorecard/tests.go | 41 +++++++++++- 8 files changed, 132 insertions(+), 28 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 9c7321459..a7af2fe52 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -54,7 +54,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-03-12T21:00:17Z" + createdAt: "2024-03-15T21:38: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 7b8e524fc..8822c74a5 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:2.5.0-20240307154322 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 labels: suite: cryostat test: cryostat-recording @@ -100,13 +100,23 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 labels: suite: cryostat test: cryostat-config-change storage: spec: mountPath: {} + - entrypoint: + - cryostat-scorecard-tests + - cryostat-report + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 + labels: + suite: cryostat + test: cryostat-report + storage: + spec: + mountPath: {} storage: spec: mountPath: {} diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 59b597ef0..f6e806ece 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:2.5.0-20240307154322" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" labels: suite: cryostat test: cryostat-recording @@ -38,7 +38,17 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240307154322" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" labels: suite: cryostat test: cryostat-config-change +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-report + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" + labels: + suite: cryostat + test: cryostat-report diff --git a/hack/custom.config.yaml.in b/hack/custom.config.yaml.in index b707766ac..4336abbe4 100644 --- a/hack/custom.config.yaml.in +++ b/hack/custom.config.yaml.in @@ -41,3 +41,13 @@ labels: suite: cryostat test: cryostat-config-change +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-report + image: "${CUSTOM_SCORECARD_IMG}" + labels: + suite: cryostat + test: cryostat-report diff --git a/internal/images/custom-scorecard-tests/main.go b/internal/images/custom-scorecard-tests/main.go index 6faed656e..b3041281c 100644 --- a/internal/images/custom-scorecard-tests/main.go +++ b/internal/images/custom-scorecard-tests/main.go @@ -81,6 +81,7 @@ func printValidTests() []scapiv1alpha3.TestResult { tests.CryostatCRTestName, tests.CryostatRecordingTestName, tests.CryostatConfigChangeTestName, + tests.CryostatReportTestName, }, ",")) result.Errors = append(result.Errors, str) @@ -94,6 +95,7 @@ func validateTests(testNames []string) bool { case tests.CryostatCRTestName: case tests.CryostatRecordingTestName: case tests.CryostatConfigChangeTestName: + case tests.CryostatReportTestName: default: return false } @@ -116,6 +118,8 @@ func runTests(testNames []string, bundle *apimanifests.Bundle, namespace string, results = append(results, tests.CryostatRecordingTest(bundle, namespace, openShiftCertManager)) case tests.CryostatConfigChangeTestName: results = append(results, tests.CryostatConfigChangeTest(bundle, namespace, openShiftCertManager)) + case tests.CryostatReportTestName: + results = append(results, tests.CryostatReportTest(bundle, namespace, openShiftCertManager)) default: log.Fatalf("unknown test found: %s", testName) } diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 8f78d7a05..2c831e72f 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -587,7 +587,7 @@ func SendRequest(ctx context.Context, httpClient *http.Client, method string, ur // Create a new request req, err := NewHttpRequest(ctx, method, url, body, header) if err != nil { - return false, fmt.Errorf("failed to create a Cryostat REST request: %s", err.Error()) + return false, fmt.Errorf("failed to create an http request: %s", err.Error()) } resp, err := httpClient.Do(req) diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index c36dc720a..00933fdf6 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -17,7 +17,9 @@ package scorecard import ( "context" + "errors" "fmt" + "io" "net/http" "net/url" "time" @@ -338,6 +340,48 @@ func createAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources } func waitTillCryostatReady(base *url.URL, resources *TestResources) error { + return sendHealthRequest(base, resources, func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error) { + health := &HealthResponse{} + err = ReadJSON(resp, health) + if err != nil { + return false, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + if err = health.Ready(); err != nil { + r.Log += fmt.Sprintf("application is not yet ready: %s\n", err.Error()) + return false, nil // Try again + } + + r.Log += fmt.Sprintf("application is ready at %s\n", base.String()) + return true, nil + }) +} + +func waitTillReportReady(name string, namespace string, port int32, resources *TestResources) error { + client := resources.Client + r := resources.TestResult + + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + + err := waitForDeploymentAvailability(ctx, client, namespace, name, r) + if err != nil { + return fmt.Errorf("report sidecar deployment did not become available: %s", err.Error()) + } + + reportsUrl := fmt.Sprintf("https://%s.%s.svc.cluster.local:%d", name, namespace, port) + base, err := url.Parse(reportsUrl) + if err != nil { + return fmt.Errorf("application URL is invalid: %s", err.Error()) + } + + return sendHealthRequest(base, resources, func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error) { + r.Log += fmt.Sprintf("reports sidecar is ready at %s\n", base.String()) + return true, nil + }) +} + +func sendHealthRequest(base *url.URL, resources *TestResources, healthCheck func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error)) error { client := NewHttpClient() r := resources.TestResult @@ -348,12 +392,15 @@ func waitTillCryostatReady(base *url.URL, resources *TestResources) error { url := base.JoinPath("/health") req, err := NewHttpRequest(ctx, http.MethodGet, url.String(), nil, make(http.Header)) if err != nil { - return false, fmt.Errorf("failed to create a Cryostat REST request: %s", err.Error()) + return false, fmt.Errorf("failed to create a an http request: %s", err.Error()) } req.Header.Add("Accept", "*/*") resp, err := client.Do(req) if err != nil { + if errors.Is(err, io.EOF) { + return false, nil // Retry + } return false, err } defer resp.Body.Close() @@ -365,22 +412,8 @@ func waitTillCryostatReady(base *url.URL, resources *TestResources) error { } return false, fmt.Errorf("API request failed with status code %d: %s", resp.StatusCode, ReadError(resp)) } - - health := &HealthResponse{} - err = ReadJSON(resp, health) - if err != nil { - return false, fmt.Errorf("failed to read response body: %s", err.Error()) - } - - if err = health.Ready(); err != nil { - r.Log += fmt.Sprintf("application is not yet ready: %s\n", err.Error()) - return false, nil // Try again - } - - r.Log += fmt.Sprintf("application is ready at %s\n", base.String()) - return true, nil + return healthCheck(resp, r) }) - return err } diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 72bb48f1a..fed488d72 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -33,6 +33,7 @@ const ( CryostatCRTestName string = "cryostat-cr" CryostatRecordingTestName string = "cryostat-recording" CryostatConfigChangeTestName string = "cryostat-config-change" + CryostatReportTestName string = "cryostat-report" ) // OperatorInstallTest checks that the operator installed correctly @@ -97,7 +98,7 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope if err != nil { return fail(*r, fmt.Sprintf("failed to determine application URL: %s", err.Error())) } - defer cleanupCryostat(r, tr.Client, CryostatRecordingTestName, namespace) + defer cleanupCryostat(r, tr.Client, CryostatConfigChangeTestName, namespace) // Switch Cryostat CR to PVC for redeployment ctx, cancel := context.WithTimeout(context.Background(), testTimeout) @@ -126,7 +127,7 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope if err != nil { return fail(*r, fmt.Sprintf("Cryostat redeployment did not become available: %s", err.Error())) } - r.Log += "Cryostat deployment has successfully updated with new spec template" + r.Log += "Cryostat deployment has successfully updated with new spec template\n" base, err := url.Parse(cr.Status.ApplicationURL) if err != nil { @@ -278,3 +279,39 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh return *r } + +func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { + tr := newTestResources(CryostatReportTestName) + r := tr.TestResult + + err := setupCRTestResources(tr, openShiftCertManager) + if err != nil { + return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatReportTestName, err.Error())) + } + + port := int32(10000) + cr := newCryostatCR(CryostatReportTestName, namespace, !tr.OpenShift) + cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + Replicas: 1, + } + cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ + ReportsConfig: &operatorv1beta1.ReportsServiceConfig{ + HTTPPort: &port, + }, + } + + // Create a default Cryostat CR + cr, err = createAndWaitTillCryostatAvailable(cr, tr) + if err != nil { + return fail(*r, fmt.Sprintf("%s test failed: %s", CryostatReportTestName, err.Error())) + } + defer cleanupCryostat(r, tr.Client, CryostatReportTestName, namespace) + + // Query health of report sidecar + err = waitTillReportReady(cr.Name+"-reports", cr.Namespace, port, tr) + if err != nil { + return fail(*r, fmt.Sprintf("failed to reach the application: %s", err.Error())) + } + + return *r +} From 8fd5307feb772c5f5ff56bfed333f83dd6390f1a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:52:21 -0400 Subject: [PATCH 13/53] fix(build-ci): fix scorecard image tag returned as null (#760) (#768) Signed-off-by: Thuan Vo Co-authored-by: Elliott Baron (cherry picked from commit 2201704822677f0e1ad94fee0d64250a7af2e67c) Co-authored-by: Thuan Vo --- .github/workflows/build-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 41b2959ef..4fcb43481 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -97,7 +97,7 @@ jobs: - name: Get scorecard image tag id: get-image-tag run: | - SCORECARD_TAG=$(yq '[.stages[0].tests[].image | capture("cryostat-operator-scorecard:(?P[\w.\-_]+)$")][0].tag' bundle/tests/scorecard/config.yaml) + SCORECARD_TAG=$(yq '[.stages[1].tests[].image | capture("cryostat-operator-scorecard:(?P[\w.\-_]+)$")][0].tag' bundle/tests/scorecard/config.yaml) echo "tag=$SCORECARD_TAG" >> $GITHUB_OUTPUT - name: Check if scorecard image tag already exists id: check-tag-exists From 2619ae0ab12a2d766dcd6e26b31f60e46401d3b5 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 19 Mar 2024 10:34:48 -0400 Subject: [PATCH 14/53] chore(api): remove minimal option from CR spec (#751) --- api/v1beta1/cryostat_conversion.go | 2 - api/v1beta1/cryostat_conversion_test.go | 5 +- api/v1beta2/cryostat_types.go | 3 - ...yostat-operator.clusterserviceversion.yaml | 10 +- .../operator.cryostat.io_cryostats.yaml | 6 - .../bases/operator.cryostat.io_cryostats.yaml | 6 - ...yostat-operator.clusterserviceversion.yaml | 7 - config/samples/operator_v1beta2_cryostat.yaml | 1 - docs/config.md | 11 -- internal/controllers/certmanager.go | 45 +---- .../resource_definitions.go | 83 ++++----- internal/controllers/ingresses.go | 5 +- internal/controllers/reconciler.go | 2 - internal/controllers/reconciler_test.go | 164 ++---------------- internal/controllers/routes.go | 16 +- internal/controllers/secrets.go | 36 ++-- internal/controllers/services.go | 38 ++-- internal/test/conversion.go | 13 +- internal/test/resources.go | 88 +++++----- 19 files changed, 143 insertions(+), 398 deletions(-) diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index 99a4af703..de2b74a35 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -42,7 +42,6 @@ func (src *Cryostat) ConvertTo(dstRaw conversion.Hub) error { } func convertSpecTo(src *CryostatSpec, dst *operatorv1beta2.CryostatSpec) { - dst.Minimal = src.Minimal dst.EnableCertManager = src.EnableCertManager dst.TrustedCertSecrets = convertCertSecretsTo(src.TrustedCertSecrets) dst.EventTemplates = convertEventTemplatesTo(src.EventTemplates) @@ -326,7 +325,6 @@ func (dst *Cryostat) ConvertFrom(srcRaw conversion.Hub) error { } func convertSpecFrom(src *operatorv1beta2.CryostatSpec, dst *CryostatSpec) { - dst.Minimal = src.Minimal dst.EnableCertManager = src.EnableCertManager dst.TrustedCertSecrets = convertCertSecretsFrom(src.TrustedCertSecrets) dst.EventTemplates = convertEventTemplatesFrom(src.EventTemplates) diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go index 5a60d5e73..a7cbc1ec0 100644 --- a/api/v1beta1/cryostat_conversion_test.go +++ b/api/v1beta1/cryostat_conversion_test.go @@ -81,7 +81,10 @@ func tableEntriesTo() []TableEntry { Entry("WS connections", (*test.TestResources).NewCryostatWithWsConnectionsSpecV1Beta1, (*test.TestResources).NewCryostat), Entry("command config", (*test.TestResources).NewCryostatWithCommandConfigV1Beta1, - (*test.TestResources).NewCryostatWithIngress)) + (*test.TestResources).NewCryostatWithIngress), + Entry("minimal mode", (*test.TestResources).NewCryostatWithMinimalModeV1Beta1, + (*test.TestResources).NewCryostat), + ) } func tableEntriesFrom() []TableEntry { diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 6facea387..db2257e90 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -31,9 +31,6 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,order=2 TargetNamespaces []string `json:"targetNamespaces,omitempty"` - // Deploy a pared-down Cryostat instance with no Grafana Dashboard or JFR Data Source. - // +operator-sdk:csv:customresourcedefinitions:type=spec,order=4,displayName="Minimal Deployment",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} - Minimal bool `json:"minimal"` // List of TLS certificates to trust when connecting to targets. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Trusted TLS Certificates" diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index a7af2fe52..d3894b2e1 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -36,7 +36,6 @@ metadata: "spec": { "enableCertManager": true, "eventTemplates": [], - "minimal": false, "reportOptions": { "replicas": 0 }, @@ -54,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-03-15T21:38:16Z" + createdAt: "2024-03-18T06:34:51Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -65,7 +64,6 @@ metadata: }, "spec": { "enableCertManager": true, - "minimal": false, "reportOptions": { "replicas": 0 } @@ -527,12 +525,6 @@ spec: path: enableCertManager x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard - or JFR Data Source. - displayName: Minimal Deployment - path: minimal - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Override default authorization properties for Cryostat on OpenShift. displayName: Authorization Properties path: authProperties diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 44f3e7098..32b212f9e 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -4844,10 +4844,6 @@ spec: credentials database. type: string type: object - minimal: - description: Deploy a pared-down Cryostat instance with no Grafana - Dashboard or JFR Data Source. - type: boolean networkOptions: description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. @@ -9056,8 +9052,6 @@ spec: - secretName type: object type: array - required: - - minimal type: object status: description: CryostatStatus defines the observed state of Cryostat. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 558887e1a..96567c509 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -4834,10 +4834,6 @@ spec: credentials database. type: string type: object - minimal: - description: Deploy a pared-down Cryostat instance with no Grafana - Dashboard or JFR Data Source. - type: boolean networkOptions: description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. @@ -9046,8 +9042,6 @@ spec: - secretName type: object type: array - required: - - minimal type: object status: description: CryostatStatus defines the observed state of Cryostat. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index f119d07de..5595c1aa6 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -15,7 +15,6 @@ metadata: }, "spec": { "enableCertManager": true, - "minimal": false, "reportOptions": { "replicas": 0 } @@ -77,12 +76,6 @@ spec: path: enableCertManager x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Deploy a pared-down Cryostat instance with no Grafana Dashboard - or JFR Data Source. - displayName: Minimal Deployment - path: minimal - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Override default authorization properties for Cryostat on OpenShift. displayName: Authorization Properties path: authProperties diff --git a/config/samples/operator_v1beta2_cryostat.yaml b/config/samples/operator_v1beta2_cryostat.yaml index 69cc3b956..8f014f31d 100644 --- a/config/samples/operator_v1beta2_cryostat.yaml +++ b/config/samples/operator_v1beta2_cryostat.yaml @@ -3,7 +3,6 @@ kind: Cryostat metadata: name: cryostat-sample spec: - minimal: false enableCertManager: true trustedCertSecrets: [] eventTemplates: [] diff --git a/docs/config.md b/docs/config.md index afb374637..1633b3f95 100644 --- a/docs/config.md +++ b/docs/config.md @@ -20,17 +20,6 @@ When installed in a multi-namespace manner, all users with access to a Cryostat For now, all authorization checks are done against the namespace where Cryostat is installed. For a user to use Cryostat with workloads in a target namespace, that user must have the necessary Kubernetes permissions in the namespace where Cryostat is installed. -### Minimal Deployment -The `spec.minimal` property determines what is deployed alongside Cryostat. This value is set to `false` by default, which tells the operator to deploy Cryostat, with a [customized Grafana](https://github.com/cryostatio/cryostat-grafana-dashboard) and a [Grafana Data Source for JFR files](https://github.com/cryostatio/jfr-datasource) as 3 containers within a Pod. When `minimal` is set to `true`, the Deployment consists of only the Cryostat container. -```yaml -apiVersion: operator.cryostat.io/v1beta1 -kind: Cryostat -metadata: - name: cryostat-sample -spec: - minimal: true -``` - ### Disabling cert-manager Integration By default, the operator expects [cert-manager](https://cert-manager.io/) to be available in the cluster. The operator uses cert-manager to generate a self-signed CA to allow traffic between Cryostat components within the cluster to use HTTPS. If cert-manager is not available in the cluster, this integration can be disabled with the `spec.enableCertManager` property. ```yaml diff --git a/internal/controllers/certmanager.go b/internal/controllers/certmanager.go index 45b305b7a..294a47eea 100644 --- a/internal/controllers/certmanager.go +++ b/internal/controllers/certmanager.go @@ -24,7 +24,6 @@ import ( resources "github.com/cryostatio/cryostat-operator/internal/controllers/common/resource_definitions" "github.com/cryostatio/cryostat-operator/internal/controllers/model" corev1 "k8s.io/api/core/v1" - kerrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -95,26 +94,13 @@ func (r *Reconciler) setupTLS(ctx context.Context, cr *model.CryostatInstance) ( } certificates := []*certv1.Certificate{caCert, cryostatCert, reportsCert} // Create a certificate for Grafana signed by the Cryostat CA - if !cr.Spec.Minimal { - grafanaCert := resources.NewGrafanaCert(cr) - err = r.createOrUpdateCertificate(ctx, grafanaCert, cr.Object) - if err != nil { - return nil, err - } - certificates = append(certificates, grafanaCert) - tlsConfig.GrafanaSecret = grafanaCert.Spec.SecretName - } else { - grafanaCert := resources.NewGrafanaCert(cr) - secret := secretForCertificate(grafanaCert) - err = r.deleteSecret(ctx, secret) - if err != nil { - return nil, err - } - err = r.deleteCert(ctx, grafanaCert) - if err != nil { - return nil, err - } + grafanaCert := resources.NewGrafanaCert(cr) + err = r.createOrUpdateCertificate(ctx, grafanaCert, cr.Object) + if err != nil { + return nil, err } + certificates = append(certificates, grafanaCert) + tlsConfig.GrafanaSecret = grafanaCert.Spec.SecretName // Update owner references of TLS secrets created by cert-manager to ensure proper cleanup err = r.setCertSecretOwner(ctx, cr.Object, certificates...) @@ -211,15 +197,6 @@ func (r *Reconciler) setCertSecretOwner(ctx context.Context, owner metav1.Object return nil } -func secretForCertificate(cert *certv1.Certificate) *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: cert.Spec.SecretName, - Namespace: cert.Namespace, - }, - } -} - func (r *Reconciler) certManagerAvailable() (bool, error) { // Check if cert-manager API is available. Checking just one should be enough. _, err := r.RESTMapper.RESTMapping(schema.GroupKind{ @@ -316,16 +293,6 @@ func (r *Reconciler) createOrUpdateCertSecret(ctx context.Context, secret *corev return nil } -func (r *Reconciler) deleteCert(ctx context.Context, cert *certv1.Certificate) error { - err := r.Client.Delete(ctx, cert) - if err != nil && !kerrors.IsNotFound(err) { - r.Log.Error(err, "Could not delete certificate", "name", cert.Name, "namespace", cert.Namespace) - return err - } - r.Log.Info("Cert deleted", "name", cert.Name, "namespace", cert.Namespace) - return nil -} - func (r *Reconciler) getCertficateBytes(ctx context.Context, cert *certv1.Certificate) ([]byte, error) { secret, err := r.GetCertificateSecret(ctx, cert) if err != nil { diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 06c1a9d65..a3cf2bf43 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -237,17 +237,10 @@ func NewDeploymentForReports(cr *model.CryostatInstance, imageTags *ImageTags, t func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *ImageTags, tls *TLSConfig, fsGroup int64, openshift bool) *corev1.PodSpec { - var containers []corev1.Container - if cr.Spec.Minimal { - containers = []corev1.Container{ - NewCoreContainer(cr, specs, imageTags.CoreImageTag, tls, openshift), - } - } else { - containers = []corev1.Container{ - NewCoreContainer(cr, specs, imageTags.CoreImageTag, tls, openshift), - NewGrafanaContainer(cr, imageTags.GrafanaImageTag, tls), - NewJfrDatasourceContainer(cr, imageTags.DatasourceImageTag), - } + containers := []corev1.Container{ + NewCoreContainer(cr, specs, imageTags.CoreImageTag, tls, openshift), + NewGrafanaContainer(cr, imageTags.GrafanaImageTag, tls), + NewJfrDatasourceContainer(cr, imageTags.DatasourceImageTag), } volumes := newVolumeForCR(cr) @@ -296,35 +289,31 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima }, }) - keyVolume := corev1.Volume{ - Name: "keystore", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: tls.CryostatSecret, - Items: []corev1.KeyToPath{ - { - Key: "keystore.p12", - Path: "keystore.p12", - Mode: &readOnlyMode, + volumes = append(volumes, + corev1.Volume{ + Name: "keystore", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: tls.CryostatSecret, + Items: []corev1.KeyToPath{ + { + Key: "keystore.p12", + Path: "keystore.p12", + Mode: &readOnlyMode, + }, }, }, }, }, - } - - volumes = append(volumes, keyVolume) - - if !cr.Spec.Minimal { - grafanaSecretVolume := corev1.Volume{ + corev1.Volume{ Name: "grafana-tls-secret", VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ SecretName: tls.GrafanaSecret, }, }, - } - volumes = append(volumes, grafanaSecretVolume) - } + }, + ) } // Project certificate secrets into deployment @@ -886,26 +875,24 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag }, }) - if !cr.Spec.Minimal { - grafanaVars := []corev1.EnvVar{ - { - Name: "GRAFANA_DATASOURCE_URL", - Value: datasourceURL, + grafanaVars := []corev1.EnvVar{ + { + Name: "GRAFANA_DATASOURCE_URL", + Value: datasourceURL, + }, + } + if specs.GrafanaURL != nil { + grafanaVars = append(grafanaVars, + corev1.EnvVar{ + Name: "GRAFANA_DASHBOARD_EXT_URL", + Value: specs.GrafanaURL.String(), }, - } - if specs.GrafanaURL != nil { - grafanaVars = append(grafanaVars, - corev1.EnvVar{ - Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: specs.GrafanaURL.String(), - }, - corev1.EnvVar{ - Name: "GRAFANA_DASHBOARD_URL", - Value: getInternalDashboardURL(tls), - }) - } - envs = append(envs, grafanaVars...) + corev1.EnvVar{ + Name: "GRAFANA_DASHBOARD_URL", + Value: getInternalDashboardURL(tls), + }) } + envs = append(envs, grafanaVars...) livenessProbeScheme := corev1.URISchemeHTTP if tls == nil { diff --git a/internal/controllers/ingresses.go b/internal/controllers/ingresses.go index 33cde225a..307307875 100644 --- a/internal/controllers/ingresses.go +++ b/internal/controllers/ingresses.go @@ -61,10 +61,9 @@ func (r *Reconciler) reconcileGrafanaIngress(ctx context.Context, cr *model.Cryo }, } - if cr.Spec.Minimal || cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.GrafanaConfig == nil || + if cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.GrafanaConfig == nil || cr.Spec.NetworkOptions.GrafanaConfig.IngressSpec == nil { - // User has either chosen a minimal deployment or not requested - // an Ingress, delete if it exists + // User has not requested an Ingress, delete if it exists return r.deleteIngress(ctx, ingress) } grafanaConfig := configureGrafanaIngress(cr) diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index 812da566f..2973af1ef 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -176,8 +176,6 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn } } - reqLogger.Info("Spec", "Minimal", cr.Spec.Minimal) - // Create lock config map or fail if owned by another CR err := r.reconcileLockConfigMap(ctx, cr) if err != nil { diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index b6e2657ba..57c7402ef 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -275,46 +275,6 @@ func (c *controllerTest) commonTests() { }) } }) - Context("succesfully creates required resources for minimal deployment", func() { - BeforeEach(func() { - t.Minimal = true - t.GeneratedPasswords = []string{"credentials_database", "jmx", "keystore"} - t.objs = append(t.objs, t.NewCryostat().Object) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - }) - It("should create certificates", func() { - t.expectCertificates() - }) - It("should create RBAC", func() { - t.expectRBAC() - }) - It("should create routes", func() { - t.expectRoutes() - }) - It("should create persistent volume claim and set owner", func() { - t.expectPVC(t.NewDefaultPVC()) - }) - It("should create Credentials Database secret and set owner", func() { - t.expectCredentialsDatabaseSecret() - }) - It("should create JMX secret and set owner", func() { - t.expectJMXSecret() - }) - It("should create core service and set owner", func() { - t.expectCoreService() - }) - It("should set ApplicationURL in CR Status", func() { - t.expectStatusApplicationURL() - }) - It("should not set GrafanaSecret in CR Status", func() { - t.expectStatusGrafanaSecretName("") - }) - It("should create deployment and set owner", func() { - t.expectMainDeployment() - }) - }) Context("after cryostat reconciled successfully", func() { BeforeEach(func() { t.objs = append(t.objs, t.NewCryostat().Object) @@ -326,18 +286,6 @@ func (c *controllerTest) commonTests() { t.expectIdempotence() }) }) - Context("After a minimal cryostat reconciled successfully", func() { - BeforeEach(func() { - t.Minimal = true - t.objs = append(t.objs, t.NewCryostat().Object) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - }) - It("should be idempotent", func() { - t.expectIdempotence() - }) - }) Context("Cryostat does not exist", func() { It("should do nothing", func() { result, err := t.reconcileWithName("does-not-exist") @@ -609,88 +557,17 @@ func (c *controllerTest) commonTests() { t.reconcileCryostatFully() }) It("should update the Routes", func() { - if !t.Minimal { - expected := t.NewGrafanaRoute() - metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "grafana", "annotation") - metav1.SetMetaDataLabel(&expected.ObjectMeta, "grafana", "label") - t.checkRoute(expected) - } - expected := t.NewCoreRoute() + expected := t.NewGrafanaRoute() + metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "grafana", "annotation") + metav1.SetMetaDataLabel(&expected.ObjectMeta, "grafana", "label") + t.checkRoute(expected) + + expected = t.NewCoreRoute() metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "custom", "annotation") metav1.SetMetaDataLabel(&expected.ObjectMeta, "custom", "label") t.checkRoute(expected) }) }) - Context("Switching from a minimal to a non-minimal deployment", func() { - BeforeEach(func() { - t.Minimal = true - t.GeneratedPasswords = []string{"credentials_database", "jmx", "keystore", "grafana"} - t.objs = append(t.objs, t.NewCryostat().Object) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - - cryostat := t.getCryostatInstance() - - t.Minimal = false - cryostat.Spec.Minimal = false - t.updateCryostatInstance(cryostat) - - t.reconcileCryostatFully() - }) - It("should create Grafana network resources", func() { - t.expectGrafanaService() - }) - It("should create the Grafana secret", func() { - t.expectGrafanaSecret() - t.expectStatusGrafanaSecretName(t.NewGrafanaSecret().Name) - }) - It("should configure deployment appropriately", func() { - t.expectMainDeployment() - }) - It("should create certificates", func() { - t.expectCertificates() - }) - }) - Context("Switching from a non-minimal to a minimal deployment", func() { - BeforeEach(func() { - t.objs = append(t.objs, t.NewCryostat().Object) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - - cryostat := t.getCryostatInstance() - - t.Minimal = true - cryostat.Spec.Minimal = true - t.updateCryostatInstance(cryostat) - - t.reconcileCryostatFully() - }) - It("should delete Grafana network resources", func() { - service := &corev1.Service{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana", Namespace: t.Namespace}, service) - Expect(kerrors.IsNotFound(err)).To(BeTrue()) - - route := &openshiftv1.Route{} - err = t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana", Namespace: t.Namespace}, route) - Expect(kerrors.IsNotFound(err)).To(BeTrue()) - }) - It("should delete the Grafana secret", func() { - secret := &corev1.Secret{} - notExpected := t.NewGrafanaSecret() - err := t.Client.Get(context.Background(), types.NamespacedName{Name: notExpected.Name, Namespace: notExpected.Namespace}, secret) - Expect(kerrors.IsNotFound(err)).To(BeTrue()) - - t.expectStatusGrafanaSecretName("") - }) - It("should configure deployment appropriately", func() { - t.expectMainDeployment() - }) - It("should create certificates", func() { - t.expectCertificates() - }) - }) Context("with report generator service", func() { var cr *model.CryostatInstance BeforeEach(func() { @@ -2323,9 +2200,7 @@ func (c *controllerTest) commonTests() { } func (t *cryostatTestInput) expectRoutes() { - if !t.Minimal { - t.checkRoute(t.NewGrafanaRoute()) - } + t.checkRoute(t.NewGrafanaRoute()) t.checkRoute(t.NewCoreRoute()) } @@ -2420,16 +2295,7 @@ func (t *cryostatTestInput) expectWaitingForCertificate() { func (t *cryostatTestInput) expectCertificates() { // Check certificates - certs := []*certv1.Certificate{t.NewCryostatCert(), t.NewCACert(), t.NewReportsCert()} - if !t.Minimal { - certs = append(certs, t.NewGrafanaCert()) - } else { - actual := &certv1.Certificate{} - expected := t.NewGrafanaCert() - err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, actual) - Expect(err).To(HaveOccurred()) - Expect(kerrors.IsNotFound(err)) - } + certs := []*certv1.Certificate{t.NewCryostatCert(), t.NewCACert(), t.NewReportsCert(), t.NewGrafanaCert()} for _, expected := range certs { actual := &certv1.Certificate{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, actual) @@ -2867,15 +2733,13 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, dbSecretProvided, t.NewCoreContainerResource(cr), t.NewCoreSecurityContext(cr)) - if !t.Minimal { - // Check that Grafana is configured properly, depending on the environment - grafanaContainer := template.Spec.Containers[1] - t.checkGrafanaContainer(&grafanaContainer, t.NewGrafanaContainerResource(cr), t.NewGrafanaSecurityContext(cr)) + // Check that Grafana is configured properly, depending on the environment + grafanaContainer := template.Spec.Containers[1] + t.checkGrafanaContainer(&grafanaContainer, t.NewGrafanaContainerResource(cr), t.NewGrafanaSecurityContext(cr)) - // Check that JFR Datasource is configured properly - datasourceContainer := template.Spec.Containers[2] - t.checkDatasourceContainer(&datasourceContainer, t.NewDatasourceContainerResource(cr), t.NewDatasourceSecurityContext(cr)) - } + // Check that JFR Datasource is configured properly + datasourceContainer := template.Spec.Containers[2] + t.checkDatasourceContainer(&datasourceContainer, t.NewDatasourceContainerResource(cr), t.NewDatasourceSecurityContext(cr)) // Check that the proper Service Account is set Expect(template.Spec.ServiceAccountName).To(Equal(t.Name)) diff --git a/internal/controllers/routes.go b/internal/controllers/routes.go index 6f2a6145d..ef0b3920d 100644 --- a/internal/controllers/routes.go +++ b/internal/controllers/routes.go @@ -27,7 +27,6 @@ import ( "github.com/cryostatio/cryostat-operator/internal/controllers/model" routev1 "github.com/openshift/api/route/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) @@ -61,10 +60,7 @@ func (r *Reconciler) reconcileGrafanaRoute(ctx context.Context, svc *corev1.Serv Namespace: cr.InstallNamespace, }, } - if cr.Spec.Minimal { - // Delete route if it exists - return r.deleteRoute(ctx, route) - } + grafanaConfig := configureGrafanaRoute(cr) url, err := r.reconcileRoute(ctx, route, svc, cr, tls, grafanaConfig) if err != nil { @@ -145,16 +141,6 @@ func getProtocol(route *routev1.Route) string { return "https" } -func (r *Reconciler) deleteRoute(ctx context.Context, route *routev1.Route) error { - err := r.Client.Delete(ctx, route) - if err != nil && !errors.IsNotFound(err) { - r.Log.Error(err, "Could not delete route", "name", route.Name, "namespace", route.Namespace) - return err - } - r.Log.Info("Route deleted", "name", route.Name, "namespace", route.Namespace) - return nil -} - func getHTTPPort(svc *corev1.Service) (*corev1.ServicePort, error) { for _, port := range svc.Spec.Ports { if port.Name == constants.HttpPortName { diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index 66ff48c49..278ff5813 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -43,34 +43,24 @@ func (r *Reconciler) reconcileGrafanaSecret(ctx context.Context, cr *model.Cryos }, } - var secretName string - if cr.Spec.Minimal { - err := r.deleteSecret(ctx, secret) - if err != nil { - return err + err := r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { + if secret.StringData == nil { + secret.StringData = map[string]string{} } - secretName = "" - } else { - err := r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { - if secret.StringData == nil { - secret.StringData = map[string]string{} - } - secret.StringData["GF_SECURITY_ADMIN_USER"] = "admin" - - // Password is generated, so don't regenerate it when updating - if secret.CreationTimestamp.IsZero() { - secret.StringData["GF_SECURITY_ADMIN_PASSWORD"] = r.GenPasswd(20) - } - return nil - }) - if err != nil { - return err + secret.StringData["GF_SECURITY_ADMIN_USER"] = "admin" + + // Password is generated, so don't regenerate it when updating + if secret.CreationTimestamp.IsZero() { + secret.StringData["GF_SECURITY_ADMIN_PASSWORD"] = r.GenPasswd(20) } - secretName = secret.Name + return nil + }) + if err != nil { + return err } // Set the Grafana secret in the CR status - cr.Status.GrafanaSecret = secretName + cr.Status.GrafanaSecret = secret.Name return r.Client.Status().Update(ctx, cr.Object) } diff --git a/internal/controllers/services.go b/internal/controllers/services.go index 6718c2d2f..9a4c87408 100644 --- a/internal/controllers/services.go +++ b/internal/controllers/services.go @@ -81,31 +81,23 @@ func (r *Reconciler) reconcileGrafanaService(ctx context.Context, cr *model.Cryo }, } - if cr.Spec.Minimal { - // Delete service if it exists - err := r.deleteService(ctx, svc) - if err != nil { - return err + config := configureGrafanaService(cr) + err := r.createOrUpdateService(ctx, svc, cr.Object, &config.ServiceConfig, func() error { + svc.Spec.Selector = map[string]string{ + "app": cr.Name, + "component": "cryostat", } - } else { - config := configureGrafanaService(cr) - err := r.createOrUpdateService(ctx, svc, cr.Object, &config.ServiceConfig, func() error { - svc.Spec.Selector = map[string]string{ - "app": cr.Name, - "component": "cryostat", - } - svc.Spec.Ports = []corev1.ServicePort{ - { - Name: "http", - Port: *config.HTTPPort, - TargetPort: intstr.IntOrString{IntVal: 3000}, - }, - } - return nil - }) - if err != nil { - return err + svc.Spec.Ports = []corev1.ServicePort{ + { + Name: "http", + Port: *config.HTTPPort, + TargetPort: intstr.IntOrString{IntVal: 3000}, + }, } + return nil + }) + if err != nil { + return err } if r.IsOpenShift { diff --git a/internal/test/conversion.go b/internal/test/conversion.go index 246e9ca6a..71eb6485e 100644 --- a/internal/test/conversion.go +++ b/internal/test/conversion.go @@ -43,12 +43,23 @@ func (r *TestResources) newCryostatSpecV1Beta1() operatorv1beta1.CryostatSpec { } } return operatorv1beta1.CryostatSpec{ - Minimal: r.Minimal, EnableCertManager: &certManager, ReportOptions: reportOptions, } } +func (r *TestResources) NewCryostatWithMinimalModeV1Beta1() *operatorv1beta1.Cryostat { + spec := r.newCryostatSpecV1Beta1() + spec.Minimal = true + return &operatorv1beta1.Cryostat{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name, + Namespace: r.Namespace, + }, + Spec: spec, + } +} + func (r *TestResources) NewCryostatWithSecretsV1Beta1() *operatorv1beta1.Cryostat { cr := r.NewCryostatV1Beta1() key := "test.crt" diff --git a/internal/test/resources.go b/internal/test/resources.go index da76eaed0..3454d6da8 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -44,7 +44,6 @@ import ( type TestResources struct { Name string Namespace string - Minimal bool TLS bool ExternalTLS bool OpenShift bool @@ -106,7 +105,6 @@ func (r *TestResources) newCryostatSpec() operatorv1beta2.CryostatSpec { } return operatorv1beta2.CryostatSpec{ TargetNamespaces: r.TargetNamespaces, - Minimal: r.Minimal, EnableCertManager: &certManager, ReportOptions: reportOptions, } @@ -1340,15 +1338,13 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps Optional: &optional, }, }, - }) + }, + corev1.EnvVar{ + Name: "GRAFANA_DATASOURCE_URL", + Value: "http://127.0.0.1:8080", + }, + ) - if !r.Minimal { - envs = append(envs, - corev1.EnvVar{ - Name: "GRAFANA_DATASOURCE_URL", - Value: "http://127.0.0.1:8080", - }) - } if !r.TLS { envs = append(envs, corev1.EnvVar{ @@ -1472,33 +1468,31 @@ func (r *TestResources) newNetworkEnvironmentVariables() []corev1.EnvVar { Value: "80", }) } - if !r.Minimal { - if r.ExternalTLS { - envs = append(envs, - corev1.EnvVar{ - Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: fmt.Sprintf("https://%s-grafana.example.com", r.Name), - }) - } else { - envs = append(envs, - corev1.EnvVar{ - Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: fmt.Sprintf("http://%s-grafana.example.com", r.Name), - }) - } - if r.TLS { - envs = append(envs, - corev1.EnvVar{ - Name: "GRAFANA_DASHBOARD_URL", - Value: "https://cryostat-health.local:3000", - }) - } else { - envs = append(envs, - corev1.EnvVar{ - Name: "GRAFANA_DASHBOARD_URL", - Value: "http://cryostat-health.local:3000", - }) - } + if r.ExternalTLS { + envs = append(envs, + corev1.EnvVar{ + Name: "GRAFANA_DASHBOARD_EXT_URL", + Value: fmt.Sprintf("https://%s-grafana.example.com", r.Name), + }) + } else { + envs = append(envs, + corev1.EnvVar{ + Name: "GRAFANA_DASHBOARD_EXT_URL", + Value: fmt.Sprintf("http://%s-grafana.example.com", r.Name), + }) + } + if r.TLS { + envs = append(envs, + corev1.EnvVar{ + Name: "GRAFANA_DASHBOARD_URL", + Value: "https://cryostat-health.local:3000", + }) + } else { + envs = append(envs, + corev1.EnvVar{ + Name: "GRAFANA_DASHBOARD_URL", + Value: "http://cryostat-health.local:3000", + }) } return envs } @@ -2058,18 +2052,16 @@ func (r *TestResources) newVolumes(certProjections []corev1.VolumeProjection) [] }, }, }, - }) - if !r.Minimal { - volumes = append(volumes, - corev1.Volume{ - Name: "grafana-tls-secret", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: r.Name + "-grafana-tls", - }, + }, + corev1.Volume{ + Name: "grafana-tls-secret", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: r.Name + "-grafana-tls", }, - }) - } + }, + }, + ) } volumes = append(volumes, From 9f1fdee2a70b7bb232d8ca5f910f87aee3f19cf8 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 18:01:55 -0400 Subject: [PATCH 15/53] test(scorecard): add container logs to scorecard results (backport #758) (#770) * test(scorecard): add container logs to scorecard results (#758) * test(scorecard): add container logs to scorecard results * build(bundle): regenerate bundle with new scorecard tags * chore(scorecard): refactor to remove duplicate codes (cherry picked from commit d01e0d283d958b6540c9319c964d50f56964a330) # Conflicts: # bundle/manifests/cryostat-operator.clusterserviceversion.yaml # bundle/tests/scorecard/config.yaml * Fix conflicts --------- Co-authored-by: Thuan Vo Co-authored-by: Elliott Baron --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 10 +- config/scorecard/patches/custom.config.yaml | 10 +- .../rbac/scorecard_role.yaml | 7 ++ internal/test/scorecard/common_utils.go | 28 +++++ internal/test/scorecard/logger.go | 106 ++++++++++++++++++ internal/test/scorecard/tests.go | 8 +- 7 files changed, 159 insertions(+), 12 deletions(-) create mode 100644 internal/test/scorecard/logger.go diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index d3894b2e1..788b71fc2 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-03-18T06:34:51Z" + createdAt: "2024-03-19T22:00:40Z" 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 8822c74a5..b71a1c1a3 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:2.5.0-20240313155212 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 labels: suite: cryostat test: cryostat-recording @@ -100,7 +100,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 labels: suite: cryostat test: cryostat-config-change @@ -110,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 labels: suite: cryostat test: cryostat-report diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index f6e806ece..47d2cb999 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:2.5.0-20240313155212" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" labels: suite: cryostat test: cryostat-recording @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" labels: suite: cryostat test: cryostat-config-change @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240313155212" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" labels: suite: cryostat test: cryostat-report diff --git a/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml b/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml index d350e6464..7eaedd854 100644 --- a/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml +++ b/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml @@ -102,6 +102,13 @@ rules: - statefulsets verbs: - get +# Permissions to retrieve container logs +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index 00933fdf6..a35a2f916 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -32,8 +32,10 @@ import ( netv1 "k8s.io/api/networking/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" ) @@ -497,3 +499,29 @@ func cleanupCryostat(r *scapiv1alpha3.TestResult, client *CryostatClientset, nam r.Log += fmt.Sprintf("failed to delete Cryostat: %s\n", err.Error()) } } + +func getCryostatPodNameForCR(clientset *kubernetes.Clientset, cr *operatorv1beta1.Cryostat) (string, error) { + selector := metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": cr.Name, + "component": "cryostat", + }, + } + opts := metav1.ListOptions{ + LabelSelector: labels.Set(selector.MatchLabels).String(), + } + + ctx, cancel := context.WithTimeout(context.TODO(), testTimeout) + defer cancel() + + pods, err := clientset.CoreV1().Pods(cr.Namespace).List(ctx, opts) + if err != nil { + return "", err + } + + if len(pods.Items) == 0 { + return "", fmt.Errorf("no matching cryostat pods for cr: %s", cr.Name) + } + + return pods.Items[0].ObjectMeta.Name, nil +} diff --git a/internal/test/scorecard/logger.go b/internal/test/scorecard/logger.go new file mode 100644 index 000000000..4cfd8a51f --- /dev/null +++ b/internal/test/scorecard/logger.go @@ -0,0 +1,106 @@ +// 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 scorecard + +import ( + "context" + "fmt" + "io" + "strings" + + operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" + v1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes" +) + +type ContainerLog struct { + Container string + Log string +} + +func LogContainer(clientset *kubernetes.Clientset, namespace, podName, containerName string, ch chan *ContainerLog) { + containerLog := &ContainerLog{ + Container: containerName, + } + buf := &strings.Builder{} + + err := GetContainerLogs(clientset, namespace, podName, containerName, buf) + if err != nil { + buf.WriteString(fmt.Sprintf("%s\n", err.Error())) + } + + containerLog.Log = buf.String() + ch <- containerLog +} + +func GetContainerLogs(clientset *kubernetes.Clientset, namespace, podName, containerName string, dest io.Writer) error { + ctx, cancel := context.WithTimeout(context.TODO(), testTimeout) + defer cancel() + + logOptions := &v1.PodLogOptions{ + Follow: true, + Container: containerName, + } + stream, err := clientset.CoreV1().Pods(namespace).GetLogs(podName, logOptions).Stream(ctx) + if err != nil { + return fmt.Errorf("failed to get logs for container %s in pod %s: %s", containerName, podName, err.Error()) + } + defer stream.Close() + + _, err = io.Copy(dest, stream) + if err != nil { + return fmt.Errorf("failed to store logs for container %s in pod %s: %s", containerName, podName, err.Error()) + } + return nil +} + +func CollectLogs(ch chan *ContainerLog) []*ContainerLog { + logs := make([]*ContainerLog, 0) + for i := 0; i < cap(ch); i++ { + logs = append(logs, <-ch) + } + return logs +} + +func CollectContainersLogsToResult(result *scapiv1alpha3.TestResult, ch chan *ContainerLog) { + logs := CollectLogs(ch) + for _, log := range logs { + if log != nil { + result.Log += fmt.Sprintf("%s CONTAINER LOG:\n\n\t%s\n", strings.ToUpper(log.Container), log.Log) + } + } +} + +func StartLogs(clientset *kubernetes.Clientset, cr *operatorv1beta1.Cryostat) (chan *ContainerLog, error) { + podName, err := getCryostatPodNameForCR(clientset, cr) + if err != nil { + return nil, fmt.Errorf("failed to get pod name for CR: %s", err.Error()) + } + + containerNames := []string{ + cr.Name, + cr.Name + "-grafana", + cr.Name + "-jfr-datasource", + } + + ch := make(chan *ContainerLog, len(containerNames)) + + for _, containerName := range containerNames { + go LogContainer(clientset, cr.Namespace, podName, containerName, ch) + } + + return ch, nil +} diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index fed488d72..88c5cb217 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -143,7 +143,7 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope } // TODO add a built in discovery test too -func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { +func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) (result scapiv1alpha3.TestResult) { tr := newTestResources(CryostatRecordingTestName) r := tr.TestResult @@ -157,6 +157,12 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh if err != nil { return fail(*r, fmt.Sprintf("failed to determine application URL: %s", err.Error())) } + ch, err := StartLogs(tr.Client.Clientset, cr) + if err != nil { + return fail(*r, fmt.Sprintf("failed to retrieve logs for the application: %s", err.Error())) + } + defer CollectContainersLogsToResult(&result, ch) + defer cleanupCryostat(r, tr.Client, CryostatRecordingTestName, namespace) base, err := url.Parse(cr.Status.ApplicationURL) From b19e8f9b6c1e14b756daf017ad66e8de825ad969 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 18:04:11 -0400 Subject: [PATCH 16/53] add permission to publish comment when ci fails (#769) (#771) Co-authored-by: Elliott Baron (cherry picked from commit 6498b0f92236ceb6374cfeeedfc230c73ac0e67f) Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> --- .github/workflows/test-ci-command.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test-ci-command.yml b/.github/workflows/test-ci-command.yml index 2e1ffce2b..559991df1 100644 --- a/.github/workflows/test-ci-command.yml +++ b/.github/workflows/test-ci-command.yml @@ -119,6 +119,8 @@ jobs: if: (always() && contains(needs.*.result, 'failure')) runs-on: ubuntu-latest needs: [run-test-jobs] + permissions: + pull-requests: write steps: - name: Leave Actions Run Comment uses: actions/github-script@v6 From ecd45b3ac6d83ed208ffd329da4b61db1dda3a9c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:56:15 -0400 Subject: [PATCH 17/53] build(go): update Golang to 1.21 (#777) (#778) (cherry picked from commit 903e93fa58f34b6c2182944ee0c334d705997904) Co-authored-by: Elliott Baron --- .github/workflows/test-ci-reusable.yml | 2 +- Dockerfile | 2 +- README.md | 2 +- go.mod | 2 +- go.sum | 2 ++ internal/images/custom-scorecard-tests/Dockerfile | 2 +- 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-ci-reusable.yml b/.github/workflows/test-ci-reusable.yml index 860971ac5..0eefabd1b 100644 --- a/.github/workflows/test-ci-reusable.yml +++ b/.github/workflows/test-ci-reusable.yml @@ -48,7 +48,7 @@ jobs: ref: ${{ inputs.ref }} - uses: actions/setup-go@v4 with: - go-version: '1.20.*' + go-version: '1.21.*' - name: Run controller tests run: make test-envtest - name: Set latest commit status as ${{ job.status }} diff --git a/Dockerfile b/Dockerfile index d62951b64..daee119a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the manager binary -FROM docker.io/library/golang:1.20 as builder +FROM docker.io/library/golang:1.21 as builder ARG TARGETOS ARG TARGETARCH diff --git a/README.md b/README.md index 69e03e0a9..acd009cf7 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ kubectl get secret ${CRYOSTAT_NAME}-jmx-auth -o jsonpath='{$.data.CRYOSTAT_RJMX_ # Building ## Requirements -- `go` v1.20 +- `go` v1.21 - [`operator-sdk`](https://github.com/operator-framework/operator-sdk) v1.31.0 - [`cert-manager`](https://github.com/cert-manager/cert-manager) v1.11.5+ (Recommended) - `podman` or `docker` diff --git a/go.mod b/go.mod index b9e111672..db9c8957d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cryostatio/cryostat-operator -go 1.20 +go 1.21 require ( github.com/blang/semver/v4 v4.0.0 diff --git a/go.sum b/go.sum index d6c3e38d1..0460050f6 100644 --- a/go.sum +++ b/go.sum @@ -287,6 +287,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -305,6 +306,7 @@ go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= diff --git a/internal/images/custom-scorecard-tests/Dockerfile b/internal/images/custom-scorecard-tests/Dockerfile index 101f5efdf..2dc8ec4dd 100644 --- a/internal/images/custom-scorecard-tests/Dockerfile +++ b/internal/images/custom-scorecard-tests/Dockerfile @@ -13,7 +13,7 @@ # limitations under the License. # Build the manager binary -FROM docker.io/library/golang:1.20 as builder +FROM docker.io/library/golang:1.21 as builder ARG TARGETOS ARG TARGETARCH From 3306fffe9ed7b2c47af32c8183215e6312d0d769 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:49:01 -0400 Subject: [PATCH 18/53] test(scorecard): logWorkloadEvent for cryostat-recording errors (backport #759) (#779) * test(scorecard): logWorkloadEvent for cryostat-recording errors (#759) * logWorkLoadEvent for cryostat-recording errors * reviews * tr.LogChannel --------- Co-authored-by: Elliott Baron (cherry picked from commit baebe17122b18cfef30d6b7259979a5c5ffec519) # Conflicts: # bundle/manifests/cryostat-operator.clusterserviceversion.yaml # bundle/tests/scorecard/config.yaml # config/scorecard/patches/custom.config.yaml * Fix conflicts --------- Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Co-authored-by: Elliott Baron --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 10 ++--- config/scorecard/patches/custom.config.yaml | 10 ++--- internal/test/scorecard/common_utils.go | 37 ++++++++++++++++--- internal/test/scorecard/logger.go | 2 +- internal/test/scorecard/tests.go | 23 +++++------- 6 files changed, 53 insertions(+), 31 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 788b71fc2..963dbf3de 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-03-19T22:00:40Z" + createdAt: "2024-03-27T17:35:46Z" 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 b71a1c1a3..2ba49230e 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:2.5.0-20240319215831 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 labels: suite: cryostat test: cryostat-recording @@ -100,7 +100,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 labels: suite: cryostat test: cryostat-config-change @@ -110,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831 + image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 labels: suite: cryostat test: cryostat-report diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 47d2cb999..20303827e 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:2.5.0-20240319215831" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" labels: suite: cryostat test: cryostat-recording @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" labels: suite: cryostat test: cryostat-config-change @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240319215831" + image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" labels: suite: cryostat test: cryostat-report diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index a35a2f916..ea134a2ac 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -45,8 +45,9 @@ const ( ) type TestResources struct { - OpenShift bool - Client *CryostatClientset + OpenShift bool + Client *CryostatClientset + LogChannel chan *ContainerLog *scapiv1alpha3.TestResult } @@ -101,6 +102,9 @@ func logWorkloadEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, n ctx := context.Background() deploy, err := client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { + if kerrors.IsNotFound(err) { + return nil + } return err } // Log deployment conditions and events @@ -177,6 +181,18 @@ func logEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace return nil } +func LogWorkloadEventsOnError(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string, name string) { + if len(r.Errors) > 0 { + r.Log += "\nWORKLOAD EVENTS:\n" + for _, deployName := range []string{name, name + "-reports"} { + logErr := logWorkloadEvents(r, client, namespace, deployName) + if logErr != nil { + r.Log += fmt.Sprintf("failed to get workload logs: %s", logErr) + } + } + } +} + func newEmptyTestResult(testName string) *scapiv1alpha3.TestResult { return &scapiv1alpha3.TestResult{ Name: testName, @@ -485,7 +501,11 @@ func updateAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources return err } -func cleanupCryostat(r *scapiv1alpha3.TestResult, client *CryostatClientset, name string, namespace string) { +func cleanupAndLogs(r *scapiv1alpha3.TestResult, tr *TestResources, name string, namespace string) { + client := tr.Client + + LogWorkloadEventsOnError(r, client, namespace, name) + cr := &operatorv1beta1.Cryostat{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -493,10 +513,15 @@ func cleanupCryostat(r *scapiv1alpha3.TestResult, client *CryostatClientset, nam }, } ctx := context.Background() - err := client.OperatorCRDs().Cryostats(cr.Namespace).Delete(ctx, - cr.Name, &metav1.DeleteOptions{}) + err := client.OperatorCRDs().Cryostats(cr.Namespace).Delete(ctx, cr.Name, &metav1.DeleteOptions{}) if err != nil { - r.Log += fmt.Sprintf("failed to delete Cryostat: %s\n", err.Error()) + if !kerrors.IsNotFound(err) { + r.Log += fmt.Sprintf("failed to delete Cryostat: %s\n", err.Error()) + } + } + + if tr.LogChannel != nil { + CollectContainersLogsToResult(r, tr.LogChannel) } } diff --git a/internal/test/scorecard/logger.go b/internal/test/scorecard/logger.go index 4cfd8a51f..6b02761e0 100644 --- a/internal/test/scorecard/logger.go +++ b/internal/test/scorecard/logger.go @@ -79,7 +79,7 @@ func CollectContainersLogsToResult(result *scapiv1alpha3.TestResult, ch chan *Co logs := CollectLogs(ch) for _, log := range logs { if log != nil { - result.Log += fmt.Sprintf("%s CONTAINER LOG:\n\n\t%s\n", strings.ToUpper(log.Container), log.Log) + result.Log += fmt.Sprintf("\n%s CONTAINER LOG:\n\n\t%s\n", strings.ToUpper(log.Container), log.Log) } } } diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 88c5cb217..12a8bf2a3 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -37,7 +37,7 @@ const ( ) // OperatorInstallTest checks that the operator installed correctly -func OperatorInstallTest(bundle *apimanifests.Bundle, namespace string) scapiv1alpha3.TestResult { +func OperatorInstallTest(bundle *apimanifests.Bundle, namespace string) (result scapiv1alpha3.TestResult) { r := newEmptyTestResult(OperatorInstallTestName) // Create a new Kubernetes REST client for this test @@ -58,7 +58,7 @@ func OperatorInstallTest(bundle *apimanifests.Bundle, namespace string) scapiv1a } // CryostatCRTest checks that the operator installs Cryostat in response to a Cryostat CR -func CryostatCRTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { +func CryostatCRTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) (result scapiv1alpha3.TestResult) { tr := newTestResources(CryostatCRTestName) r := tr.TestResult @@ -66,18 +66,17 @@ func CryostatCRTest(bundle *apimanifests.Bundle, namespace string, openShiftCert if err != nil { return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatCRTestName, err.Error())) } + defer cleanupAndLogs(&result, tr, CryostatCRTestName, namespace) // Create a default Cryostat CR _, err = createAndWaitTillCryostatAvailable(newCryostatCR(CryostatCRTestName, namespace, !tr.OpenShift), tr) if err != nil { return fail(*r, fmt.Sprintf("%s test failed: %s", CryostatCRTestName, err.Error())) } - defer cleanupCryostat(r, tr.Client, CryostatCRTestName, namespace) - return *r } -func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { +func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) (result scapiv1alpha3.TestResult) { tr := newTestResources(CryostatConfigChangeTestName) r := tr.TestResult @@ -85,6 +84,7 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope if err != nil { return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatConfigChangeTestName, err.Error())) } + defer cleanupAndLogs(&result, tr, CryostatConfigChangeTestName, namespace) // Create a default Cryostat CR with default empty dir cr := newCryostatCR(CryostatConfigChangeTestName, namespace, !tr.OpenShift) @@ -98,7 +98,6 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope if err != nil { return fail(*r, fmt.Sprintf("failed to determine application URL: %s", err.Error())) } - defer cleanupCryostat(r, tr.Client, CryostatConfigChangeTestName, namespace) // Switch Cryostat CR to PVC for redeployment ctx, cancel := context.WithTimeout(context.Background(), testTimeout) @@ -151,19 +150,17 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh if err != nil { return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatRecordingTestName, err.Error())) } + defer cleanupAndLogs(&result, tr, CryostatRecordingTestName, namespace) // Create a default Cryostat CR cr, err := createAndWaitTillCryostatAvailable(newCryostatCR(CryostatRecordingTestName, namespace, !tr.OpenShift), tr) if err != nil { return fail(*r, fmt.Sprintf("failed to determine application URL: %s", err.Error())) } - ch, err := StartLogs(tr.Client.Clientset, cr) + tr.LogChannel, err = StartLogs(tr.Client.Clientset, cr) if err != nil { - return fail(*r, fmt.Sprintf("failed to retrieve logs for the application: %s", err.Error())) + r.Log += fmt.Sprintf("failed to retrieve logs for the application: %s", err.Error()) } - defer CollectContainersLogsToResult(&result, ch) - - defer cleanupCryostat(r, tr.Client, CryostatRecordingTestName, namespace) base, err := url.Parse(cr.Status.ApplicationURL) if err != nil { @@ -286,7 +283,7 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh return *r } -func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) scapiv1alpha3.TestResult { +func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) (result scapiv1alpha3.TestResult) { tr := newTestResources(CryostatReportTestName) r := tr.TestResult @@ -294,6 +291,7 @@ func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShift if err != nil { return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatReportTestName, err.Error())) } + defer cleanupAndLogs(&result, tr, CryostatReportTestName, namespace) port := int32(10000) cr := newCryostatCR(CryostatReportTestName, namespace, !tr.OpenShift) @@ -311,7 +309,6 @@ func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShift if err != nil { return fail(*r, fmt.Sprintf("%s test failed: %s", CryostatReportTestName, err.Error())) } - defer cleanupCryostat(r, tr.Client, CryostatReportTestName, namespace) // Query health of report sidecar err = waitTillReportReady(cr.Name+"-reports", cr.Namespace, port, tr) From db115b3902fa7236b58c86e8ebb49a331f2d8e34 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Wed, 27 Mar 2024 14:28:02 -0400 Subject: [PATCH 19/53] chore(version): bump version to 3.0.0-dev (#781) --- Makefile | 4 ++-- .../cryostat-operator.clusterserviceversion.yaml | 10 +++++----- bundle/tests/scorecard/config.yaml | 10 +++++----- config/manager/kustomization.yaml | 2 +- .../bases/cryostat-operator.clusterserviceversion.yaml | 2 +- config/scorecard/patches/custom.config.yaml | 10 +++++----- internal/controllers/const_generated.go | 2 +- internal/controllers/cryostat_controller.go | 3 +++ internal/controllers/insights/test/resources.go | 2 +- internal/tools/const_generator.go | 6 +++--- 10 files changed, 27 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 81dc3a4ea..fc33bbbd9 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ OS = $(shell go env GOOS) ARCH = $(shell go env GOARCH) # Current Operator version -export OPERATOR_VERSION ?= 2.5.0-dev +export OPERATOR_VERSION ?= 3.0.0-dev IMAGE_VERSION ?= $(OPERATOR_VERSION) BUNDLE_VERSION ?= $(IMAGE_VERSION) DEFAULT_NAMESPACE ?= quay.io/cryostat @@ -92,7 +92,7 @@ ENVTEST_K8S_VERSION ?= 1.26 # See: https://github.com/operator-framework/operator-sdk/pull/4762 # # Suffix is the timestamp of the image build, compute with: date -u '+%Y%m%d%H%M%S' -CUSTOM_SCORECARD_VERSION ?= 2.5.0-$(shell date -u '+%Y%m%d%H%M%S') +CUSTOM_SCORECARD_VERSION ?= 3.0.0-$(shell date -u '+%Y%m%d%H%M%S') export CUSTOM_SCORECARD_IMG ?= $(IMAGE_TAG_BASE)-scorecard:$(CUSTOM_SCORECARD_VERSION) DEPLOY_NAMESPACE ?= cryostat-operator-system diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 963dbf3de..295b91d3d 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -52,8 +52,8 @@ metadata: ] capabilities: Seamless Upgrades categories: Monitoring, Developer Tools - containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev - createdAt: "2024-03-27T17:35:46Z" + containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev + createdAt: "2024-03-27T18:00:37Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -77,7 +77,7 @@ metadata: operatorframework.io/arch.amd64: supported operatorframework.io/arch.arm64: supported operatorframework.io/os.linux: supported - name: cryostat-operator.v2.5.0-dev + name: cryostat-operator.v3.0.0-dev namespace: placeholder spec: apiservicedefinitions: {} @@ -1106,7 +1106,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: quay.io/cryostat/cryostat-operator:2.5.0-dev + image: quay.io/cryostat/cryostat-operator:3.0.0-dev imagePullPolicy: Always livenessProbe: httpGet: @@ -1234,7 +1234,7 @@ spec: name: grafana - image: quay.io/cryostat/cryostat-reports:latest name: reports - version: 2.5.0-dev + version: 3.0.0-dev webhookdefinitions: - admissionReviewVersions: - v1 diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml index 2ba49230e..2d65c780a 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:2.5.0-20240327173340 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 labels: suite: cryostat test: cryostat-recording @@ -100,7 +100,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 labels: suite: cryostat test: cryostat-config-change @@ -110,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 labels: suite: cryostat test: cryostat-report diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 116f3c815..55c8015cb 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -13,4 +13,4 @@ kind: Kustomization images: - name: controller newName: quay.io/cryostat/cryostat-operator - newTag: 2.5.0-dev + newTag: 3.0.0-dev diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 5595c1aa6..a4b0dad69 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -4,7 +4,7 @@ metadata: annotations: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools - containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev + containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 20303827e..5b91daab8 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:2.5.0-20240327173340" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" labels: suite: cryostat test: cryostat-recording @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" labels: suite: cryostat test: cryostat-config-change @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:2.5.0-20240327173340" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" labels: suite: cryostat test: cryostat-report diff --git a/internal/controllers/const_generated.go b/internal/controllers/const_generated.go index 52d842a9c..94f769ea5 100644 --- a/internal/controllers/const_generated.go +++ b/internal/controllers/const_generated.go @@ -5,7 +5,7 @@ package controllers const AppName = "Cryostat" // Version of the Cryostat Operator -const OperatorVersion = "2.5.0-dev" +const OperatorVersion = "3.0.0-dev" // Default image tag for the core application image const DefaultCoreImageTag = "quay.io/cryostat/cryostat:latest" diff --git a/internal/controllers/cryostat_controller.go b/internal/controllers/cryostat_controller.go index e32027d23..37541e6b1 100644 --- a/internal/controllers/cryostat_controller.go +++ b/internal/controllers/cryostat_controller.go @@ -26,6 +26,9 @@ 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/insights/test/resources.go b/internal/controllers/insights/test/resources.go index dffbe9848..8c7937059 100644 --- a/internal/controllers/insights/test/resources.go +++ b/internal/controllers/insights/test/resources.go @@ -31,7 +31,7 @@ type InsightsTestResources struct { Resources *corev1.ResourceRequirements } -const expectedOperatorVersion = "2.5.0-dev" +const expectedOperatorVersion = "3.0.0-dev" func (r *InsightsTestResources) NewGlobalPullSecret() *corev1.Secret { config := `{"auths":{"example.com":{"auth":"hello"},"cloud.openshift.com":{"auth":"world"}}}` diff --git a/internal/tools/const_generator.go b/internal/tools/const_generator.go index b2b932c10..eadea2eeb 100644 --- a/internal/tools/const_generator.go +++ b/internal/tools/const_generator.go @@ -29,9 +29,9 @@ const datasourceImageEnv = "DATASOURCE_IMG" const grafanaImageEnv = "GRAFANA_IMG" const reportsImageEnv = "REPORTS_IMG" -// This program generates a imagetag_generated.go file containing image tag -// constants for each container image deployed by the operator. These constants -// are populated using environment variables. +// This program generates a const_generated.go file containing image tag +// constants for each container image deployed by the operator, along with +// other constants. These constants are populated using environment variables. func main() { // Fill in image tags struct from the environment variables consts := struct { From 0b380d227f7b047571f8adf0a2467281ac3a5758 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:49:14 -0400 Subject: [PATCH 20/53] test(scorecard): fix rebasing skipped commit (#780) (#782) * Merge pull request #8 from ebaron/scorecard-methods test(scorecard): use methods for more easily passing data * update bundle image (cherry picked from commit b3970953d2bfcc2cf2add227a8a0687f6a65b52c) Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 10 +- config/scorecard/patches/custom.config.yaml | 10 +- .../images/custom-scorecard-tests/main.go | 10 +- internal/test/scorecard/common_utils.go | 113 ++++++-------- internal/test/scorecard/logger.go | 36 +++-- internal/test/scorecard/openshift.go | 3 +- internal/test/scorecard/tests.go | 142 +++++++++--------- 8 files changed, 151 insertions(+), 175 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 295b91d3d..d9a0669a7 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-03-27T18:00:37Z" + createdAt: "2024-03-27T18:30:58Z" 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 2d65c780a..30f793a8d 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:3.0.0-20240327175250 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 labels: suite: cryostat test: cryostat-recording @@ -100,7 +100,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 labels: suite: cryostat test: cryostat-config-change @@ -110,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 labels: suite: cryostat test: cryostat-report diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 5b91daab8..cba5454f8 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:3.0.0-20240327175250" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" labels: suite: cryostat test: cryostat-recording @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" labels: suite: cryostat test: cryostat-config-change @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327175250" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" labels: suite: cryostat test: cryostat-report diff --git a/internal/images/custom-scorecard-tests/main.go b/internal/images/custom-scorecard-tests/main.go index b3041281c..cce16f5a6 100644 --- a/internal/images/custom-scorecard-tests/main.go +++ b/internal/images/custom-scorecard-tests/main.go @@ -111,15 +111,15 @@ func runTests(testNames []string, bundle *apimanifests.Bundle, namespace string, for _, testName := range testNames { switch testName { case tests.OperatorInstallTestName: - results = append(results, tests.OperatorInstallTest(bundle, namespace)) + results = append(results, *tests.OperatorInstallTest(bundle, namespace, openShiftCertManager)) case tests.CryostatCRTestName: - results = append(results, tests.CryostatCRTest(bundle, namespace, openShiftCertManager)) + results = append(results, *tests.CryostatCRTest(bundle, namespace, openShiftCertManager)) case tests.CryostatRecordingTestName: - results = append(results, tests.CryostatRecordingTest(bundle, namespace, openShiftCertManager)) + results = append(results, *tests.CryostatRecordingTest(bundle, namespace, openShiftCertManager)) case tests.CryostatConfigChangeTestName: - results = append(results, tests.CryostatConfigChangeTest(bundle, namespace, openShiftCertManager)) + results = append(results, *tests.CryostatConfigChangeTest(bundle, namespace, openShiftCertManager)) case tests.CryostatReportTestName: - results = append(results, tests.CryostatReportTest(bundle, namespace, openShiftCertManager)) + results = append(results, *tests.CryostatReportTest(bundle, namespace, openShiftCertManager)) default: log.Fatalf("unknown test found: %s", testName) } diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index ea134a2ac..99c639ee0 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -35,7 +35,6 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" ) @@ -51,10 +50,9 @@ type TestResources struct { *scapiv1alpha3.TestResult } -func waitForDeploymentAvailability(ctx context.Context, client *CryostatClientset, namespace string, - name string, r *scapiv1alpha3.TestResult) error { +func (r *TestResources) waitForDeploymentAvailability(ctx context.Context, namespace string, name string) error { err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { - deploy, err := client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) + deploy, err := r.Client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { if kerrors.IsNotFound(err) { r.Log += fmt.Sprintf("deployment %s is not yet found\n", name) @@ -79,7 +77,7 @@ func waitForDeploymentAvailability(ctx context.Context, client *CryostatClientse return false, nil }) if err != nil { - logErr := logWorkloadEvents(r, client, namespace, name) + logErr := r.logWorkloadEvents(namespace, name) if logErr != nil { r.Log += fmt.Sprintf("failed to look up deployment errors: %s\n", logErr.Error()) } @@ -87,20 +85,20 @@ func waitForDeploymentAvailability(ctx context.Context, client *CryostatClientse return err } -func logError(r *scapiv1alpha3.TestResult, message string) { +func (r *TestResources) logError(message string) { r.State = scapiv1alpha3.FailState r.Errors = append(r.Errors, message) } -func fail(r scapiv1alpha3.TestResult, message string) scapiv1alpha3.TestResult { +func (r *TestResources) fail(message string) *scapiv1alpha3.TestResult { r.State = scapiv1alpha3.FailState r.Errors = append(r.Errors, message) - return r + return r.TestResult } -func logWorkloadEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string, name string) error { +func (r *TestResources) logWorkloadEvents(namespace string, name string) error { ctx := context.Background() - deploy, err := client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) + deploy, err := r.Client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { if kerrors.IsNotFound(err) { return nil @@ -115,7 +113,7 @@ func logWorkloadEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, n } r.Log += fmt.Sprintf("deployment %s warning events:\n", deploy.Name) - err = logEvents(r, client, namespace, scheme.Scheme, deploy) + err = r.logEvents(namespace, scheme.Scheme, deploy) if err != nil { return err } @@ -125,7 +123,7 @@ func logWorkloadEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, n if err != nil { return err } - replicaSets, err := client.AppsV1().ReplicaSets(namespace).List(ctx, metav1.ListOptions{ + replicaSets, err := r.Client.AppsV1().ReplicaSets(namespace).List(ctx, metav1.ListOptions{ LabelSelector: selector.String(), }) if err != nil { @@ -138,14 +136,14 @@ func logWorkloadEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, n condition.Reason, condition.Message) } r.Log += fmt.Sprintf("replica set %s warning events:\n", rs.Name) - err = logEvents(r, client, namespace, scheme.Scheme, &rs) + err = r.logEvents(namespace, scheme.Scheme, &rs) if err != nil { return err } } // Look up pods for deployment and log conditions and events - pods, err := client.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + pods, err := r.Client.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ LabelSelector: selector.String(), }) if err != nil { @@ -159,7 +157,7 @@ func logWorkloadEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, n condition.Reason, condition.Message) } r.Log += fmt.Sprintf("pod %s warning events:\n", pod.Name) - err = logEvents(r, client, namespace, scheme.Scheme, &pod) + err = r.logEvents(namespace, scheme.Scheme, &pod) if err != nil { return err } @@ -167,9 +165,8 @@ func logWorkloadEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, n return nil } -func logEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string, - scheme *runtime.Scheme, obj runtime.Object) error { - events, err := client.CoreV1().Events(namespace).Search(scheme, obj) +func (r *TestResources) logEvents(namespace string, scheme *runtime.Scheme, obj runtime.Object) error { + events, err := r.Client.CoreV1().Events(namespace).Search(scheme, obj) if err != nil { return err } @@ -181,11 +178,11 @@ func logEvents(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace return nil } -func LogWorkloadEventsOnError(r *scapiv1alpha3.TestResult, client *CryostatClientset, namespace string, name string) { +func (r *TestResources) LogWorkloadEventsOnError(namespace string, name string) { if len(r.Errors) > 0 { r.Log += "\nWORKLOAD EVENTS:\n" for _, deployName := range []string{name, name + "-reports"} { - logErr := logWorkloadEvents(r, client, namespace, deployName) + logErr := r.logWorkloadEvents(namespace, deployName) if logErr != nil { r.Log += fmt.Sprintf("failed to get workload logs: %s", logErr) } @@ -208,28 +205,26 @@ func newTestResources(testName string) *TestResources { } } -func setupCRTestResources(tr *TestResources, openShiftCertManager bool) error { - r := tr.TestResult - +func (r *TestResources) setupCRTestResources(openShiftCertManager bool) error { // Create a new Kubernetes REST client for this test client, err := NewClientset() if err != nil { - logError(r, fmt.Sprintf("failed to create client: %s", err.Error())) + r.logError(fmt.Sprintf("failed to create client: %s", err.Error())) return err } - tr.Client = client + r.Client = client openshift, err := isOpenShift(client) if err != nil { - logError(r, fmt.Sprintf("could not determine whether platform is OpenShift: %s", err.Error())) + r.logError(fmt.Sprintf("could not determine whether platform is OpenShift: %s", err.Error())) return err } - tr.OpenShift = openshift + r.OpenShift = openshift if openshift && openShiftCertManager { - err := installOpenShiftCertManager(r) + err := r.installOpenShiftCertManager() if err != nil { - logError(r, fmt.Sprintf("failed to install cert-manager Operator for Red Hat OpenShift: %s", err.Error())) + r.logError(fmt.Sprintf("failed to install cert-manager Operator for Red Hat OpenShift: %s", err.Error())) return err } } @@ -318,27 +313,24 @@ func newCryostatCR(name string, namespace string, withIngress bool) *operatorv1b return cr } -func createAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources *TestResources) (*operatorv1beta1.Cryostat, error) { - client := resources.Client - r := resources.TestResult - - cr, err := client.OperatorCRDs().Cryostats(cr.Namespace).Create(context.Background(), cr) +func (r *TestResources) createAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat) (*operatorv1beta1.Cryostat, error) { + cr, err := r.Client.OperatorCRDs().Cryostats(cr.Namespace).Create(context.Background(), cr) if err != nil { - logError(r, fmt.Sprintf("failed to create Cryostat CR: %s", err.Error())) + r.logError(fmt.Sprintf("failed to create Cryostat CR: %s", err.Error())) return nil, err } // Poll the deployment until it becomes available or we timeout ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err = waitForDeploymentAvailability(ctx, client, cr.Namespace, cr.Name, r) + err = r.waitForDeploymentAvailability(ctx, cr.Namespace, cr.Name) if err != nil { - logError(r, fmt.Sprintf("Cryostat main deployment did not become available: %s", err.Error())) + r.logError(fmt.Sprintf("Cryostat main deployment did not become available: %s", err.Error())) return nil, err } err = wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { - cr, err = client.OperatorCRDs().Cryostats(cr.Namespace).Get(ctx, cr.Name) + cr, err = r.Client.OperatorCRDs().Cryostats(cr.Namespace).Get(ctx, cr.Name) if err != nil { return false, fmt.Errorf("failed to get Cryostat CR: %s", err.Error()) } @@ -349,7 +341,7 @@ func createAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources return false, nil }) if err != nil { - logError(r, fmt.Sprintf("application URL not found in CR: %s", err.Error())) + r.logError(fmt.Sprintf("application URL not found in CR: %s", err.Error())) return nil, err } r.Log += fmt.Sprintf("application is available at %s\n", cr.Status.ApplicationURL) @@ -357,8 +349,8 @@ func createAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources return cr, nil } -func waitTillCryostatReady(base *url.URL, resources *TestResources) error { - return sendHealthRequest(base, resources, func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error) { +func (r *TestResources) waitTillCryostatReady(base *url.URL) error { + return r.sendHealthRequest(base, func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error) { health := &HealthResponse{} err = ReadJSON(resp, health) if err != nil { @@ -375,14 +367,11 @@ func waitTillCryostatReady(base *url.URL, resources *TestResources) error { }) } -func waitTillReportReady(name string, namespace string, port int32, resources *TestResources) error { - client := resources.Client - r := resources.TestResult - +func (r *TestResources) waitTillReportReady(name string, namespace string, port int32) error { ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err := waitForDeploymentAvailability(ctx, client, namespace, name, r) + err := r.waitForDeploymentAvailability(ctx, namespace, name) if err != nil { return fmt.Errorf("report sidecar deployment did not become available: %s", err.Error()) } @@ -393,15 +382,14 @@ func waitTillReportReady(name string, namespace string, port int32, resources *T return fmt.Errorf("application URL is invalid: %s", err.Error()) } - return sendHealthRequest(base, resources, func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error) { + return r.sendHealthRequest(base, func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error) { r.Log += fmt.Sprintf("reports sidecar is ready at %s\n", base.String()) return true, nil }) } -func sendHealthRequest(base *url.URL, resources *TestResources, healthCheck func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error)) error { +func (r *TestResources) sendHealthRequest(base *url.URL, healthCheck func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error)) error { client := NewHttpClient() - r := resources.TestResult ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() @@ -430,16 +418,13 @@ func sendHealthRequest(base *url.URL, resources *TestResources, healthCheck func } return false, fmt.Errorf("API request failed with status code %d: %s", resp.StatusCode, ReadError(resp)) } - return healthCheck(resp, r) + return healthCheck(resp, r.TestResult) }) return err } -func updateAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources *TestResources) error { - client := resources.Client - r := resources.TestResult - - cr, err := client.OperatorCRDs().Cryostats(cr.Namespace).Update(context.Background(), cr) +func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat) error { + cr, err := r.Client.OperatorCRDs().Cryostats(cr.Namespace).Update(context.Background(), cr) if err != nil { r.Log += fmt.Sprintf("failed to update Cryostat CR: %s", err.Error()) return err @@ -449,7 +434,7 @@ func updateAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() err = wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { - deploy, err := client.AppsV1().Deployments(cr.Namespace).Get(ctx, cr.Name, metav1.GetOptions{}) + deploy, err := r.Client.AppsV1().Deployments(cr.Namespace).Get(ctx, cr.Name, metav1.GetOptions{}) if err != nil { if kerrors.IsNotFound(err) { r.Log += fmt.Sprintf("deployment %s is not yet found\n", cr.Name) @@ -501,10 +486,8 @@ func updateAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat, resources return err } -func cleanupAndLogs(r *scapiv1alpha3.TestResult, tr *TestResources, name string, namespace string) { - client := tr.Client - - LogWorkloadEventsOnError(r, client, namespace, name) +func (r *TestResources) cleanupAndLogs(name string, namespace string) { + r.LogWorkloadEventsOnError(namespace, name) cr := &operatorv1beta1.Cryostat{ ObjectMeta: metav1.ObjectMeta{ @@ -513,19 +496,19 @@ func cleanupAndLogs(r *scapiv1alpha3.TestResult, tr *TestResources, name string, }, } ctx := context.Background() - err := client.OperatorCRDs().Cryostats(cr.Namespace).Delete(ctx, cr.Name, &metav1.DeleteOptions{}) + err := r.Client.OperatorCRDs().Cryostats(cr.Namespace).Delete(ctx, cr.Name, &metav1.DeleteOptions{}) if err != nil { if !kerrors.IsNotFound(err) { r.Log += fmt.Sprintf("failed to delete Cryostat: %s\n", err.Error()) } } - if tr.LogChannel != nil { - CollectContainersLogsToResult(r, tr.LogChannel) + if r.LogChannel != nil { + r.CollectContainersLogsToResult() } } -func getCryostatPodNameForCR(clientset *kubernetes.Clientset, cr *operatorv1beta1.Cryostat) (string, error) { +func (r *TestResources) getCryostatPodNameForCR(cr *operatorv1beta1.Cryostat) (string, error) { selector := metav1.LabelSelector{ MatchLabels: map[string]string{ "app": cr.Name, @@ -539,7 +522,7 @@ func getCryostatPodNameForCR(clientset *kubernetes.Clientset, cr *operatorv1beta ctx, cancel := context.WithTimeout(context.TODO(), testTimeout) defer cancel() - pods, err := clientset.CoreV1().Pods(cr.Namespace).List(ctx, opts) + pods, err := r.Client.CoreV1().Pods(cr.Namespace).List(ctx, opts) if err != nil { return "", err } diff --git a/internal/test/scorecard/logger.go b/internal/test/scorecard/logger.go index 6b02761e0..dd38d79b7 100644 --- a/internal/test/scorecard/logger.go +++ b/internal/test/scorecard/logger.go @@ -21,9 +21,7 @@ import ( "strings" operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" - scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" v1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes" ) type ContainerLog struct { @@ -31,22 +29,22 @@ type ContainerLog struct { Log string } -func LogContainer(clientset *kubernetes.Clientset, namespace, podName, containerName string, ch chan *ContainerLog) { +func (r *TestResources) logContainer(namespace, podName, containerName string) { containerLog := &ContainerLog{ Container: containerName, } buf := &strings.Builder{} - err := GetContainerLogs(clientset, namespace, podName, containerName, buf) + err := r.GetContainerLogs(namespace, podName, containerName, buf) if err != nil { buf.WriteString(fmt.Sprintf("%s\n", err.Error())) } containerLog.Log = buf.String() - ch <- containerLog + r.LogChannel <- containerLog } -func GetContainerLogs(clientset *kubernetes.Clientset, namespace, podName, containerName string, dest io.Writer) error { +func (r *TestResources) GetContainerLogs(namespace, podName, containerName string, dest io.Writer) error { ctx, cancel := context.WithTimeout(context.TODO(), testTimeout) defer cancel() @@ -54,7 +52,7 @@ func GetContainerLogs(clientset *kubernetes.Clientset, namespace, podName, conta Follow: true, Container: containerName, } - stream, err := clientset.CoreV1().Pods(namespace).GetLogs(podName, logOptions).Stream(ctx) + stream, err := r.Client.CoreV1().Pods(namespace).GetLogs(podName, logOptions).Stream(ctx) if err != nil { return fmt.Errorf("failed to get logs for container %s in pod %s: %s", containerName, podName, err.Error()) } @@ -67,27 +65,27 @@ func GetContainerLogs(clientset *kubernetes.Clientset, namespace, podName, conta return nil } -func CollectLogs(ch chan *ContainerLog) []*ContainerLog { +func (r *TestResources) CollectLogs() []*ContainerLog { logs := make([]*ContainerLog, 0) - for i := 0; i < cap(ch); i++ { - logs = append(logs, <-ch) + for i := 0; i < cap(r.LogChannel); i++ { + logs = append(logs, <-r.LogChannel) } return logs } -func CollectContainersLogsToResult(result *scapiv1alpha3.TestResult, ch chan *ContainerLog) { - logs := CollectLogs(ch) +func (r *TestResources) CollectContainersLogsToResult() { + logs := r.CollectLogs() for _, log := range logs { if log != nil { - result.Log += fmt.Sprintf("\n%s CONTAINER LOG:\n\n\t%s\n", strings.ToUpper(log.Container), log.Log) + r.Log += fmt.Sprintf("\n%s CONTAINER LOG:\n\n\t%s\n", strings.ToUpper(log.Container), log.Log) } } } -func StartLogs(clientset *kubernetes.Clientset, cr *operatorv1beta1.Cryostat) (chan *ContainerLog, error) { - podName, err := getCryostatPodNameForCR(clientset, cr) +func (r *TestResources) StartLogs(cr *operatorv1beta1.Cryostat) error { + podName, err := r.getCryostatPodNameForCR(cr) if err != nil { - return nil, fmt.Errorf("failed to get pod name for CR: %s", err.Error()) + return fmt.Errorf("failed to get pod name for CR: %s", err.Error()) } containerNames := []string{ @@ -96,11 +94,11 @@ func StartLogs(clientset *kubernetes.Clientset, cr *operatorv1beta1.Cryostat) (c cr.Name + "-jfr-datasource", } - ch := make(chan *ContainerLog, len(containerNames)) + r.LogChannel = make(chan *ContainerLog, len(containerNames)) for _, containerName := range containerNames { - go LogContainer(clientset, cr.Namespace, podName, containerName, ch) + go r.logContainer(cr.Namespace, podName, containerName) } - return ch, nil + return nil } diff --git a/internal/test/scorecard/openshift.go b/internal/test/scorecard/openshift.go index 247068a48..7880221ce 100644 --- a/internal/test/scorecard/openshift.go +++ b/internal/test/scorecard/openshift.go @@ -21,7 +21,6 @@ import ( "time" "github.com/blang/semver/v4" - scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" operatorsv1 "github.com/operator-framework/api/pkg/operators/v1" operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" ctrl "sigs.k8s.io/controller-runtime" @@ -39,7 +38,7 @@ import ( corev1client "k8s.io/client-go/kubernetes/typed/core/v1" ) -func installOpenShiftCertManager(r *scapiv1alpha3.TestResult) error { +func (r *TestResources) installOpenShiftCertManager() error { ctx := context.Background() // Get in-cluster REST config from pod diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 12a8bf2a3..9d3d251a6 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -37,76 +37,74 @@ const ( ) // OperatorInstallTest checks that the operator installed correctly -func OperatorInstallTest(bundle *apimanifests.Bundle, namespace string) (result scapiv1alpha3.TestResult) { - r := newEmptyTestResult(OperatorInstallTestName) +func OperatorInstallTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { + r := newTestResources(OperatorInstallTestName) // Create a new Kubernetes REST client for this test - client, err := NewClientset() + err := r.setupCRTestResources(openShiftCertManager) if err != nil { - return fail(*r, fmt.Sprintf("failed to create client: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to set up %s test: %s", OperatorInstallTestName, err.Error())) } + defer r.cleanupAndLogs(OperatorInstallTestName, namespace) // Poll the deployment until it becomes available or we timeout ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err = waitForDeploymentAvailability(ctx, client, namespace, operatorDeploymentName, r) + err = r.waitForDeploymentAvailability(ctx, namespace, operatorDeploymentName) if err != nil { - return fail(*r, fmt.Sprintf("operator deployment did not become available: %s", err.Error())) + return r.fail(fmt.Sprintf("operator deployment did not become available: %s", err.Error())) } - return *r + return r.TestResult } // CryostatCRTest checks that the operator installs Cryostat in response to a Cryostat CR -func CryostatCRTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) (result scapiv1alpha3.TestResult) { - tr := newTestResources(CryostatCRTestName) - r := tr.TestResult +func CryostatCRTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { + r := newTestResources(CryostatCRTestName) - err := setupCRTestResources(tr, openShiftCertManager) + err := r.setupCRTestResources(openShiftCertManager) if err != nil { - return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatCRTestName, err.Error())) + return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatCRTestName, err.Error())) } - defer cleanupAndLogs(&result, tr, CryostatCRTestName, namespace) + defer r.cleanupAndLogs(CryostatCRTestName, namespace) // Create a default Cryostat CR - _, err = createAndWaitTillCryostatAvailable(newCryostatCR(CryostatCRTestName, namespace, !tr.OpenShift), tr) + _, err = r.createAndWaitTillCryostatAvailable(newCryostatCR(CryostatCRTestName, namespace, !r.OpenShift)) if err != nil { - return fail(*r, fmt.Sprintf("%s test failed: %s", CryostatCRTestName, err.Error())) + return r.fail(fmt.Sprintf("%s test failed: %s", CryostatCRTestName, err.Error())) } - return *r + return r.TestResult } -func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) (result scapiv1alpha3.TestResult) { - tr := newTestResources(CryostatConfigChangeTestName) - r := tr.TestResult +func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { + r := newTestResources(CryostatConfigChangeTestName) - err := setupCRTestResources(tr, openShiftCertManager) + err := r.setupCRTestResources(openShiftCertManager) if err != nil { - return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatConfigChangeTestName, err.Error())) + return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatConfigChangeTestName, err.Error())) } - defer cleanupAndLogs(&result, tr, CryostatConfigChangeTestName, namespace) + defer r.cleanupAndLogs(CryostatConfigChangeTestName, namespace) // Create a default Cryostat CR with default empty dir - cr := newCryostatCR(CryostatConfigChangeTestName, namespace, !tr.OpenShift) + cr := newCryostatCR(CryostatConfigChangeTestName, namespace, !r.OpenShift) cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ EmptyDir: &operatorv1beta1.EmptyDirConfig{ Enabled: true, }, } - _, err = createAndWaitTillCryostatAvailable(cr, tr) + _, err = r.createAndWaitTillCryostatAvailable(cr) if err != nil { - return fail(*r, fmt.Sprintf("failed to determine application URL: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to determine application URL: %s", err.Error())) } // Switch Cryostat CR to PVC for redeployment ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - client := tr.Client - cr, err = client.OperatorCRDs().Cryostats(namespace).Get(ctx, CryostatConfigChangeTestName) + cr, err = r.Client.OperatorCRDs().Cryostats(namespace).Get(ctx, CryostatConfigChangeTestName) if err != nil { - return fail(*r, fmt.Sprintf("failed to get Cryostat CR: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to get Cryostat CR: %s", err.Error())) } cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ @@ -122,54 +120,53 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope } // Wait for redeployment of Cryostat CR - err = updateAndWaitTillCryostatAvailable(cr, tr) + err = r.updateAndWaitTillCryostatAvailable(cr) if err != nil { - return fail(*r, fmt.Sprintf("Cryostat redeployment did not become available: %s", err.Error())) + return r.fail(fmt.Sprintf("Cryostat redeployment did not become available: %s", err.Error())) } r.Log += "Cryostat deployment has successfully updated with new spec template\n" base, err := url.Parse(cr.Status.ApplicationURL) if err != nil { - return fail(*r, fmt.Sprintf("application URL is invalid: %s", err.Error())) + return r.fail(fmt.Sprintf("application URL is invalid: %s", err.Error())) } - err = waitTillCryostatReady(base, tr) + err = r.waitTillCryostatReady(base) if err != nil { - return fail(*r, fmt.Sprintf("failed to reach the application: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to reach the application: %s", err.Error())) } - return *r + return r.TestResult } // TODO add a built in discovery test too -func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) (result scapiv1alpha3.TestResult) { - tr := newTestResources(CryostatRecordingTestName) - r := tr.TestResult +func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { + r := newTestResources(CryostatRecordingTestName) - err := setupCRTestResources(tr, openShiftCertManager) + err := r.setupCRTestResources(openShiftCertManager) if err != nil { - return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatRecordingTestName, err.Error())) + return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatRecordingTestName, err.Error())) } - defer cleanupAndLogs(&result, tr, CryostatRecordingTestName, namespace) + defer r.cleanupAndLogs(CryostatRecordingTestName, namespace) // Create a default Cryostat CR - cr, err := createAndWaitTillCryostatAvailable(newCryostatCR(CryostatRecordingTestName, namespace, !tr.OpenShift), tr) + cr, err := r.createAndWaitTillCryostatAvailable(newCryostatCR(CryostatRecordingTestName, namespace, !r.OpenShift)) if err != nil { - return fail(*r, fmt.Sprintf("failed to determine application URL: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to determine application URL: %s", err.Error())) } - tr.LogChannel, err = StartLogs(tr.Client.Clientset, cr) + err = r.StartLogs(cr) if err != nil { r.Log += fmt.Sprintf("failed to retrieve logs for the application: %s", err.Error()) } base, err := url.Parse(cr.Status.ApplicationURL) if err != nil { - return fail(*r, fmt.Sprintf("application URL is invalid: %s", err.Error())) + return r.fail(fmt.Sprintf("application URL is invalid: %s", err.Error())) } - err = waitTillCryostatReady(base, tr) + err = r.waitTillCryostatReady(base) if err != nil { - return fail(*r, fmt.Sprintf("failed to reach the application: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to reach the application: %s", err.Error())) } apiClient := NewCryostatRESTClientset(base) @@ -181,15 +178,15 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh } target, err := apiClient.Targets().Create(context.Background(), targetOptions) if err != nil { - return fail(*r, fmt.Sprintf("failed to create a target: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to create a target: %s", err.Error())) } r.Log += fmt.Sprintf("created a custom target: %+v\n", target) connectUrl := target.ConnectUrl jmxSecretName := CryostatRecordingTestName + "-jmx-auth" - secret, err := tr.Client.CoreV1().Secrets(namespace).Get(context.Background(), jmxSecretName, metav1.GetOptions{}) + secret, err := r.Client.CoreV1().Secrets(namespace).Get(context.Background(), jmxSecretName, metav1.GetOptions{}) if err != nil { - return fail(*r, fmt.Sprintf("failed to get jmx credentials: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to get jmx credentials: %s", err.Error())) } credential := &Credential{ @@ -200,7 +197,7 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh err = apiClient.CredentialClient.Create(context.Background(), credential) if err != nil { - return fail(*r, fmt.Sprintf("failed to create stored credential: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to create stored credential: %s", err.Error())) } r.Log += fmt.Sprintf("created stored credential with match expression: %s\n", credential.MatchExpression) @@ -218,14 +215,14 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh } rec, err := apiClient.Recordings().Create(context.Background(), connectUrl, options) if err != nil { - return fail(*r, fmt.Sprintf("failed to create a recording: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to create a recording: %s", err.Error())) } r.Log += fmt.Sprintf("created a recording: %+v\n", rec) // View the current recording list after creating one recs, err := apiClient.Recordings().List(context.Background(), connectUrl) if err != nil { - return fail(*r, fmt.Sprintf("failed to list recordings: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to list recordings: %s", err.Error())) } r.Log += fmt.Sprintf("current list of recordings: %+v\n", recs) @@ -235,66 +232,65 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh // Archive the recording archiveName, err := apiClient.Recordings().Archive(context.Background(), connectUrl, rec.Name) if err != nil { - return fail(*r, fmt.Sprintf("failed to archive the recording: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to archive the recording: %s", err.Error())) } r.Log += fmt.Sprintf("archived the recording %s at: %s\n", rec.Name, archiveName) archives, err := apiClient.Recordings().ListArchives(context.Background(), connectUrl) if err != nil { - return fail(*r, fmt.Sprintf("failed to list archives: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to list archives: %s", err.Error())) } r.Log += fmt.Sprintf("current list of archives: %+v\n", archives) report, err := apiClient.Recordings().GenerateReport(context.Background(), connectUrl, rec) if err != nil { - return fail(*r, fmt.Sprintf("failed to generate report for the recording: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to generate report for the recording: %s", err.Error())) } r.Log += fmt.Sprintf("generated report for the recording %s: %+v\n", rec.Name, report) // Stop the recording err = apiClient.Recordings().Stop(context.Background(), connectUrl, rec.Name) if err != nil { - return fail(*r, fmt.Sprintf("failed to stop the recording %s: %s", rec.Name, err.Error())) + return r.fail(fmt.Sprintf("failed to stop the recording %s: %s", rec.Name, err.Error())) } // Get the recording to verify its state rec, err = apiClient.Recordings().Get(context.Background(), connectUrl, rec.Name) if err != nil { - return fail(*r, fmt.Sprintf("failed to get the recordings: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to get the recordings: %s", err.Error())) } if rec.State != "STOPPED" { - return fail(*r, fmt.Sprintf("recording %s failed to stop: %s", rec.Name, err.Error())) + return r.fail(fmt.Sprintf("recording %s failed to stop: %s", rec.Name, err.Error())) } r.Log += fmt.Sprintf("stopped the recording: %s\n", rec.Name) // Delete the recording err = apiClient.Recordings().Delete(context.Background(), connectUrl, rec.Name) if err != nil { - return fail(*r, fmt.Sprintf("failed to delete the recording %s: %s", rec.Name, err.Error())) + return r.fail(fmt.Sprintf("failed to delete the recording %s: %s", rec.Name, err.Error())) } r.Log += fmt.Sprintf("deleted the recording: %s\n", rec.Name) // View the current recording list after deleting one recs, err = apiClient.Recordings().List(context.Background(), connectUrl) if err != nil { - return fail(*r, fmt.Sprintf("failed to list recordings: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to list recordings: %s", err.Error())) } r.Log += fmt.Sprintf("current list of recordings: %+v\n", recs) - return *r + return r.TestResult } -func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) (result scapiv1alpha3.TestResult) { - tr := newTestResources(CryostatReportTestName) - r := tr.TestResult +func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { + r := newTestResources(CryostatReportTestName) - err := setupCRTestResources(tr, openShiftCertManager) + err := r.setupCRTestResources(openShiftCertManager) if err != nil { - return fail(*r, fmt.Sprintf("failed to set up %s test: %s", CryostatReportTestName, err.Error())) + return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatReportTestName, err.Error())) } - defer cleanupAndLogs(&result, tr, CryostatReportTestName, namespace) + defer r.cleanupAndLogs(CryostatReportTestName, namespace) port := int32(10000) - cr := newCryostatCR(CryostatReportTestName, namespace, !tr.OpenShift) + cr := newCryostatCR(CryostatReportTestName, namespace, !r.OpenShift) cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ Replicas: 1, } @@ -305,16 +301,16 @@ func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShift } // Create a default Cryostat CR - cr, err = createAndWaitTillCryostatAvailable(cr, tr) + cr, err = r.createAndWaitTillCryostatAvailable(cr) if err != nil { - return fail(*r, fmt.Sprintf("%s test failed: %s", CryostatReportTestName, err.Error())) + return r.fail(fmt.Sprintf("%s test failed: %s", CryostatReportTestName, err.Error())) } // Query health of report sidecar - err = waitTillReportReady(cr.Name+"-reports", cr.Namespace, port, tr) + err = r.waitTillReportReady(cr.Name+"-reports", cr.Namespace, port) if err != nil { - return fail(*r, fmt.Sprintf("failed to reach the application: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to reach the application: %s", err.Error())) } - return *r + return r.TestResult } From 3fcbfab356fb38594e9957c548738615a5ccdf03 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Wed, 3 Apr 2024 16:26:26 -0400 Subject: [PATCH 21/53] ci(branch): run push workflows on cryostat3 branch (#786) --- .github/workflows/build-ci.yml | 2 ++ .github/workflows/test-ci-push.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 4fcb43481..b6dfc8f46 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -11,6 +11,8 @@ on: - v[0-9]+ - v[0-9]+.[0-9]+ - cryostat-v[0-9]+.[0-9]+ + # TODO remove once merged into main + - cryostat3 env: CI_USER: cryostat+bot diff --git a/.github/workflows/test-ci-push.yml b/.github/workflows/test-ci-push.yml index 0975e4149..df523c501 100644 --- a/.github/workflows/test-ci-push.yml +++ b/.github/workflows/test-ci-push.yml @@ -11,6 +11,8 @@ on: - v[0-9]+ - v[0-9]+.[0-9]+ - cryostat-v[0-9]+.[0-9]+ + # TODO remove once merged into main + - cryostat3 jobs: check-before-test: From 461096ccfcbad99ddfb002f5bcf803fb76d6c733 Mon Sep 17 00:00:00 2001 From: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Date: Fri, 5 Apr 2024 17:47:34 -0400 Subject: [PATCH 22/53] test(scorecard): multi-namespace scorecard test for 3.0 (#773) * 3.0 multi-namespace scorecard test * refractor testResources --- api/v1beta1/cryostat_types.go | 2 +- ...yostat-operator.clusterserviceversion.yaml | 6 +- .../operator.cryostat.io_cryostats.yaml | 5 +- bundle/tests/scorecard/config.yaml | 20 +- .../bases/operator.cryostat.io_cryostats.yaml | 5 +- ...yostat-operator.clusterserviceversion.yaml | 4 +- config/scorecard/patches/custom.config.yaml | 20 +- hack/custom.config.yaml.in | 10 + .../images/custom-scorecard-tests/main.go | 4 + .../rbac/scorecard_role.yaml | 9 + internal/test/scorecard/clients.go | 18 +- internal/test/scorecard/common_utils.go | 249 +++++++++++------- internal/test/scorecard/logger.go | 4 +- internal/test/scorecard/tests.go | 89 ++++--- 14 files changed, 286 insertions(+), 159 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index a480a28c6..9d554e068 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -419,7 +419,7 @@ type JmxCacheOptions struct { // Cryostat allows you to install Cryostat for a single namespace. // It contains configuration options for controlling the Deployment of the Cryostat // application and its related components. -// A ClusterCryostat or Cryostat instance must be created to instruct the operator +// A Cryostat instance must be created to instruct the operator // to deploy the Cryostat application. // +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} // +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index d9a0669a7..c8e3d1a59 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-03-27T18:30:58Z" + createdAt: "2024-04-04T17:19:02Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -85,8 +85,8 @@ spec: owned: - description: Cryostat allows you to install Cryostat for a single namespace. It contains configuration options for controlling the Deployment of the Cryostat - application and its related components. A ClusterCryostat or Cryostat instance - must be created to instruct the operator to deploy the Cryostat application. + application and its related components. A Cryostat instance must be created + to instruct the operator to deploy the Cryostat application. displayName: Cryostat kind: Cryostat name: cryostats.operator.cryostat.io diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 32b212f9e..6b5826616 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -37,9 +37,8 @@ spec: openAPIV3Schema: description: Cryostat allows you to install Cryostat for a single namespace. It contains configuration options for controlling the Deployment of the - Cryostat application and its related components. A ClusterCryostat or Cryostat - instance must be created to instruct the operator to deploy the Cryostat - application. + Cryostat application and its related components. A Cryostat instance must + be created to instruct the operator to deploy the Cryostat application. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml index 30f793a8d..acc4e5d26 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:3.0.0-20240327182927 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404165315 labels: suite: cryostat test: operator-install @@ -80,17 +80,27 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404165315 labels: suite: cryostat test: cryostat-cr storage: spec: mountPath: {} + - entrypoint: + - cryostat-scorecard-tests + - cryostat-multi-namespace + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404165315 + labels: + suite: cryostat + test: cryostat-multi-namespace + storage: + spec: + mountPath: {} - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404165315 labels: suite: cryostat test: cryostat-recording @@ -100,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404165315 labels: suite: cryostat test: cryostat-config-change @@ -110,7 +120,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404165315 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 96567c509..0739136ab 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -27,9 +27,8 @@ spec: openAPIV3Schema: description: Cryostat allows you to install Cryostat for a single namespace. It contains configuration options for controlling the Deployment of the - Cryostat application and its related components. A ClusterCryostat or Cryostat - instance must be created to instruct the operator to deploy the Cryostat - application. + Cryostat application and its related components. A Cryostat instance must + be created to instruct the operator to deploy the Cryostat application. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index a4b0dad69..f78ca7ac2 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -415,8 +415,8 @@ spec: version: v1beta2 - description: Cryostat allows you to install Cryostat for a single namespace. It contains configuration options for controlling the Deployment of the Cryostat - application and its related components. A ClusterCryostat or Cryostat instance - must be created to instruct the operator to deploy the Cryostat application. + application and its related components. A Cryostat instance must be created + to instruct the operator to deploy the Cryostat application. displayName: Cryostat kind: Cryostat name: cryostats.operator.cryostat.io diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index cba5454f8..f095f1d50 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:3.0.0-20240327182927" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" labels: suite: cryostat test: operator-install @@ -18,17 +18,27 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" labels: suite: cryostat test: cryostat-cr +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-multi-namespace + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" + labels: + suite: cryostat + test: cryostat-multi-namespace - op: add path: /stages/1/tests/- value: entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" labels: suite: cryostat test: cryostat-recording @@ -38,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" labels: suite: cryostat test: cryostat-config-change @@ -48,7 +58,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240327182927" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" labels: suite: cryostat test: cryostat-report diff --git a/hack/custom.config.yaml.in b/hack/custom.config.yaml.in index 4336abbe4..75306a910 100644 --- a/hack/custom.config.yaml.in +++ b/hack/custom.config.yaml.in @@ -21,6 +21,16 @@ labels: suite: cryostat test: cryostat-cr +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-multi-namespace + image: "${CUSTOM_SCORECARD_IMG}" + labels: + suite: cryostat + test: cryostat-multi-namespace - op: add path: /stages/1/tests/- value: diff --git a/internal/images/custom-scorecard-tests/main.go b/internal/images/custom-scorecard-tests/main.go index cce16f5a6..5592e766f 100644 --- a/internal/images/custom-scorecard-tests/main.go +++ b/internal/images/custom-scorecard-tests/main.go @@ -79,6 +79,7 @@ func printValidTests() []scapiv1alpha3.TestResult { str := fmt.Sprintf("valid tests for this image include: %s", strings.Join([]string{ tests.OperatorInstallTestName, tests.CryostatCRTestName, + tests.CryostatMultiNamespaceTestName, tests.CryostatRecordingTestName, tests.CryostatConfigChangeTestName, tests.CryostatReportTestName, @@ -93,6 +94,7 @@ func validateTests(testNames []string) bool { switch testName { case tests.OperatorInstallTestName: case tests.CryostatCRTestName: + case tests.CryostatMultiNamespaceTestName: case tests.CryostatRecordingTestName: case tests.CryostatConfigChangeTestName: case tests.CryostatReportTestName: @@ -114,6 +116,8 @@ func runTests(testNames []string, bundle *apimanifests.Bundle, namespace string, results = append(results, *tests.OperatorInstallTest(bundle, namespace, openShiftCertManager)) case tests.CryostatCRTestName: results = append(results, *tests.CryostatCRTest(bundle, namespace, openShiftCertManager)) + case tests.CryostatMultiNamespaceTestName: + results = append(results, *tests.CryostatMultiNamespaceTest(bundle, namespace, openShiftCertManager)) case tests.CryostatRecordingTestName: results = append(results, *tests.CryostatRecordingTest(bundle, namespace, openShiftCertManager)) case tests.CryostatConfigChangeTestName: diff --git a/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml b/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml index 7eaedd854..ca90abb1f 100644 --- a/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml +++ b/internal/images/custom-scorecard-tests/rbac/scorecard_role.yaml @@ -150,3 +150,12 @@ rules: - namespaces verbs: - create + - delete +- apiGroups: + - operator.cryostat.io + resources: + - cryostats + verbs: + - create + - delete + - get diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 2c831e72f..05965499f 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -26,7 +26,7 @@ import ( "strings" "time" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -101,10 +101,10 @@ func newOperatorCRDClient(config *rest.Config) (*OperatorCRDClient, error) { func newCRDClient(config *rest.Config) (*rest.RESTClient, error) { scheme := runtime.NewScheme() - if err := operatorv1beta1.AddToScheme(scheme); err != nil { + if err := operatorv1beta2.AddToScheme(scheme); err != nil { return nil, err } - return newRESTClientForGV(config, scheme, &operatorv1beta1.GroupVersion) + return newRESTClientForGV(config, scheme, &operatorv1beta2.GroupVersion) } func newRESTClientForGV(config *rest.Config, scheme *runtime.Scheme, gv *schema.GroupVersion) (*rest.RESTClient, error) { @@ -125,18 +125,18 @@ type CryostatClient struct { } // Get returns a Cryostat CR for the given name -func (c *CryostatClient) Get(ctx context.Context, name string) (*operatorv1beta1.Cryostat, error) { - return get(ctx, c.restClient, c.resource, c.namespace, name, &operatorv1beta1.Cryostat{}) +func (c *CryostatClient) Get(ctx context.Context, name string) (*operatorv1beta2.Cryostat, error) { + return get(ctx, c.restClient, c.resource, c.namespace, name, &operatorv1beta2.Cryostat{}) } // Create creates the provided Cryostat CR -func (c *CryostatClient) Create(ctx context.Context, obj *operatorv1beta1.Cryostat) (*operatorv1beta1.Cryostat, error) { - return create(ctx, c.restClient, c.resource, c.namespace, obj, &operatorv1beta1.Cryostat{}) +func (c *CryostatClient) Create(ctx context.Context, obj *operatorv1beta2.Cryostat) (*operatorv1beta2.Cryostat, error) { + return create(ctx, c.restClient, c.resource, c.namespace, obj, &operatorv1beta2.Cryostat{}) } // Update updates the provided Cryostat CR -func (c *CryostatClient) Update(ctx context.Context, obj *operatorv1beta1.Cryostat) (*operatorv1beta1.Cryostat, error) { - return update(ctx, c.restClient, c.resource, c.namespace, obj, &operatorv1beta1.Cryostat{}, obj.Name) +func (c *CryostatClient) Update(ctx context.Context, obj *operatorv1beta2.Cryostat) (*operatorv1beta2.Cryostat, error) { + return update(ctx, c.restClient, c.resource, c.namespace, obj, &operatorv1beta2.Cryostat{}, obj.Name) } // Delete deletes the Cryostat CR with the given name diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index 99c639ee0..c85c2c2f9 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -24,7 +24,7 @@ import ( "net/url" "time" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" appsv1 "k8s.io/api/apps/v1" @@ -44,13 +44,16 @@ const ( ) type TestResources struct { - OpenShift bool - Client *CryostatClientset - LogChannel chan *ContainerLog + Name string + Namespace string + TargetNamespaces []string + OpenShift bool + Client *CryostatClientset + LogChannel chan *ContainerLog *scapiv1alpha3.TestResult } -func (r *TestResources) waitForDeploymentAvailability(ctx context.Context, namespace string, name string) error { +func (r *TestResources) waitForDeploymentAvailability(ctx context.Context, name string, namespace string) error { err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { deploy, err := r.Client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { @@ -77,7 +80,7 @@ func (r *TestResources) waitForDeploymentAvailability(ctx context.Context, names return false, nil }) if err != nil { - logErr := r.logWorkloadEvents(namespace, name) + logErr := r.logWorkloadEvents(r.Name) if logErr != nil { r.Log += fmt.Sprintf("failed to look up deployment errors: %s\n", logErr.Error()) } @@ -96,9 +99,9 @@ func (r *TestResources) fail(message string) *scapiv1alpha3.TestResult { return r.TestResult } -func (r *TestResources) logWorkloadEvents(namespace string, name string) error { +func (r *TestResources) logWorkloadEvents(name string) error { ctx := context.Background() - deploy, err := r.Client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) + deploy, err := r.Client.AppsV1().Deployments(r.Namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { if kerrors.IsNotFound(err) { return nil @@ -113,7 +116,7 @@ func (r *TestResources) logWorkloadEvents(namespace string, name string) error { } r.Log += fmt.Sprintf("deployment %s warning events:\n", deploy.Name) - err = r.logEvents(namespace, scheme.Scheme, deploy) + err = r.logEvents(scheme.Scheme, deploy) if err != nil { return err } @@ -123,7 +126,7 @@ func (r *TestResources) logWorkloadEvents(namespace string, name string) error { if err != nil { return err } - replicaSets, err := r.Client.AppsV1().ReplicaSets(namespace).List(ctx, metav1.ListOptions{ + replicaSets, err := r.Client.AppsV1().ReplicaSets(r.Namespace).List(ctx, metav1.ListOptions{ LabelSelector: selector.String(), }) if err != nil { @@ -136,14 +139,14 @@ func (r *TestResources) logWorkloadEvents(namespace string, name string) error { condition.Reason, condition.Message) } r.Log += fmt.Sprintf("replica set %s warning events:\n", rs.Name) - err = r.logEvents(namespace, scheme.Scheme, &rs) + err = r.logEvents(scheme.Scheme, &rs) if err != nil { return err } } // Look up pods for deployment and log conditions and events - pods, err := r.Client.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + pods, err := r.Client.CoreV1().Pods(r.Namespace).List(ctx, metav1.ListOptions{ LabelSelector: selector.String(), }) if err != nil { @@ -157,7 +160,7 @@ func (r *TestResources) logWorkloadEvents(namespace string, name string) error { condition.Reason, condition.Message) } r.Log += fmt.Sprintf("pod %s warning events:\n", pod.Name) - err = r.logEvents(namespace, scheme.Scheme, &pod) + err = r.logEvents(scheme.Scheme, &pod) if err != nil { return err } @@ -165,8 +168,8 @@ func (r *TestResources) logWorkloadEvents(namespace string, name string) error { return nil } -func (r *TestResources) logEvents(namespace string, scheme *runtime.Scheme, obj runtime.Object) error { - events, err := r.Client.CoreV1().Events(namespace).Search(scheme, obj) +func (r *TestResources) logEvents(scheme *runtime.Scheme, obj runtime.Object) error { + events, err := r.Client.CoreV1().Events(r.Namespace).Search(scheme, obj) if err != nil { return err } @@ -178,11 +181,11 @@ func (r *TestResources) logEvents(namespace string, scheme *runtime.Scheme, obj return nil } -func (r *TestResources) LogWorkloadEventsOnError(namespace string, name string) { +func (r *TestResources) LogWorkloadEventsOnError() { if len(r.Errors) > 0 { r.Log += "\nWORKLOAD EVENTS:\n" - for _, deployName := range []string{name, name + "-reports"} { - logErr := r.logWorkloadEvents(namespace, deployName) + for _, deployName := range []string{r.Name, r.Name + "-reports"} { + logErr := r.logWorkloadEvents(deployName) if logErr != nil { r.Log += fmt.Sprintf("failed to get workload logs: %s", logErr) } @@ -199,8 +202,10 @@ func newEmptyTestResult(testName string) *scapiv1alpha3.TestResult { } } -func newTestResources(testName string) *TestResources { +func newTestResources(testName string, namespace string) *TestResources { return &TestResources{ + Name: testName, + Namespace: namespace, TestResult: newEmptyTestResult(testName), } } @@ -231,42 +236,82 @@ func (r *TestResources) setupCRTestResources(openShiftCertManager bool) error { return nil } -func newCryostatCR(name string, namespace string, withIngress bool) *operatorv1beta1.Cryostat { - cr := &operatorv1beta1.Cryostat{ +func (r *TestResources) setupTargetNamespace() error { + ctx := context.Background() + + for _, namespaceName := range r.TargetNamespaces { + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespaceName, + }, + } + ns, err := r.Client.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("failed to create namespace %s: %s", namespaceName, err.Error()) + } + r.Log += fmt.Sprintf("created namespace: %s\n", ns.Name) + } + return nil +} + +func (r *TestResources) newCryostatCR() *operatorv1beta2.Cryostat { + cr := &operatorv1beta2.Cryostat{ ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, + Name: r.Name, + Namespace: r.Namespace, }, - Spec: operatorv1beta1.CryostatSpec{ - Minimal: false, + Spec: operatorv1beta2.CryostatSpec{ EnableCertManager: &[]bool{true}[0], }, } + if !r.OpenShift { + configureIngress(cr.Name, &cr.Spec) + } - if withIngress { - pathType := netv1.PathTypePrefix - cr.Spec.NetworkOptions = &operatorv1beta1.NetworkConfigurationList{ - CoreConfig: &operatorv1beta1.NetworkConfiguration{ - Annotations: map[string]string{ - "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", - }, - IngressSpec: &netv1.IngressSpec{ - TLS: []netv1.IngressTLS{{}}, - Rules: []netv1.IngressRule{ - { - Host: "testing.cryostat", - IngressRuleValue: netv1.IngressRuleValue{ - HTTP: &netv1.HTTPIngressRuleValue{ - Paths: []netv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathType, - Backend: netv1.IngressBackend{ - Service: &netv1.IngressServiceBackend{ - Name: name, - Port: netv1.ServiceBackendPort{ - Number: 8181, - }, + return cr +} + +func (r *TestResources) newMultiNamespaceCryostatCR() *operatorv1beta2.Cryostat { + cr := &operatorv1beta2.Cryostat{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name, + Namespace: r.Namespace, + }, + Spec: operatorv1beta2.CryostatSpec{ + TargetNamespaces: r.TargetNamespaces, + EnableCertManager: &[]bool{true}[0], + }, + } + if !r.OpenShift { + configureIngress(cr.Name, &cr.Spec) + } + + return cr +} + +func configureIngress(name string, cryostatSpec *operatorv1beta2.CryostatSpec) { + pathType := netv1.PathTypePrefix + cryostatSpec.NetworkOptions = &operatorv1beta2.NetworkConfigurationList{ + CoreConfig: &operatorv1beta2.NetworkConfiguration{ + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", + }, + IngressSpec: &netv1.IngressSpec{ + TLS: []netv1.IngressTLS{{}}, + Rules: []netv1.IngressRule{ + { + Host: "testing.cryostat", + IngressRuleValue: netv1.IngressRuleValue{ + HTTP: &netv1.HTTPIngressRuleValue{ + Paths: []netv1.HTTPIngressPath{ + { + Path: "/", + PathType: &pathType, + Backend: netv1.IngressBackend{ + Service: &netv1.IngressServiceBackend{ + Name: name, + Port: netv1.ServiceBackendPort{ + Number: 8181, }, }, }, @@ -277,27 +322,27 @@ func newCryostatCR(name string, namespace string, withIngress bool) *operatorv1b }, }, }, - GrafanaConfig: &operatorv1beta1.NetworkConfiguration{ - Annotations: map[string]string{ - "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", - }, - IngressSpec: &netv1.IngressSpec{ - TLS: []netv1.IngressTLS{{}}, - Rules: []netv1.IngressRule{ - { - Host: "testing.cryostat-grafana", - IngressRuleValue: netv1.IngressRuleValue{ - HTTP: &netv1.HTTPIngressRuleValue{ - Paths: []netv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathType, - Backend: netv1.IngressBackend{ - Service: &netv1.IngressServiceBackend{ - Name: fmt.Sprintf("%s-grafana", name), - Port: netv1.ServiceBackendPort{ - Number: 3000, - }, + }, + GrafanaConfig: &operatorv1beta2.NetworkConfiguration{ + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", + }, + IngressSpec: &netv1.IngressSpec{ + TLS: []netv1.IngressTLS{{}}, + Rules: []netv1.IngressRule{ + { + Host: "testing.cryostat-grafana", + IngressRuleValue: netv1.IngressRuleValue{ + HTTP: &netv1.HTTPIngressRuleValue{ + Paths: []netv1.HTTPIngressPath{ + { + Path: "/", + PathType: &pathType, + Backend: netv1.IngressBackend{ + Service: &netv1.IngressServiceBackend{ + Name: fmt.Sprintf("%s-grafana", name), + Port: netv1.ServiceBackendPort{ + Number: 3000, }, }, }, @@ -308,12 +353,11 @@ func newCryostatCR(name string, namespace string, withIngress bool) *operatorv1b }, }, }, - } + }, } - return cr } -func (r *TestResources) createAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat) (*operatorv1beta1.Cryostat, error) { +func (r *TestResources) createAndWaitTillCryostatAvailable(cr *operatorv1beta2.Cryostat) (*operatorv1beta2.Cryostat, error) { cr, err := r.Client.OperatorCRDs().Cryostats(cr.Namespace).Create(context.Background(), cr) if err != nil { r.logError(fmt.Sprintf("failed to create Cryostat CR: %s", err.Error())) @@ -323,7 +367,7 @@ func (r *TestResources) createAndWaitTillCryostatAvailable(cr *operatorv1beta1.C // Poll the deployment until it becomes available or we timeout ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err = r.waitForDeploymentAvailability(ctx, cr.Namespace, cr.Name) + err = r.waitForDeploymentAvailability(ctx, r.Name, r.Namespace) if err != nil { r.logError(fmt.Sprintf("Cryostat main deployment did not become available: %s", err.Error())) return nil, err @@ -334,23 +378,35 @@ func (r *TestResources) createAndWaitTillCryostatAvailable(cr *operatorv1beta1.C if err != nil { return false, fmt.Errorf("failed to get Cryostat CR: %s", err.Error()) } - if len(cr.Status.ApplicationURL) > 0 { - return true, nil + if len(cr.Spec.TargetNamespaces) > 0 { + if len(cr.Status.TargetNamespaces) == 0 { + r.Log += "application's target namespaces are not available" + return false, nil // Retry + } + for i := range cr.Status.TargetNamespaces { + if cr.Status.TargetNamespaces[i] != cr.Spec.TargetNamespaces[i] { + return false, fmt.Errorf("application's target namespaces do not correctly match CR's") + } + } } - r.Log += "application URL is not yet available\n" - return false, nil + if len(cr.Status.ApplicationURL) == 0 { + r.Log += "application URL is not yet available\n" + return false, nil + } + return true, nil }) if err != nil { r.logError(fmt.Sprintf("application URL not found in CR: %s", err.Error())) return nil, err } + r.Log += fmt.Sprintf("application has access to the following namespaces: %s\n", cr.Status.TargetNamespaces) r.Log += fmt.Sprintf("application is available at %s\n", cr.Status.ApplicationURL) return cr, nil } func (r *TestResources) waitTillCryostatReady(base *url.URL) error { - return r.sendHealthRequest(base, func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error) { + return r.sendHealthRequest(base, func(resp *http.Response, result *scapiv1alpha3.TestResult) (done bool, err error) { health := &HealthResponse{} err = ReadJSON(resp, health) if err != nil { @@ -367,28 +423,28 @@ func (r *TestResources) waitTillCryostatReady(base *url.URL) error { }) } -func (r *TestResources) waitTillReportReady(name string, namespace string, port int32) error { +func (r *TestResources) waitTillReportReady(port int32) error { ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err := r.waitForDeploymentAvailability(ctx, namespace, name) + err := r.waitForDeploymentAvailability(ctx, r.Name+"-reports", r.Namespace) if err != nil { return fmt.Errorf("report sidecar deployment did not become available: %s", err.Error()) } - reportsUrl := fmt.Sprintf("https://%s.%s.svc.cluster.local:%d", name, namespace, port) + reportsUrl := fmt.Sprintf("https://%s.%s.svc.cluster.local:%d", r.Name+"-reports", r.Namespace, port) base, err := url.Parse(reportsUrl) if err != nil { return fmt.Errorf("application URL is invalid: %s", err.Error()) } - return r.sendHealthRequest(base, func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error) { + return r.sendHealthRequest(base, func(resp *http.Response, result *scapiv1alpha3.TestResult) (done bool, err error) { r.Log += fmt.Sprintf("reports sidecar is ready at %s\n", base.String()) return true, nil }) } -func (r *TestResources) sendHealthRequest(base *url.URL, healthCheck func(resp *http.Response, r *scapiv1alpha3.TestResult) (done bool, err error)) error { +func (r *TestResources) sendHealthRequest(base *url.URL, healthCheck func(resp *http.Response, result *scapiv1alpha3.TestResult) (done bool, err error)) error { client := NewHttpClient() ctx, cancel := context.WithTimeout(context.Background(), testTimeout) @@ -423,7 +479,7 @@ func (r *TestResources) sendHealthRequest(base *url.URL, healthCheck func(resp * return err } -func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta1.Cryostat) error { +func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta2.Cryostat) error { cr, err := r.Client.OperatorCRDs().Cryostats(cr.Namespace).Update(context.Background(), cr) if err != nil { r.Log += fmt.Sprintf("failed to update Cryostat CR: %s", err.Error()) @@ -486,29 +542,32 @@ func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta1.C return err } -func (r *TestResources) cleanupAndLogs(name string, namespace string) { - r.LogWorkloadEventsOnError(namespace, name) +func (r *TestResources) cleanupAndLogs() { + r.LogWorkloadEventsOnError() - cr := &operatorv1beta1.Cryostat{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - } ctx := context.Background() - err := r.Client.OperatorCRDs().Cryostats(cr.Namespace).Delete(ctx, cr.Name, &metav1.DeleteOptions{}) + err := r.Client.OperatorCRDs().Cryostats(r.Namespace).Delete(ctx, r.Name, &metav1.DeleteOptions{}) if err != nil { if !kerrors.IsNotFound(err) { r.Log += fmt.Sprintf("failed to delete Cryostat: %s\n", err.Error()) } } + for _, namespaceName := range r.TargetNamespaces { + err := r.Client.CoreV1().Namespaces().Delete(ctx, namespaceName, metav1.DeleteOptions{}) + if err != nil { + if !kerrors.IsNotFound(err) { + r.Log += fmt.Sprintf("failed to delete namespace %s: %s", namespaceName, err.Error()) + } + } + } + if r.LogChannel != nil { r.CollectContainersLogsToResult() } } -func (r *TestResources) getCryostatPodNameForCR(cr *operatorv1beta1.Cryostat) (string, error) { +func (r *TestResources) getCryostatPodNameForCR(cr *operatorv1beta2.Cryostat) (string, error) { selector := metav1.LabelSelector{ MatchLabels: map[string]string{ "app": cr.Name, diff --git a/internal/test/scorecard/logger.go b/internal/test/scorecard/logger.go index dd38d79b7..385338055 100644 --- a/internal/test/scorecard/logger.go +++ b/internal/test/scorecard/logger.go @@ -20,7 +20,7 @@ import ( "io" "strings" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" v1 "k8s.io/api/core/v1" ) @@ -82,7 +82,7 @@ func (r *TestResources) CollectContainersLogsToResult() { } } -func (r *TestResources) StartLogs(cr *operatorv1beta1.Cryostat) error { +func (r *TestResources) StartLogs(cr *operatorv1beta2.Cryostat) error { podName, err := r.getCryostatPodNameForCR(cr) if err != nil { return fmt.Errorf("failed to get pod name for CR: %s", err.Error()) diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 9d3d251a6..518ac08fe 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -20,7 +20,7 @@ import ( "net/url" "time" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" corev1 "k8s.io/api/core/v1" @@ -29,66 +29,92 @@ import ( ) const ( - OperatorInstallTestName string = "operator-install" - CryostatCRTestName string = "cryostat-cr" - CryostatRecordingTestName string = "cryostat-recording" - CryostatConfigChangeTestName string = "cryostat-config-change" - CryostatReportTestName string = "cryostat-report" + OperatorInstallTestName string = "operator-install" + CryostatCRTestName string = "cryostat-cr" + CryostatMultiNamespaceTestName string = "cryostat-multi-namespace" + CryostatRecordingTestName string = "cryostat-recording" + CryostatConfigChangeTestName string = "cryostat-config-change" + CryostatReportTestName string = "cryostat-report" ) // OperatorInstallTest checks that the operator installed correctly func OperatorInstallTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { - r := newTestResources(OperatorInstallTestName) + r := newTestResources(OperatorInstallTestName, namespace) // Create a new Kubernetes REST client for this test err := r.setupCRTestResources(openShiftCertManager) if err != nil { return r.fail(fmt.Sprintf("failed to set up %s test: %s", OperatorInstallTestName, err.Error())) } - defer r.cleanupAndLogs(OperatorInstallTestName, namespace) + defer r.cleanupAndLogs() // Poll the deployment until it becomes available or we timeout ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err = r.waitForDeploymentAvailability(ctx, namespace, operatorDeploymentName) + err = r.waitForDeploymentAvailability(ctx, operatorDeploymentName, namespace) if err != nil { return r.fail(fmt.Sprintf("operator deployment did not become available: %s", err.Error())) } - return r.TestResult } // CryostatCRTest checks that the operator installs Cryostat in response to a Cryostat CR func CryostatCRTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { - r := newTestResources(CryostatCRTestName) + r := newTestResources(CryostatCRTestName, namespace) err := r.setupCRTestResources(openShiftCertManager) if err != nil { return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatCRTestName, err.Error())) } - defer r.cleanupAndLogs(CryostatCRTestName, namespace) + defer r.cleanupAndLogs() // Create a default Cryostat CR - _, err = r.createAndWaitTillCryostatAvailable(newCryostatCR(CryostatCRTestName, namespace, !r.OpenShift)) + _, err = r.createAndWaitTillCryostatAvailable(r.newCryostatCR()) if err != nil { return r.fail(fmt.Sprintf("%s test failed: %s", CryostatCRTestName, err.Error())) } return r.TestResult } +// CryostatMultiNamespaceTest checks that the operator installs multi-namespace Cryostat in response to a multi-namespace Cryostat CR +func CryostatMultiNamespaceTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { + r := newTestResources(CryostatMultiNamespaceTestName, namespace) + r.TargetNamespaces = []string{namespace + "-other"} + + err := r.setupCRTestResources(openShiftCertManager) + if err != nil { + return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatMultiNamespaceTestName, err.Error())) + } + defer r.cleanupAndLogs() + + err = r.setupTargetNamespace() + if err != nil { + return r.fail(fmt.Sprintf("failed to create target namespaces for %s test: %s", CryostatMultiNamespaceTestName, err.Error())) + } + + // Create a default ClusterCryostat CR + _, err = r.createAndWaitTillCryostatAvailable(r.newMultiNamespaceCryostatCR()) + if err != nil { + return r.fail(fmt.Sprintf("%s test failed: %s", CryostatMultiNamespaceTestName, err.Error())) + } + + return r.TestResult +} + +// CryostatConfigChangeTest checks that the operator redeploys Cryostat in response to a change to Cryostat CR func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { - r := newTestResources(CryostatConfigChangeTestName) + r := newTestResources(CryostatConfigChangeTestName, namespace) err := r.setupCRTestResources(openShiftCertManager) if err != nil { return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatConfigChangeTestName, err.Error())) } - defer r.cleanupAndLogs(CryostatConfigChangeTestName, namespace) + defer r.cleanupAndLogs() // Create a default Cryostat CR with default empty dir - cr := newCryostatCR(CryostatConfigChangeTestName, namespace, !r.OpenShift) - cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ - EmptyDir: &operatorv1beta1.EmptyDirConfig{ + cr := r.newCryostatCR() + cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ + EmptyDir: &operatorv1beta2.EmptyDirConfig{ Enabled: true, }, } @@ -106,8 +132,8 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope if err != nil { return r.fail(fmt.Sprintf("failed to get Cryostat CR: %s", err.Error())) } - cr.Spec.StorageOptions = &operatorv1beta1.StorageConfiguration{ - PVC: &operatorv1beta1.PersistentVolumeClaimConfig{ + cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ + PVC: &operatorv1beta2.PersistentVolumeClaimConfig{ Spec: &corev1.PersistentVolumeClaimSpec{ StorageClassName: nil, Resources: corev1.ResourceRequirements{ @@ -141,16 +167,16 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope // TODO add a built in discovery test too func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { - r := newTestResources(CryostatRecordingTestName) + r := newTestResources(CryostatRecordingTestName, namespace) err := r.setupCRTestResources(openShiftCertManager) if err != nil { return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatRecordingTestName, err.Error())) } - defer r.cleanupAndLogs(CryostatRecordingTestName, namespace) + defer r.cleanupAndLogs() // Create a default Cryostat CR - cr, err := r.createAndWaitTillCryostatAvailable(newCryostatCR(CryostatRecordingTestName, namespace, !r.OpenShift)) + cr, err := r.createAndWaitTillCryostatAvailable(r.newCryostatCR()) if err != nil { return r.fail(fmt.Sprintf("failed to determine application URL: %s", err.Error())) } @@ -280,34 +306,35 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh return r.TestResult } +// CryostatReportTest checks that the operator deploys a report sidecar in response to a Cryostat CR func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { - r := newTestResources(CryostatReportTestName) + r := newTestResources(CryostatReportTestName, namespace) err := r.setupCRTestResources(openShiftCertManager) if err != nil { return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatReportTestName, err.Error())) } - defer r.cleanupAndLogs(CryostatReportTestName, namespace) + defer r.cleanupAndLogs() port := int32(10000) - cr := newCryostatCR(CryostatReportTestName, namespace, !r.OpenShift) - cr.Spec.ReportOptions = &operatorv1beta1.ReportConfiguration{ + cr := r.newCryostatCR() + cr.Spec.ReportOptions = &operatorv1beta2.ReportConfiguration{ Replicas: 1, } - cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ - ReportsConfig: &operatorv1beta1.ReportsServiceConfig{ + cr.Spec.ServiceOptions = &operatorv1beta2.ServiceConfigList{ + ReportsConfig: &operatorv1beta2.ReportsServiceConfig{ HTTPPort: &port, }, } // Create a default Cryostat CR - cr, err = r.createAndWaitTillCryostatAvailable(cr) + _, err = r.createAndWaitTillCryostatAvailable(cr) if err != nil { return r.fail(fmt.Sprintf("%s test failed: %s", CryostatReportTestName, err.Error())) } // Query health of report sidecar - err = r.waitTillReportReady(cr.Name+"-reports", cr.Namespace, port) + err = r.waitTillReportReady(port) if err != nil { return r.fail(fmt.Sprintf("failed to reach the application: %s", err.Error())) } From f7990987afe40e9d36d1639a25c68be2bca0930e Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 15:38:01 -0400 Subject: [PATCH 23/53] test(scorecard): add container logs for report sidecard test (backport #772) (#796) * test(scorecard): add container logs for report sidecard test (#772) * test(scorecard): add container logs for report sidecard test odified: internal/test/scorecard/common_utils.go * test(scorecard): clean up (cherry picked from commit 4b8ad764340a9bd034e92c83f836fad6f4d05d85) # Conflicts: # bundle/manifests/cryostat-operator.clusterserviceversion.yaml # bundle/tests/scorecard/config.yaml # config/scorecard/patches/custom.config.yaml # internal/test/scorecard/logger.go * Fix conflicts --------- Co-authored-by: Thuan Vo Co-authored-by: Elliott Baron --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 12 +++--- config/scorecard/patches/custom.config.yaml | 12 +++--- internal/test/scorecard/common_utils.go | 42 +++++++++++++++---- internal/test/scorecard/logger.go | 41 ++++++++++++++---- internal/test/scorecard/tests.go | 5 +++ 6 files changed, 84 insertions(+), 30 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index c8e3d1a59..536a361a2 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-04-04T17:19:02Z" + createdAt: "2024-04-16T19:14:19Z" 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 acc4e5d26..11a3c1c17 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:3.0.0-20240404165315 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404165315 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245 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:3.0.0-20240404165315 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245 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:3.0.0-20240404165315 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245 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:3.0.0-20240404165315 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245 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:3.0.0-20240404165315 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245 labels: suite: cryostat test: cryostat-report diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index f095f1d50..8e7c7c550 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:3.0.0-20240404171904" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" labels: suite: cryostat test: cryostat-multi-namespace @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" labels: suite: cryostat test: cryostat-recording @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" labels: suite: cryostat test: cryostat-config-change @@ -58,7 +58,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240404171904" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" labels: suite: cryostat test: cryostat-report diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index c85c2c2f9..e14e3ac7b 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -571,24 +571,50 @@ func (r *TestResources) getCryostatPodNameForCR(cr *operatorv1beta2.Cryostat) (s selector := metav1.LabelSelector{ MatchLabels: map[string]string{ "app": cr.Name, + "kind": "cryostat", "component": "cryostat", }, } - opts := metav1.ListOptions{ - LabelSelector: labels.Set(selector.MatchLabels).String(), + + names, err := r.getPodnamesForSelector(cr.Namespace, selector) + if err != nil { + return "", err } - ctx, cancel := context.WithTimeout(context.TODO(), testTimeout) - defer cancel() + if len(names) == 0 { + return "", fmt.Errorf("no matching cryostat pods for cr: %s", cr.Name) + } + return names[0].ObjectMeta.Name, nil +} - pods, err := r.Client.CoreV1().Pods(cr.Namespace).List(ctx, opts) +func (r *TestResources) getReportPodNameForCR(cr *operatorv1beta2.Cryostat) (string, error) { + selector := metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": cr.Name, + "kind": "cryostat", + "component": "reports", + }, + } + + names, err := r.getPodnamesForSelector(cr.Namespace, selector) if err != nil { return "", err } - if len(pods.Items) == 0 { - return "", fmt.Errorf("no matching cryostat pods for cr: %s", cr.Name) + if len(names) == 0 { + return "", fmt.Errorf("no matching report sidecar pods for cr: %s", cr.Name) } + return names[0].ObjectMeta.Name, nil +} - return pods.Items[0].ObjectMeta.Name, nil +func (r *TestResources) getPodnamesForSelector(namespace string, selector metav1.LabelSelector) ([]corev1.Pod, error) { + labelSelector := labels.Set(selector.MatchLabels).String() + + ctx, cancel := context.WithTimeout(context.TODO(), testTimeout) + defer cancel() + + pods, err := r.Client.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: labelSelector, + }) + return pods.Items, err } diff --git a/internal/test/scorecard/logger.go b/internal/test/scorecard/logger.go index 385338055..deacd1bdb 100644 --- a/internal/test/scorecard/logger.go +++ b/internal/test/scorecard/logger.go @@ -25,12 +25,16 @@ import ( ) type ContainerLog struct { + Namespace string + Pod string Container string Log string } func (r *TestResources) logContainer(namespace, podName, containerName string) { containerLog := &ContainerLog{ + Namespace: namespace, + Pod: podName, Container: containerName, } buf := &strings.Builder{} @@ -77,27 +81,46 @@ func (r *TestResources) CollectContainersLogsToResult() { logs := r.CollectLogs() for _, log := range logs { if log != nil { - r.Log += fmt.Sprintf("\n%s CONTAINER LOG:\n\n\t%s\n", strings.ToUpper(log.Container), log.Log) + r.Log += fmt.Sprintf("\nNAMESPACE: %s\nPOD: %s\nCONTAINER: %s\nLOG:\n\t%s\n", + strings.ToUpper(log.Namespace), + strings.ToUpper(log.Pod), + strings.ToUpper(log.Container), + log.Log, + ) } } } func (r *TestResources) StartLogs(cr *operatorv1beta2.Cryostat) error { - podName, err := r.getCryostatPodNameForCR(cr) + cryostatPodName, err := r.getCryostatPodNameForCR(cr) if err != nil { return fmt.Errorf("failed to get pod name for CR: %s", err.Error()) } - containerNames := []string{ - cr.Name, - cr.Name + "-grafana", - cr.Name + "-jfr-datasource", + logSelections := map[string][]string{ + cryostatPodName: { + cr.Name, + cr.Name + "-grafana", + cr.Name + "-jfr-datasource", + }, } + bufferSize := 3 - r.LogChannel = make(chan *ContainerLog, len(containerNames)) + if cr.Spec.ReportOptions != nil && cr.Spec.ReportOptions.Replicas > 0 { + reportPodName, err := r.getReportPodNameForCR(cr) + if err != nil { + return fmt.Errorf("failed to get pod name for report sidecar: %s", err.Error()) + } + logSelections[reportPodName] = []string{cr.Name + "-reports"} + bufferSize++ + } - for _, containerName := range containerNames { - go r.logContainer(cr.Namespace, podName, containerName) + r.LogChannel = make(chan *ContainerLog, bufferSize) + + for pod, containers := range logSelections { + for _, container := range containers { + go r.logContainer(cr.Namespace, pod, container) + } } return nil diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 518ac08fe..77692dcb9 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -339,5 +339,10 @@ func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShift return r.fail(fmt.Sprintf("failed to reach the application: %s", err.Error())) } + err = r.StartLogs(cr) + if err != nil { + r.Log += fmt.Sprintf("failed to retrieve logs for the application: %s", err.Error()) + } + return r.TestResult } From 8ed858b4362a3c7cb3eb7399ffc701444664acb5 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 17:21:10 -0400 Subject: [PATCH 24/53] test(scorecard): retry on cryostat update conflict (backport #774) (#797) * test(scorecard): retry on cryostat update conflict (#774) * retry on cryostat update conflict * review * review (cherry picked from commit d7b0379122b9129a76b0c25ffa29923fe4ca433a) # Conflicts: # bundle/manifests/cryostat-operator.clusterserviceversion.yaml # bundle/tests/scorecard/config.yaml # config/scorecard/patches/custom.config.yaml # internal/test/scorecard/common_utils.go # internal/test/scorecard/tests.go * Fix conflicts --------- Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Co-authored-by: Elliott Baron --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 12 +++--- config/scorecard/patches/custom.config.yaml | 12 +++--- internal/test/scorecard/common_utils.go | 37 ++++++++++++++++--- internal/test/scorecard/tests.go | 26 +------------ 5 files changed, 46 insertions(+), 43 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 536a361a2..1761b6e18 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-04-16T19:14:19Z" + createdAt: "2024-04-16T21:08:10Z" 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 11a3c1c17..30459721b 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:3.0.0-20240416191245 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645 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:3.0.0-20240416191245 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645 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:3.0.0-20240416191245 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645 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:3.0.0-20240416191245 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645 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:3.0.0-20240416191245 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645 labels: suite: cryostat test: cryostat-report diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 8e7c7c550..39c8ea87f 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:3.0.0-20240416191245" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" labels: suite: cryostat test: cryostat-multi-namespace @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" labels: suite: cryostat test: cryostat-recording @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" labels: suite: cryostat test: cryostat-config-change @@ -58,7 +58,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416191245" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" labels: suite: cryostat test: cryostat-report diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index e14e3ac7b..91bb99163 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -31,11 +31,13 @@ import ( corev1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/util/retry" ) const ( @@ -479,11 +481,34 @@ func (r *TestResources) sendHealthRequest(base *url.URL, healthCheck func(resp * return err } -func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta2.Cryostat) error { - cr, err := r.Client.OperatorCRDs().Cryostats(cr.Namespace).Update(context.Background(), cr) - if err != nil { - r.Log += fmt.Sprintf("failed to update Cryostat CR: %s", err.Error()) +func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta2.Cryostat) (*operatorv1beta2.Cryostat, error) { + ctx := context.Background() + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + var err error + cr, err = r.Client.OperatorCRDs().Cryostats(cr.Namespace).Get(ctx, cr.Name) + if err != nil { + return fmt.Errorf("failed to get Cryostat CR: %s", err.Error()) + } + + cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ + PVC: &operatorv1beta2.PersistentVolumeClaimConfig{ + Spec: &corev1.PersistentVolumeClaimSpec{ + StorageClassName: nil, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceStorage: resource.MustParse("1Gi"), + }, + }, + }, + }, + } + + cr, err = r.Client.OperatorCRDs().Cryostats(cr.Namespace).Update(context.Background(), cr) return err + }) + if err != nil { + return nil, fmt.Errorf("failed to update Cryostat CR: %s", err.Error()) } // Poll the deployment until it becomes available or we timeout @@ -537,9 +562,9 @@ func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta2.C return false, nil }) if err != nil { - return fmt.Errorf("failed to look up deployment errors: %s", err.Error()) + return nil, fmt.Errorf("failed to look up deployment errors: %s", err.Error()) } - return err + return cr, err } func (r *TestResources) cleanupAndLogs() { diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 77692dcb9..3ad6257cb 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -23,8 +23,6 @@ import ( operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -125,34 +123,14 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope } // Switch Cryostat CR to PVC for redeployment - ctx, cancel := context.WithTimeout(context.Background(), testTimeout) - defer cancel() - - cr, err = r.Client.OperatorCRDs().Cryostats(namespace).Get(ctx, CryostatConfigChangeTestName) - if err != nil { - return r.fail(fmt.Sprintf("failed to get Cryostat CR: %s", err.Error())) - } - cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ - PVC: &operatorv1beta2.PersistentVolumeClaimConfig{ - Spec: &corev1.PersistentVolumeClaimSpec{ - StorageClassName: nil, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceStorage: resource.MustParse("1Gi"), - }, - }, - }, - }, - } - - // Wait for redeployment of Cryostat CR - err = r.updateAndWaitTillCryostatAvailable(cr) + cr, err = r.updateAndWaitTillCryostatAvailable(cr) if err != nil { return r.fail(fmt.Sprintf("Cryostat redeployment did not become available: %s", err.Error())) } r.Log += "Cryostat deployment has successfully updated with new spec template\n" base, err := url.Parse(cr.Status.ApplicationURL) + r.Log += fmt.Sprintf("base url: %s\n", base) if err != nil { return r.fail(fmt.Sprintf("application URL is invalid: %s", err.Error())) } From 53d2b73f5d141e38682f965ab1cfafe63855edda Mon Sep 17 00:00:00 2001 From: Joshua Matsuoka Date: Tue, 23 Apr 2024 13:03:08 -0400 Subject: [PATCH 25/53] feat(deploy): deploy cryostat 3.0 (#727) * feat(discovery): options to configure discovery port names and numbers (backport #715) (#725) * feat(discovery): options to configure discovery port names and numbers (#715) Signed-off-by: Thuan Vo (cherry picked from commit a55202198f41debba71c521817c56162ebc1fce5) * resolve conflict --------- Co-authored-by: Thuan Vo Co-authored-by: Andrew Azores * Deploy cryostat 3.0 * Remove extraneous file * test adjustments * feat(discovery): options to configure discovery port names and numbers (#715) Signed-off-by: Thuan Vo * Fix typo in environment variable breaking reconciler test, fix missing SecurityContext * Fix conflict with cluster cryostat removal * ci(gh): add comment when /build_test is finished (#745) * add scorecard test/suite selection (#746) * test(scorecard): scorecard tests for recording management (#698) * test(scorecard): scorecard tests for recording management Signed-off-by: Thuan Vo * fixup(scorecard): fix cr cleanup func * test(scorecard): registry recording test to suite * chore(scorecard): reorganize client def * chore(scorecard): clean up common setup func * chore(bundle): regenerate bundle with scorecard tag * chore(bundle): correct image tag in bundle * fix(bundle): add missing scorecard test config patch * feat(scorecard): scaffold cryostat API client * chore(scorecard): clean up API client * test(scorecard): implement recording scorecard test * fixup(scorecard): correctly add scorecard test via hack templates * fix(client): ignore unverified tls certs and base64 oauth token * chore(bundle): split cryostat tests to separate stage * fix(scorecard): extend default transport instead of overwriting * chore(scorecard): refactor client to support multi-part * fixup(client): fix request verb * fix(client): fix recording create form format * fix(scorecard): create stored credentials for target JVM * fix(scorecard): fix 502 status error * chore(scorecard): simplify client def * chore(scorecard): fetch recordings to ensure action is correctly performed * test(scorecard): test generating report for a recording * chore(scorecard): clean up * test(scorecard): list archives in tests * ci(scorecard): reconfigure ingress for kind * ci(k8s): correct cluster name * test(scorecard): use role instead of clusterrole for oauth rules * test(scorecard): parse health response for additional checks * chore(scorecard): add missing newline in logs * chore(scorecard): check status code before parsing body in health check * test(scorecard): add custom target discovery to recording scorecard test * add EOF wait and resp headers * add resp headers * chore(client): configure all clients to send safe requests * fix(clients): add missing content-type header * fix(scorecard): add missing test name in help message * chore(client): create new http requests when retrying * chore(bundle): update scorecard image tags --------- Signed-off-by: Thuan Vo Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Co-authored-by: Ming Wang * test(scorecard): scorecard test for Cryostat CR configuration changes (#739) * CR config scorecard * reformat * reviews * add kubectl license * test(scorecard): scorecard test for report generator (#753) * deploy reports sidecar * report scorecard test * update * rebase fix * query health * fix(build-ci): fix scorecard image tag returned as null (#760) Signed-off-by: Thuan Vo Co-authored-by: Elliott Baron * test(scorecard): add container logs to scorecard results (#758) * test(scorecard): add container logs to scorecard results * build(bundle): regenerate bundle with new scorecard tags * chore(scorecard): refactor to remove duplicate codes * add permission to publish comment when ci fails (#769) Co-authored-by: Elliott Baron * Update NewCoreContainer and associated tests * build(go): update Golang to 1.21 (#777) * test(scorecard): logWorkloadEvent for cryostat-recording errors (#759) * logWorkLoadEvent for cryostat-recording errors * reviews * tr.LogChannel --------- Co-authored-by: Elliott Baron * test(scorecard): fix rebasing skipped commit (#780) * Merge pull request #8 from ebaron/scorecard-methods test(scorecard): use methods for more easily passing data * update bundle image * Review fixes * generate storage key, create expected Secret * fixup! generate storage key, create expected Secret * database secret handling corrections * combine database connection password and encryption key into one secret * correct storage secret key/access key * update datasource port number to not conflict with storage * precreate eventtemplates bucket * remove storage volume parameter overrides * use HTTP for Cryostat probe even when TLS is enabled - TLS will be done via auth proxy later * correct environment variable names for proxy awareness * Fix remaining merge conflict * Fix makefile * config cleanup and test fixup --------- Signed-off-by: Thuan Vo Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Thuan Vo Co-authored-by: Andrew Azores Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Co-authored-by: Ming Wang Co-authored-by: Elliott Baron --- Makefile | 18 +- api/v1beta1/cryostat_conversion_test.go | 4 - api/v1beta1/cryostat_types.go | 20 + api/v1beta1/zz_generated.deepcopy.go | 36 + api/v1beta2/cryostat_types.go | 8 + api/v1beta2/zz_generated.deepcopy.go | 10 + bundle.Dockerfile | 2 +- ...yostat-operator.clusterserviceversion.yaml | 18 +- .../operator.cryostat.io_cryostats.yaml | 828 ++++++++++++++++-- bundle/metadata/annotations.yaml | 2 +- .../bases/operator.cryostat.io_cryostats.yaml | 828 ++++++++++++++++-- config/default/image_tag_patch.yaml | 2 +- ...yostat-operator.clusterserviceversion.yaml | 12 + .../resource_definitions.go | 441 +++++++--- internal/controllers/const_generated.go | 8 +- internal/controllers/constants/constants.go | 4 +- internal/controllers/reconciler.go | 8 + internal/controllers/reconciler_test.go | 152 ++-- internal/controllers/secrets.go | 52 +- internal/test/reconciler.go | 8 + internal/test/resources.go | 309 +++---- internal/tools/const_generator.go | 12 + 22 files changed, 2252 insertions(+), 530 deletions(-) diff --git a/Makefile b/Makefile index fc33bbbd9..9d9a63ac9 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ export APP_NAME ?= Cryostat # Images used by the operator CORE_NAMESPACE ?= $(DEFAULT_NAMESPACE) CORE_NAME ?= cryostat -CORE_VERSION ?= latest +CORE_VERSION ?= 3.0.0-snapshot export CORE_IMG ?= $(CORE_NAMESPACE)/$(CORE_NAME):$(CORE_VERSION) DATASOURCE_NAMESPACE ?= $(DEFAULT_NAMESPACE) DATASOURCE_NAME ?= jfr-datasource @@ -76,6 +76,14 @@ REPORTS_NAMESPACE ?= $(DEFAULT_NAMESPACE) REPORTS_NAME ?= cryostat-reports REPORTS_VERSION ?= latest export REPORTS_IMG ?= $(REPORTS_NAMESPACE)/$(REPORTS_NAME):$(REPORTS_VERSION) +DATABASE_NAMESPACE ?= $(DEFAULT_NAMESPACE) +DATABASE_NAME ?= cryostat-db +DATABASE_VERSION ?= latest +export DATABASE_IMG ?= $(DATABASE_NAMESPACE)/$(DATABASE_NAME):$(DATABASE_VERSION) +STORAGE_NAMESPACE ?= $(DEFAULT_NAMESPACE) +STORAGE_NAME ?= cryostat-storage +STORAGE_VERSION ?= latest +export STORAGE_IMG ?= $(STORAGE_NAMESPACE)/$(STORAGE_NAME):$(STORAGE_VERSION) CERT_MANAGER_VERSION ?= 1.11.5 CERT_MANAGER_MANIFEST ?= \ @@ -449,8 +457,8 @@ endif ##@ Deployment .PHONY: install -install: manifests kustomize ## Install CRDs into the cluster specified in ~/.kube/config. - $(KUSTOMIZE) build config/crd | $(CLUSTER_CLIENT) apply -f - +install: uninstall manifests kustomize ## Install CRDs into the cluster specified in ~/.kube/config. + $(KUSTOMIZE) build config/crd | $(CLUSTER_CLIENT) create -f - .PHONY: uninstall uninstall: manifests kustomize ## Uninstall CRDs from the cluster specified in ~/.kube/config. @@ -466,8 +474,8 @@ print_deploy_config: predeploy ## Print deployment configurations for the contro $(KUSTOMIZE) build $(KUSTOMIZE_DIR) .PHONY: deploy -deploy: check_cert_manager manifests kustomize predeploy ## Deploy controller in the configured cluster in ~/.kube/config - $(KUSTOMIZE) build $(KUSTOMIZE_DIR) | $(CLUSTER_CLIENT) apply -f - +deploy: check_cert_manager manifests kustomize predeploy undeploy ## Deploy controller in the configured cluster in ~/.kube/config + $(KUSTOMIZE) build $(KUSTOMIZE_DIR) | $(CLUSTER_CLIENT) create -f - ifeq ($(DISABLE_SERVICE_TLS), true) @echo "Disabling TLS for in-cluster communication between Services" @$(CLUSTER_CLIENT) -n $(DEPLOY_NAMESPACE) set env deployment/cryostat-operator-controller-manager DISABLE_SERVICE_TLS=true diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go index a7cbc1ec0..443b69cdb 100644 --- a/api/v1beta1/cryostat_conversion_test.go +++ b/api/v1beta1/cryostat_conversion_test.go @@ -139,8 +139,6 @@ func tableEntries() []TableEntry { (*test.TestResources).NewCryostatWithResources), Entry("low resource limit", (*test.TestResources).NewCryostatWithLowResourceLimitV1Beta1, (*test.TestResources).NewCryostatWithLowResourceLimit), - Entry("auth properties", (*test.TestResources).NewCryostatWithAuthPropertiesV1Beta1, - (*test.TestResources).NewCryostatWithAuthProperties), Entry("built-in discovery disabled", (*test.TestResources).NewCryostatWithBuiltInDiscoveryDisabledV1Beta1, (*test.TestResources).NewCryostatWithBuiltInDiscoveryDisabled), Entry("discovery port custom config", (*test.TestResources).NewCryostatWithDiscoveryPortConfigV1Beta1, @@ -149,8 +147,6 @@ func tableEntries() []TableEntry { (*test.TestResources).NewCryostatWithBuiltInPortConfigDisabled), Entry("JMX cache options", (*test.TestResources).NewCryostatWithJmxCacheOptionsSpecV1Beta1, (*test.TestResources).NewCryostatWithJmxCacheOptionsSpec), - Entry("subprocess heap", (*test.TestResources).NewCryostatWithReportSubprocessHeapSpecV1Beta1, - (*test.TestResources).NewCryostatWithReportSubprocessHeapSpec), Entry("security", (*test.TestResources).NewCryostatWithSecurityOptionsV1Beta1, (*test.TestResources).NewCryostatWithSecurityOptions), Entry("reports security", (*test.TestResources).NewCryostatWithReportSecurityOptionsV1Beta1, diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 9d554e068..3b7b04000 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -141,6 +141,8 @@ type CryostatStatus struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=status,order=2,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} GrafanaSecret string `json:"grafanaSecret,omitempty"` + // Name of the Secret containing the cryostat storage connection key + StorageSecret string `json:"storageSecret,omitempty"` // Address of the deployed Cryostat web application. // +operator-sdk:csv:customresourcedefinitions:type=status,order=1,xDescriptors={"urn:alm:descriptor:org.w3:link"} ApplicationURL string `json:"applicationUrl"` @@ -287,6 +289,13 @@ type GrafanaServiceConfig struct { ServiceConfig `json:",inline"` } +type StorageServiceConfig struct { + // HTTP port number for the cryostat storage service. + // Defaults to 8333 + HTTPPort *int32 `json:"httpPort,omitempty"` + ServiceConfig `json:",inline"` +} + // ReportsServiceConfig provides customization for the service handling // traffic for the cryostat-reports sidecars. type ReportsServiceConfig struct { @@ -309,6 +318,9 @@ type ServiceConfigList struct { // Specification for the service responsible for the cryostat-reports sidecars. // +optional ReportsConfig *ReportsServiceConfig `json:"reportsConfig,omitempty"` + // Specification for the service responsible for the cryostat storage container. + // +optional + StorageConfig *StorageServiceConfig `json:"storageConfig,omitEmpty"` } // NetworkConfiguration provides customization for how to expose a Cryostat @@ -502,6 +514,14 @@ type SecurityOptions struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec GrafanaSecurityContext *corev1.SecurityContext `json:"grafanaSecurityContext,omitempty"` + // Security Context to apply to the storage container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + StorageSecurityContext *corev1.SecurityContext `json:"storageSecurityContext,omitempty"` + // Security Context to apply to the storage container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + DatabaseSecurityContext *corev1.SecurityContext `json:"databaseSecurityContext,omitempty"` } // ReportsSecurityOptions contains Security Context customizations for the diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index a4098fcbd..7863ae29e 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -660,6 +660,16 @@ func (in *SecurityOptions) DeepCopyInto(out *SecurityOptions) { *out = new(corev1.SecurityContext) (*in).DeepCopyInto(*out) } + if in.StorageSecurityContext != nil { + in, out := &in.StorageSecurityContext, &out.StorageSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } + if in.DatabaseSecurityContext != nil { + in, out := &in.DatabaseSecurityContext, &out.DatabaseSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityOptions. @@ -724,6 +734,11 @@ func (in *ServiceConfigList) DeepCopyInto(out *ServiceConfigList) { *out = new(ReportsServiceConfig) (*in).DeepCopyInto(*out) } + if in.StorageConfig != nil { + in, out := &in.StorageConfig, &out.StorageConfig + *out = new(StorageServiceConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceConfigList. @@ -761,6 +776,27 @@ func (in *StorageConfiguration) DeepCopy() *StorageConfiguration { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StorageServiceConfig) DeepCopyInto(out *StorageServiceConfig) { + *out = *in + if in.HTTPPort != nil { + in, out := &in.HTTPPort, &out.HTTPPort + *out = new(int32) + **out = **in + } + in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageServiceConfig. +func (in *StorageServiceConfig) DeepCopy() *StorageServiceConfig { + if in == nil { + return nil + } + out := new(StorageServiceConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TargetDiscoveryOptions) DeepCopyInto(out *TargetDiscoveryOptions) { *out = *in diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index db2257e90..118c57aef 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -512,6 +512,14 @@ type SecurityOptions struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec GrafanaSecurityContext *corev1.SecurityContext `json:"grafanaSecurityContext,omitempty"` + // Security Context to apply to the storage container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + StorageSecurityContext *corev1.SecurityContext `json:"storageSecurityContext,omitempty"` + // Security Context to apply to the database container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + DatabaseSecurityContext *corev1.SecurityContext `json:"databaseSecurityContext,omitempty"` } // ReportsSecurityOptions contains Security Context customizations for the diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 96818377e..94b9e5f5f 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -665,6 +665,16 @@ func (in *SecurityOptions) DeepCopyInto(out *SecurityOptions) { *out = new(corev1.SecurityContext) (*in).DeepCopyInto(*out) } + if in.StorageSecurityContext != nil { + in, out := &in.StorageSecurityContext, &out.StorageSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } + if in.DatabaseSecurityContext != nil { + in, out := &in.DatabaseSecurityContext, &out.DatabaseSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityOptions. diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 8f2467e7d..b3a677365 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -6,7 +6,7 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=cryostat-operator LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.31.0 +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.32.0 LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 1761b6e18..e9ad2edfd 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -69,7 +69,7 @@ metadata: } } } - operators.operatorframework.io/builder: operator-sdk-v1.31.0 + operators.operatorframework.io/builder: operator-sdk-v1.32.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: github.com/cryostatio/cryostat-operator support: Cryostat Community @@ -379,12 +379,18 @@ spec: - description: Security Context to apply to the JFR Data Source container. displayName: Data Source Security Context path: securityOptions.dataSourceSecurityContext + - description: Security Context to apply to the storage container. + displayName: Database Security Context + path: securityOptions.databaseSecurityContext - description: Security Context to apply to the Grafana container. displayName: Grafana Security Context path: securityOptions.grafanaSecurityContext - description: Security Context to apply to the Cryostat pod. displayName: Pod Security Context path: securityOptions.podSecurityContext + - description: Security Context to apply to the storage container. + displayName: Storage Security Context + path: securityOptions.storageSecurityContext - description: Options to customize the services created for the Cryostat application and Grafana dashboard. displayName: Service Options @@ -754,12 +760,18 @@ spec: - description: Security Context to apply to the JFR Data Source container. displayName: Data Source Security Context path: securityOptions.dataSourceSecurityContext + - description: Security Context to apply to the storage container. + displayName: Database Security Context + path: securityOptions.databaseSecurityContext - description: Security Context to apply to the Grafana container. displayName: Grafana Security Context path: securityOptions.grafanaSecurityContext - description: Security Context to apply to the Cryostat pod. displayName: Pod Security Context path: securityOptions.podSecurityContext + - description: Security Context to apply to the storage container. + displayName: Storage Security Context + path: securityOptions.storageSecurityContext - description: Options to customize the services created for the Cryostat application and Grafana dashboard. displayName: Service Options @@ -1091,7 +1103,7 @@ spec: - /manager env: - name: RELATED_IMAGE_CORE - value: quay.io/cryostat/cryostat:latest + value: quay.io/cryostat/cryostat:3.0.0-snapshot - name: RELATED_IMAGE_DATASOURCE value: quay.io/cryostat/jfr-datasource:latest - name: RELATED_IMAGE_GRAFANA @@ -1226,7 +1238,7 @@ spec: provider: name: The Cryostat Community relatedImages: - - image: quay.io/cryostat/cryostat:latest + - image: quay.io/cryostat/cryostat:3.0.0-snapshot name: core - image: quay.io/cryostat/jfr-datasource:latest name: datasource diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 6b5826616..ebdfb45cc 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -3915,6 +3915,174 @@ spec: type: string type: object type: object + databaseSecurityContext: + description: Security Context to apply to the storage container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object grafanaSecurityContext: description: Security Context to apply to the Grafana container. properties: @@ -4219,11 +4387,179 @@ spec: type: array windowsOptions: description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. + containers. If unspecified, the options within a container's + SecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + storageSecurityContext: + description: Security Context to apply to the storage container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. properties: gmsaCredentialSpec: description: GMSACredentialSpec is where the GMSA admission @@ -4345,6 +4681,32 @@ spec: description: Type of service to create. Defaults to "ClusterIP". type: string type: object + storageConfig: + description: Specification for the service responsible for the + cryostat storage container. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the cryostat storage service. + Defaults to 8333 + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object type: object storageOptions: description: Options to customize the storage for Flight Recordings @@ -4733,6 +5095,10 @@ spec: grafanaSecret: description: Name of the Secret containing the generated Grafana credentials. type: string + storageSecret: + description: Name of the Secret containing the cryostat storage connection + key + type: string required: - applicationUrl type: object @@ -7916,61 +8282,230 @@ spec: type: array type: object type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod to - a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat pods - to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the Cryostat - application. - properties: - coreSecurityContext: - description: Security Context to apply to the Cryostat application + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod to + a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat pods + to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the Cryostat + application. + properties: + coreSecurityContext: + description: Security Context to apply to the Cryostat application + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + dataSourceSecurityContext: + description: Security Context to apply to the JFR Data Source container. properties: allowPrivilegeEscalation: @@ -8138,9 +8673,8 @@ spec: type: string type: object type: object - dataSourceSecurityContext: - description: Security Context to apply to the JFR Data Source - container. + databaseSecurityContext: + description: Security Context to apply to the storage container. properties: allowPrivilegeEscalation: description: 'AllowPrivilegeEscalation controls whether a @@ -8649,6 +9183,174 @@ spec: type: string type: object type: object + storageSecurityContext: + description: Security Context to apply to the storage container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object type: object serviceOptions: description: Options to customize the services created for the Cryostat diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index fc9f8edfc..70e2c7764 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -5,7 +5,7 @@ annotations: operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: cryostat-operator operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.metrics.builder: operator-sdk-v1.31.0 + operators.operatorframework.io.metrics.builder: operator-sdk-v1.32.0 operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 0739136ab..7b688916f 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -3905,6 +3905,174 @@ spec: type: string type: object type: object + databaseSecurityContext: + description: Security Context to apply to the storage container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object grafanaSecurityContext: description: Security Context to apply to the Grafana container. properties: @@ -4209,11 +4377,179 @@ spec: type: array windowsOptions: description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. + containers. If unspecified, the options within a container's + SecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + storageSecurityContext: + description: Security Context to apply to the storage container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. properties: gmsaCredentialSpec: description: GMSACredentialSpec is where the GMSA admission @@ -4335,6 +4671,32 @@ spec: description: Type of service to create. Defaults to "ClusterIP". type: string type: object + storageConfig: + description: Specification for the service responsible for the + cryostat storage container. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the service during its + creation. + type: object + httpPort: + description: HTTP port number for the cryostat storage service. + Defaults to 8333 + format: int32 + type: integer + labels: + additionalProperties: + type: string + description: Labels to add to the service during its creation. + The labels with keys "app" and "component" are reserved + for use by the operator. + type: object + serviceType: + description: Type of service to create. Defaults to "ClusterIP". + type: string + type: object type: object storageOptions: description: Options to customize the storage for Flight Recordings @@ -4723,6 +5085,10 @@ spec: grafanaSecret: description: Name of the Secret containing the generated Grafana credentials. type: string + storageSecret: + description: Name of the Secret containing the cryostat storage connection + key + type: string required: - applicationUrl type: object @@ -7906,61 +8272,230 @@ spec: type: array type: object type: object - nodeSelector: - additionalProperties: - type: string - description: 'Label selector used to schedule a Cryostat pod to - a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - tolerations: - description: 'Tolerations to allow scheduling of Cryostat pods - to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - type: object - securityOptions: - description: Options to configure the Security Contexts for the Cryostat - application. - properties: - coreSecurityContext: - description: Security Context to apply to the Cryostat application + nodeSelector: + additionalProperties: + type: string + description: 'Label selector used to schedule a Cryostat pod to + a node. See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + tolerations: + description: 'Tolerations to allow scheduling of Cryostat pods + to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + securityOptions: + description: Options to configure the Security Contexts for the Cryostat + application. + properties: + coreSecurityContext: + description: Security Context to apply to the Cryostat application + container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + dataSourceSecurityContext: + description: Security Context to apply to the JFR Data Source container. properties: allowPrivilegeEscalation: @@ -8128,9 +8663,8 @@ spec: type: string type: object type: object - dataSourceSecurityContext: - description: Security Context to apply to the JFR Data Source - container. + databaseSecurityContext: + description: Security Context to apply to the database container. properties: allowPrivilegeEscalation: description: 'AllowPrivilegeEscalation controls whether a @@ -8639,6 +9173,174 @@ spec: type: string type: object type: object + storageSecurityContext: + description: Security Context to apply to the storage container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object type: object serviceOptions: description: Options to customize the services created for the Cryostat diff --git a/config/default/image_tag_patch.yaml b/config/default/image_tag_patch.yaml index 32f0912c3..443332fd6 100644 --- a/config/default/image_tag_patch.yaml +++ b/config/default/image_tag_patch.yaml @@ -10,7 +10,7 @@ spec: - name: manager env: - name: RELATED_IMAGE_CORE - value: "quay.io/cryostat/cryostat:latest" + value: "quay.io/cryostat/cryostat:3.0.0-snapshot" - name: RELATED_IMAGE_DATASOURCE value: "quay.io/cryostat/jfr-datasource:latest" - name: RELATED_IMAGE_GRAFANA diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index f78ca7ac2..c5fd8c9d5 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -305,12 +305,18 @@ spec: - description: Security Context to apply to the JFR Data Source container. displayName: Data Source Security Context path: securityOptions.dataSourceSecurityContext + - description: Security Context to apply to the storage container. + displayName: Database Security Context + path: securityOptions.databaseSecurityContext - description: Security Context to apply to the Grafana container. displayName: Grafana Security Context path: securityOptions.grafanaSecurityContext - description: Security Context to apply to the Cryostat pod. displayName: Pod Security Context path: securityOptions.podSecurityContext + - description: Security Context to apply to the storage container. + displayName: Storage Security Context + path: securityOptions.storageSecurityContext - description: Options to customize the services created for the Cryostat application and Grafana dashboard. displayName: Service Options @@ -709,12 +715,18 @@ spec: - description: Security Context to apply to the JFR Data Source container. displayName: Data Source Security Context path: securityOptions.dataSourceSecurityContext + - description: Security Context to apply to the storage container. + displayName: Database Security Context + path: securityOptions.databaseSecurityContext - description: Security Context to apply to the Grafana container. displayName: Grafana Security Context path: securityOptions.grafanaSecurityContext - description: Security Context to apply to the Cryostat pod. displayName: Pod Security Context path: securityOptions.podSecurityContext + - description: Security Context to apply to the storage container. + displayName: Storage Security Context + path: securityOptions.storageSecurityContext - description: Options to customize the services created for the Cryostat application and Grafana dashboard. displayName: Service Options diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index a3cf2bf43..470f1dd5e 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -38,6 +38,8 @@ type ImageTags struct { DatasourceImageTag string GrafanaImageTag string ReportsImageTag string + StorageImageTag string + DatabaseImageTag string } type ServiceSpecs struct { @@ -45,6 +47,8 @@ type ServiceSpecs struct { GrafanaURL *url.URL ReportsURL *url.URL InsightsURL *url.URL + StorageURL *url.URL + DatabaseURL *url.URL } // TLSConfig contains TLS-related information useful when creating other objects @@ -241,6 +245,8 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima NewCoreContainer(cr, specs, imageTags.CoreImageTag, tls, openshift), NewGrafanaContainer(cr, imageTags.GrafanaImageTag, tls), NewJfrDatasourceContainer(cr, imageTags.DatasourceImageTag), + NewStorageContainer(cr, imageTags.StorageImageTag, tls), + newDatabaseContainer(cr, imageTags.DatabaseImageTag, tls), } volumes := newVolumeForCR(cr) @@ -349,28 +355,6 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima volumes = append(volumes, eventTemplateVolume) } - // Add Auth properties as a volume if specified (on Openshift) - if openshift && cr.Spec.AuthProperties != nil { - authResourceVolume := corev1.Volume{ - Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Spec.AuthProperties.ConfigMapName, - }, - Items: []corev1.KeyToPath{ - { - Key: cr.Spec.AuthProperties.Filename, - Path: "OpenShiftAuthManager.properties", - Mode: &readOnlyMode, - }, - }, - }, - }, - } - volumes = append(volumes, authResourceVolume) - } - var podSc *corev1.PodSecurityContext if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.PodSecurityContext != nil { podSc = cr.Spec.SecurityOptions.PodSecurityContext @@ -604,12 +588,71 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag templatesPath := "/opt/cryostat.d/templates.d" clientlibPath := "/opt/cryostat.d/clientlib.d" probesPath := "/opt/cryostat.d/probes.d" - authPropertiesPath := "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties" envs := []corev1.EnvVar{ { - Name: "CRYOSTAT_WEB_PORT", - Value: strconv.Itoa(int(constants.CryostatHTTPContainerPort)), + Name: "QUARKUS_HTTP_HOST", + Value: "localhost", + }, + { + Name: "QUARKUS_HTTP_PORT", + Value: "8181", + }, + { + Name: "QUARKUS_HTTP_PROXY_PROXY_ADDRESS_FORWARDING", + Value: "true", + }, + { + Name: "QUARKUS_HTTP_PROXY_ALLOW_X_FORWARDED", + Value: "true", + }, + { + Name: "QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_HOST", + Value: "true", + }, + { + Name: "QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_PREFIX", + Value: "true", + }, + { + Name: "QUARKUS_HIBERNATE_ORM_DATABASE_GENERATION", + Value: "drop-and-create", + }, + { + Name: "QUARKUS_DATASOURCE_USERNAME", + Value: "cryostat3", + }, + { + Name: "QUARKUS_DATASOURCE_JDBC_URL", + Value: "jdbc:postgresql://localhost:5432/cryostat3", + }, + { + Name: "STORAGE_BUCKETS_ARCHIVE_NAME", + Value: "archivedrecordings", + }, + { + Name: "QUARKUS_S3_ENDPOINT_OVERRIDE", + Value: "http://localhost:8333", + }, + { + Name: "QUARKUS_S3_PATH_STYLE_ACCESS", + Value: "true", + }, + { + Name: "QUARKUS_S3_AWS_REGION", + Value: "us-east-1", + }, + { + Name: "QUARKUS_S3_AWS_CREDENTIALS_TYPE", + Value: "static", + }, + { + Name: "QUARKUS_S3_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID", + Value: "cryostat", + }, + { + Name: "AWS_ACCESS_KEY_ID", + Value: "$(QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID)", }, { Name: "CRYOSTAT_CONFIG_PATH", @@ -680,6 +723,48 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag }, } + optional := false + secretName := cr.Name + "-db" + if cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil { + secretName = *cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName + } + envs = append(envs, corev1.EnvVar{ + Name: "QUARKUS_DATASOURCE_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + Key: "CONNECTION_KEY", + Optional: &optional, + }, + }, + }) + + envs = append(envs, corev1.EnvVar{ + Name: "QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID", + Value: "cryostat", + }) + + secretName = cr.Name + "-storage-secret-key" + envs = append(envs, corev1.EnvVar{ + Name: "QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + Key: "SECRET_KEY", + Optional: &optional, + }, + }, + }) + + envs = append(envs, corev1.EnvVar{ + Name: "AWS_SECRET_ACCESS_KEY", + Value: "$(QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY)", + }) + if specs.CoreURL != nil { coreEnvs := []corev1.EnvVar{ { @@ -696,23 +781,11 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag if specs.ReportsURL != nil { reportsEnvs := []corev1.EnvVar{ { - Name: "CRYOSTAT_REPORT_GENERATOR", + Name: "CRYOSTAT_SERVICES_REPORTS_URL", Value: specs.ReportsURL.String(), }, } envs = append(envs, reportsEnvs...) - } else { - subProcessMaxHeapSize := "200" - if cr.Spec.ReportOptions != nil && cr.Spec.ReportOptions.SubProcessMaxHeapSize != 0 { - subProcessMaxHeapSize = strconv.Itoa(int(cr.Spec.ReportOptions.SubProcessMaxHeapSize)) - } - subprocessReportHeapEnv := []corev1.EnvVar{ - { - Name: "CRYOSTAT_REPORT_GENERATION_MAX_HEAP", - Value: subProcessMaxHeapSize, - }, - } - envs = append(envs, subprocessReportHeapEnv...) } // Define INSIGHTS_PROXY URL if Insights integration is enabled @@ -740,11 +813,11 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag } jmxCacheEnvs := []corev1.EnvVar{ { - Name: "CRYOSTAT_TARGET_CACHE_SIZE", + Name: "CRYOSTAT_CONNECTIONS_MAX_OPEN", Value: targetCacheSize, }, { - Name: "CRYOSTAT_TARGET_CACHE_TTL", + Name: "CRYOSTAT_CONNECTIONS_TTL", Value: targetCacheTTL, }, } @@ -759,51 +832,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag }, } - if openshift { - // Force OpenShift platform strategy - openshiftEnvs := []corev1.EnvVar{ - { - Name: "CRYOSTAT_PLATFORM", - Value: "io.cryostat.platform.internal.OpenShiftPlatformStrategy", - }, - { - Name: "CRYOSTAT_AUTH_MANAGER", - Value: "io.cryostat.net.openshift.OpenShiftAuthManager", - }, - { - Name: "CRYOSTAT_OAUTH_CLIENT_ID", - Value: cr.Name, - }, - { - Name: "CRYOSTAT_BASE_OAUTH_ROLE", - Value: constants.OperatorNamePrefix + "oauth-client", - }, - } - envs = append(envs, openshiftEnvs...) - - if cr.Spec.AuthProperties != nil { - // Mount Auth properties if specified (on Openshift) - mounts = append(mounts, corev1.VolumeMount{ - Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, - MountPath: authPropertiesPath, - SubPath: "OpenShiftAuthManager.properties", - ReadOnly: true, - }) - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_CUSTOM_OAUTH_ROLE", - Value: cr.Spec.AuthProperties.ClusterRoleName, - }) - } - } - if cr.Spec.TargetDiscoveryOptions != nil { - if cr.Spec.TargetDiscoveryOptions.BuiltInDiscoveryDisabled { - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_DISABLE_BUILTIN_DISCOVERY", - Value: "true", - }) - } - var portNames string if len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames) > 0 { portNames = strings.Join(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames[:], ",") @@ -835,46 +864,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag } } - if !useEmptyDir(cr) { - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_JDBC_URL", - Value: "jdbc:h2:file:/opt/cryostat.d/conf.d/h2;INIT=create domain if not exists jsonb as varchar", - }, corev1.EnvVar{ - Name: "CRYOSTAT_HBM2DDL", - Value: "update", - }, corev1.EnvVar{ - Name: "CRYOSTAT_JDBC_DRIVER", - Value: "org.h2.Driver", - }, corev1.EnvVar{ - Name: "CRYOSTAT_HIBERNATE_DIALECT", - Value: "org.hibernate.dialect.H2Dialect", - }, corev1.EnvVar{ - Name: "CRYOSTAT_JDBC_USERNAME", - Value: cr.Name, - }, corev1.EnvVar{ - Name: "CRYOSTAT_JDBC_PASSWORD", - Value: cr.Name, - }) - } - - secretOptional := false - secretName := cr.Name + "-jmx-credentials-db" - if cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil { - secretName = *cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName - } - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: secretName, - }, - Key: "CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD", - Optional: &secretOptional, - }, - }, - }) - grafanaVars := []corev1.EnvVar{ { Name: "GRAFANA_DATASOURCE_URL", @@ -894,7 +883,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag } envs = append(envs, grafanaVars...) - livenessProbeScheme := corev1.URISchemeHTTP if tls == nil { // If TLS isn't set up, tell Cryostat to not use it envs = append(envs, corev1.EnvVar{ @@ -930,9 +918,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag } mounts = append(mounts, keystoreMount) - - // Use HTTPS for liveness probe - livenessProbeScheme = corev1.URISchemeHTTPS } // Mount the templates specified in Cryostat CR under /opt/cryostat.d/templates.d @@ -950,7 +935,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag HTTPGet: &corev1.HTTPGetAction{ Port: intstr.IntOrString{IntVal: constants.CryostatHTTPContainerPort}, Path: "/health/liveness", - Scheme: livenessProbeScheme, + Scheme: corev1.URISchemeHTTP, }, } @@ -1091,6 +1076,198 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo } } +/* + * storage.image.repository - Repository for the database container + * storage.image.pullPolicy - Pull Policy for the database container + * storage.image.tag - Image tag for the database container + * storage.resources - Resource requests/limits for the database container + * storage.securityContext - Security Context for the database container + */ +func NewStorageContainer(cr *model.CryostatInstance, imageTag string, tls *TLSConfig) corev1.Container { + var containerSc *corev1.SecurityContext + envs := []corev1.EnvVar{ + { + Name: "CRYOSTAT_BUCKETS", + Value: "archivedrecordings,archivedreports,eventtemplates", + }, + { + Name: "CRYOSTAT_ACCESS_KEY", + Value: "cryostat", + }, + { + Name: "DATA_DIR", + Value: "/data", + }, + { + Name: "IP_BIND", + Value: "0.0.0.0", + }, + } + + mounts := []corev1.VolumeMount{ + { + Name: cr.Name, + MountPath: "/data", + SubPath: "seaweed", + }, + } + + secretName := cr.Name + "-storage-secret-key" + optional := false + envs = append(envs, corev1.EnvVar{ + Name: "CRYOSTAT_SECRET_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + Key: "SECRET_KEY", + Optional: &optional, + }, + }, + }) + + if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.StorageSecurityContext != nil { + containerSc = cr.Spec.SecurityOptions.StorageSecurityContext + } else { + privEscalation := false + containerSc = &corev1.SecurityContext{ + AllowPrivilegeEscalation: &privEscalation, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{constants.CapabilityAll}, + }, + } + } + + livenessProbeScheme := corev1.URISchemeHTTP + probeHandler := corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.IntOrString{IntVal: 8333}, + Path: "/status", + Scheme: livenessProbeScheme, + }, + } + + return corev1.Container{ + Name: cr.Name + "-storage", + Image: imageTag, + ImagePullPolicy: getPullPolicy(imageTag), + VolumeMounts: mounts, + SecurityContext: containerSc, + Env: envs, + Ports: []corev1.ContainerPort{ + { + ContainerPort: constants.StoragePort, + }, + }, + LivenessProbe: &corev1.Probe{ + ProbeHandler: probeHandler, + FailureThreshold: 2, + }, + StartupProbe: &corev1.Probe{ + ProbeHandler: probeHandler, + FailureThreshold: 13, + }, + } +} + +/* +* { + Name: cr.Name, + MountPath: "/var/lib/pgsql/data", + SubPath: "postgres", + }, +*/ +/* + * db.image.repository - Repository for the database container + * db.image.pullPolicy - Pull Policy for the database container + * db.image.tag - Image tag for the database container + * db.resources - Resource requests/limits for the database container + * db.securityContext - Security Context for the database container + */ +func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSConfig) corev1.Container { + var containerSc *corev1.SecurityContext + if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.DatabaseSecurityContext != nil { + containerSc = cr.Spec.SecurityOptions.DatabaseSecurityContext + } else { + privEscalation := false + containerSc = &corev1.SecurityContext{ + AllowPrivilegeEscalation: &privEscalation, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{constants.CapabilityAll}, + }, + } + } + + envs := []corev1.EnvVar{ + { + Name: "POSTGRESQL_USER", + Value: "cryostat3", + }, + { + Name: "POSTGRESQL_DATABASE", + Value: "cryostat3", + }, + } + + optional := false + secretName := cr.Name + "-db" + envs = append(envs, corev1.EnvVar{ + Name: "POSTGRESQL_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + Key: "CONNECTION_KEY", + Optional: &optional, + }, + }, + }) + + envs = append(envs, corev1.EnvVar{ + Name: "PG_ENCRYPT_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + Key: "ENCRYPTION_KEY", + Optional: &optional, + }, + }, + }) + + mounts := []corev1.VolumeMount{ + { + Name: cr.Name, + MountPath: "/data", + SubPath: "seaweed", + }, + } + + return corev1.Container{ + Name: cr.Name + "-db", + Image: imageTag, + ImagePullPolicy: getPullPolicy(imageTag), + VolumeMounts: mounts, + SecurityContext: containerSc, + Env: envs, + Ports: []corev1.ContainerPort{ + { + ContainerPort: constants.DatabasePort, + }, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + Exec: &corev1.ExecAction{ + Command: []string{"pg_isready", "-U", "cryostat3", "-d", "cryostat3"}, + }, + }, + }, + } +} + // datasourceURL contains the fixed URL to jfr-datasource's web server var datasourceURL = "http://" + constants.LoopbackAddress + ":" + strconv.Itoa(int(constants.DatasourceContainerPort)) @@ -1128,9 +1305,13 @@ func NewJfrDatasourceContainer(cr *model.CryostatInstance, imageTag string) core }, Env: []corev1.EnvVar{ { - Name: "LISTEN_HOST", + Name: "QUARKUS_HTTP_HOST", Value: constants.LoopbackAddress, }, + { + Name: "QUARKUS_HTTP_PORT", + Value: strconv.Itoa(int(constants.DatasourceContainerPort)), + }, }, // Can't use HTTP probe since the port is not exposed over the network LivenessProbe: &corev1.Probe{ diff --git a/internal/controllers/const_generated.go b/internal/controllers/const_generated.go index 94f769ea5..d96a17a87 100644 --- a/internal/controllers/const_generated.go +++ b/internal/controllers/const_generated.go @@ -8,7 +8,7 @@ const AppName = "Cryostat" const OperatorVersion = "3.0.0-dev" // Default image tag for the core application image -const DefaultCoreImageTag = "quay.io/cryostat/cryostat:latest" +const DefaultCoreImageTag = "quay.io/cryostat/cryostat:3.0.0-snapshot" // Default image tag for the JFR datasource image const DefaultDatasourceImageTag = "quay.io/cryostat/jfr-datasource:latest" @@ -18,3 +18,9 @@ const DefaultGrafanaImageTag = "quay.io/cryostat/cryostat-grafana-dashboard:late // Default image tag for the Grafana dashboard image const DefaultReportsImageTag = "quay.io/cryostat/cryostat-reports:latest" + +// Default image tag for the Storage image +const DefaultStorageImageTag = "quay.io/cryostat/cryostat-storage:latest" + +// Default image tag for the Database image +const DefaultDatabaseImageTag = "quay.io/cryostat/cryostat-db:latest" diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index cc9541bf3..0e89f2f6a 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -23,8 +23,10 @@ const ( CryostatHTTPContainerPort int32 = 8181 CryostatJMXContainerPort int32 = 9091 GrafanaContainerPort int32 = 3000 - DatasourceContainerPort int32 = 8080 + DatasourceContainerPort int32 = 8989 ReportsContainerPort int32 = 10000 + StoragePort int32 = 8333 + DatabasePort int32 = 5432 LoopbackAddress string = "127.0.0.1" OperatorNamePrefix string = "cryostat-operator-" OperatorDeploymentName string = "cryostat-operator-controller-manager" diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index 2973af1ef..ce23a86ee 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -93,6 +93,12 @@ const grafanaImageTagEnv = "RELATED_IMAGE_GRAFANA" // Environment variable to override the cryostat-reports image const reportsImageTagEnv = "RELATED_IMAGE_REPORTS" +// Environment variable to override the cryostat-storage image +const storageImageTagEnv = "RELATED_IMAGE_STORAGE" + +// Environment variable to override the cryostat-database image +const databaseImageTagEnv = "RELATED_IMAGE_DATABASE" + // Regular expression for the start of a GID range in the OpenShift // supplemental groups SCC annotation var supGroupRegexp = regexp.MustCompile(`^\d+`) @@ -362,6 +368,8 @@ func (r *Reconciler) getImageTags() *resources.ImageTags { 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), } } diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 57c7402ef..e8fcde9ab 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -66,7 +66,7 @@ type cryostatTestInput struct { func (c *controllerTest) commonBeforeEach() *cryostatTestInput { t := &cryostatTestInput{ TestReconcilerConfig: test.TestReconcilerConfig{ - GeneratedPasswords: []string{"grafana", "credentials_database", "jmx", "keystore"}, + GeneratedPasswords: []string{"grafana", "credentials_database", "encryption_key", "object_storage", "jmx", "keystore"}, }, TestResources: &test.TestResources{ Name: "cryostat", @@ -146,6 +146,7 @@ func resourceChecks() []resourceCheck { }, "persistent volume claim"}, {(*cryostatTestInput).expectGrafanaSecret, "Grafana secret"}, {(*cryostatTestInput).expectCredentialsDatabaseSecret, "credentials database secret"}, + {(*cryostatTestInput).expectStorageSecret, "object storage secret"}, {(*cryostatTestInput).expectJMXSecret, "JMX secret"}, {(*cryostatTestInput).expectGrafanaService, "Grafana service"}, {(*cryostatTestInput).expectCoreService, "core service"}, @@ -528,7 +529,7 @@ func (c *controllerTest) commonTests() { var oldSecret *corev1.Secret BeforeEach(func() { cr = t.NewCryostat() - oldSecret = t.OtherCredentialsDatabaseSecret() + oldSecret = t.OtherDatabaseSecret() t.objs = append(t.objs, cr.Object, oldSecret) }) JustBeforeEach(func() { @@ -540,7 +541,7 @@ func (c *controllerTest) commonTests() { Expect(err).ToNot(HaveOccurred()) Expect(metav1.IsControlledBy(secret, cr.Object)).To(BeTrue()) - Expect(secret.StringData["CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD"]).To(Equal(oldSecret.StringData["CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD"])) + Expect(secret.StringData["CONNECTION_KEY"]).To(Equal(oldSecret.StringData["CONNECTION_KEY"])) }) }) Context("with existing Routes", func() { @@ -949,9 +950,6 @@ func (c *controllerTest) commonTests() { It("should create the EmptyDir with default specs", func() { t.expectEmptyDir(t.NewDefaultEmptyDir()) }) - It("should set Cryostat database to h2:mem", func() { - t.expectInMemoryDatabase() - }) }) Context("with custom EmptyDir config with requested spec", func() { BeforeEach(func() { @@ -963,9 +961,6 @@ func (c *controllerTest) commonTests() { It("should create the EmptyDir with requested specs", func() { t.expectEmptyDir(t.NewEmptyDirWithSpec()) }) - It("should set Cryostat database to h2:file", func() { - t.expectInMemoryDatabase() - }) }) Context("with overriden image tags", func() { var mainDeploy, reportsDeploy *appsv1.Deployment @@ -988,10 +983,14 @@ func (c *controllerTest) commonTests() { datasourceImg := "my/datasource-image:1.0.0-BETA25" grafanaImg := "my/grafana-image:1.0.0-dev" reportsImg := "my/reports-image:1.0.0-SNAPSHOT" + storageImg := "my/storage-image:1.0.0-dev" + databaseImg := "my/database-image:1.0.0-dev" t.EnvCoreImageTag = &coreImg t.EnvDatasourceImageTag = &datasourceImg t.EnvGrafanaImageTag = &grafanaImg t.EnvReportsImageTag = &reportsImg + t.EnvDatabaseImageTag = &databaseImg + t.EnvStorageImageTag = &storageImg }) It("should create deployment with the expected tags", func() { t.expectMainDeployment() @@ -999,7 +998,7 @@ func (c *controllerTest) commonTests() { }) It("should set ImagePullPolicy to Always", func() { containers := mainDeploy.Spec.Template.Spec.Containers - Expect(containers).To(HaveLen(3)) + Expect(containers).To(HaveLen(5)) for _, container := range containers { Expect(container.ImagePullPolicy).To(Equal(corev1.PullAlways)) } @@ -1014,10 +1013,14 @@ func (c *controllerTest) commonTests() { datasourceImg := "my/datasource-image:1.0.0" grafanaImg := "my/grafana-image:1.0.0" reportsImg := "my/reports-image:1.0.0" + storageImg := "my/storage-image:1.0.0" + databaseImg := "my/database-image:1.0.0" t.EnvCoreImageTag = &coreImg t.EnvDatasourceImageTag = &datasourceImg t.EnvGrafanaImageTag = &grafanaImg t.EnvReportsImageTag = &reportsImg + t.EnvDatabaseImageTag = &databaseImg + t.EnvStorageImageTag = &storageImg }) JustBeforeEach(func() { t.reconcileCryostatFully() @@ -1028,7 +1031,7 @@ func (c *controllerTest) commonTests() { }) It("should set ImagePullPolicy to IfNotPresent", func() { containers := mainDeploy.Spec.Template.Spec.Containers - Expect(containers).To(HaveLen(3)) + Expect(containers).To(HaveLen(5)) for _, container := range containers { Expect(container.ImagePullPolicy).To(Equal(corev1.PullIfNotPresent)) } @@ -1043,10 +1046,14 @@ func (c *controllerTest) commonTests() { datasourceImg := "my/datasource-image@sha256:59ded87392077c2371b26e021aade0409855b597383fa78e549eefafab8fc90c" grafanaImg := "my/grafana-image@sha256:e5bc16c2c5b69cd6fd8fdf1381d0a8b6cc9e01d92b9e1bb0a61ed89196563c72" reportsImg := "my/reports-image@sha256:8a23ca5e8c8a343789b8c14558a44a49d35ecd130c18e62edf0d1ad9ce88d37d" + storageImg := "my/storage-image@sha256:8b23ca5e8c8a343789b8c14558a44a49d35ecd130c18e62edf0d1ad9ce88d37d" + databaseImg := "my/database-image@sha256:8c23ca5e8c8a343789b8c14558a44a49d35ecd130c18e62edf0d1ad9ce88d37d" t.EnvCoreImageTag = &coreImg t.EnvDatasourceImageTag = &datasourceImg t.EnvGrafanaImageTag = &grafanaImg t.EnvReportsImageTag = &reportsImg + t.EnvDatabaseImageTag = &databaseImg + t.EnvStorageImageTag = &storageImg }) It("should create deployment with the expected tags", func() { t.expectMainDeployment() @@ -1054,7 +1061,7 @@ func (c *controllerTest) commonTests() { }) It("should set ImagePullPolicy to IfNotPresent", func() { containers := mainDeploy.Spec.Template.Spec.Containers - Expect(containers).To(HaveLen(3)) + Expect(containers).To(HaveLen(5)) for _, container := range containers { Expect(container.ImagePullPolicy).To(Equal(corev1.PullIfNotPresent)) } @@ -1080,7 +1087,7 @@ func (c *controllerTest) commonTests() { }) It("should set ImagePullPolicy to Always", func() { containers := mainDeploy.Spec.Template.Spec.Containers - Expect(containers).To(HaveLen(3)) + Expect(containers).To(HaveLen(5)) for _, container := range containers { Expect(container.ImagePullPolicy).To(Equal(corev1.PullAlways)) } @@ -1499,14 +1506,6 @@ func (c *controllerTest) commonTests() { JustBeforeEach(func() { t.reconcileCryostatFully() }) - Context("containing SubProcessMaxHeapSize", func() { - BeforeEach(func() { - t.objs = append(t.objs, t.NewCryostatWithReportSubprocessHeapSpec().Object) - }) - It("should set report subprocess max heap size", func() { - t.checkCoreHasEnvironmentVariables(t.NewReportSubprocessHeapEnv()) - }) - }) Context("containing JmxCacheOptions", func() { BeforeEach(func() { t.objs = append(t.objs, t.NewCryostatWithJmxCacheOptionsSpec().Object) @@ -1558,17 +1557,6 @@ func (c *controllerTest) commonTests() { }) }) }) - Context("Cryostat CR has authorization properties", func() { - BeforeEach(func() { - t.objs = append(t.objs, t.NewCryostatWithAuthProperties().Object, t.NewAuthPropertiesConfigMap(), t.NewAuthClusterRole()) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - }) - It("Should add volumes and volumeMounts to deployment", func() { - t.checkDeploymentHasAuthProperties() - }) - }) Context("with security options", func() { JustBeforeEach(func() { t.reconcileCryostatFully() @@ -1658,16 +1646,16 @@ func (c *controllerTest) commonTests() { }) It("should not generate default secret", func() { secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-jmx-credentials-db", Namespace: t.Namespace}, secret) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-db", Namespace: t.Namespace}, secret) Expect(kerrors.IsNotFound(err)).To(BeTrue()) }) Context("with an existing Credentials Database Secret", func() { BeforeEach(func() { - t.objs = append(t.objs, t.NewCredentialsDatabaseSecret()) + t.objs = append(t.objs, t.NewDatabaseSecret()) }) It("should not delete the existing Credentials Database Secret", func() { secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-jmx-credentials-db", Namespace: t.Namespace}, secret) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-db", Namespace: t.Namespace}, secret) Expect(err).ToNot(HaveOccurred()) }) }) @@ -2008,17 +1996,6 @@ func (c *controllerTest) commonTests() { Expect(kerrors.IsNotFound(err)).To(BeTrue()) }) }) - Context("Cryostat CR has authorization properties", func() { - BeforeEach(func() { - t.objs = append(t.objs, t.NewCryostatWithAuthProperties().Object, t.NewAuthPropertiesConfigMap(), t.NewAuthClusterRole()) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - }) - It("Should not add volumes and volumeMounts to deployment", func() { - t.checkDeploymentHasNoAuthProperties() - }) - }) Context("with report generator service", func() { BeforeEach(func() { t.ReportReplicas = 1 @@ -2462,16 +2439,6 @@ func (t *cryostatTestInput) expectEmptyDir(expectedEmptyDir *corev1.EmptyDirVolu Expect(emptyDir.SizeLimit).To(Equal(expectedEmptyDir.SizeLimit)) } -func (t *cryostatTestInput) expectInMemoryDatabase() { - deployment := &appsv1.Deployment{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, deployment) - Expect(err).ToNot(HaveOccurred()) - - containers := deployment.Spec.Template.Spec.Containers - coreContainer := containers[0] - Expect(coreContainer.Env).ToNot(ContainElements(t.DatabaseConfigEnvironmentVariables())) -} - func (t *cryostatTestInput) expectGrafanaSecret() { secret := &corev1.Secret{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana-basic", Namespace: t.Namespace}, secret) @@ -2485,11 +2452,22 @@ func (t *cryostatTestInput) expectGrafanaSecret() { func (t *cryostatTestInput) expectCredentialsDatabaseSecret() { secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-jmx-credentials-db", Namespace: t.Namespace}, secret) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-db", Namespace: t.Namespace}, secret) + Expect(err).ToNot(HaveOccurred()) + + // Compare to desired spec + expectedSecret := t.NewDatabaseSecret() + t.checkMetadata(secret, expectedSecret) + Expect(secret.StringData).To(Equal(expectedSecret.StringData)) +} + +func (t *cryostatTestInput) expectStorageSecret() { + secret := &corev1.Secret{} + err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-storage-secret-key", Namespace: t.Namespace}, secret) Expect(err).ToNot(HaveOccurred()) // Compare to desired spec - expectedSecret := t.NewCredentialsDatabaseSecret() + expectedSecret := t.NewStorageSecret() t.checkMetadata(secret, expectedSecret) Expect(secret.StringData).To(Equal(expectedSecret.StringData)) } @@ -2499,6 +2477,7 @@ func (t *cryostatTestInput) expectJMXSecret() { err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-jmx-auth", Namespace: t.Namespace}, secret) Expect(err).ToNot(HaveOccurred()) + // Compare to desired spec expectedSecret := t.NewJMXSecret() t.checkMetadata(secret, expectedSecret) Expect(secret.StringData).To(Equal(expectedSecret.StringData)) @@ -2715,7 +2694,6 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, ingress := !t.OpenShift && cr.Spec.NetworkOptions != nil && cr.Spec.NetworkOptions.CoreConfig != nil && cr.Spec.NetworkOptions.CoreConfig.IngressSpec != nil emptyDir := cr.Spec.StorageOptions != nil && cr.Spec.StorageOptions.EmptyDir != nil && cr.Spec.StorageOptions.EmptyDir.Enabled - builtInDiscoveryDisabled := cr.Spec.TargetDiscoveryOptions != nil && cr.Spec.TargetDiscoveryOptions.BuiltInDiscoveryDisabled hasPortConfig := cr.Spec.TargetDiscoveryOptions != nil && len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames) > 0 && len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNumbers) > 0 @@ -2727,7 +2705,6 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, t.checkCoreContainer(&coreContainer, ingress, reportsUrl, cr.Spec.AuthProperties != nil, emptyDir, - builtInDiscoveryDisabled, hasPortConfig, builtInPortConfigDisabled, dbSecretProvided, @@ -2870,45 +2847,10 @@ func (t *cryostatTestInput) checkDeploymentHasTemplates() { Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) } -func (t *cryostatTestInput) checkDeploymentHasAuthProperties() { - deployment := &appsv1.Deployment{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, deployment) - Expect(err).ToNot(HaveOccurred()) - - volumes := deployment.Spec.Template.Spec.Volumes - expectedVolumes := t.NewVolumeWithAuthProperties() - Expect(volumes).To(ConsistOf(expectedVolumes)) - - coreContainer := deployment.Spec.Template.Spec.Containers[0] - - volumeMounts := coreContainer.VolumeMounts - expectedVolumeMounts := t.NewVolumeMountsWithAuthProperties() - Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) - Expect(coreContainer.Env).To(ConsistOf(t.NewCoreEnvironmentVariables("", true, false, false, false, false, false, false))) -} - -func (t *cryostatTestInput) checkDeploymentHasNoAuthProperties() { - deployment := &appsv1.Deployment{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, deployment) - Expect(err).ToNot(HaveOccurred()) - - volumes := deployment.Spec.Template.Spec.Volumes - expectedVolumes := t.NewVolumes() - Expect(volumes).ToNot(ContainElements(t.NewAuthPropertiesVolume())) - Expect(volumes).To(ConsistOf(expectedVolumes)) - - coreContainer := deployment.Spec.Template.Spec.Containers[0] - - volumeMounts := coreContainer.VolumeMounts - expectedVolumeMounts := t.NewCoreVolumeMounts() - Expect(volumeMounts).ToNot(ContainElement(t.NewAuthPropertiesVolumeMount())) - Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) -} - func (t *cryostatTestInput) checkCoreContainer(container *corev1.Container, ingress bool, reportsUrl string, authProps bool, emptyDir bool, - builtInDiscoveryDisabled bool, hasPortConfig bool, builtInPortConfigDisabled bool, + hasPortConfig bool, builtInPortConfigDisabled bool, dbSecretProvided bool, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext) { @@ -2919,7 +2861,7 @@ func (t *cryostatTestInput) checkCoreContainer(container *corev1.Container, ingr Expect(container.Image).To(Equal(*t.EnvCoreImageTag)) } Expect(container.Ports).To(ConsistOf(t.NewCorePorts())) - Expect(container.Env).To(ConsistOf(t.NewCoreEnvironmentVariables(reportsUrl, authProps, ingress, emptyDir, builtInDiscoveryDisabled, hasPortConfig, builtInPortConfigDisabled, dbSecretProvided))) + Expect(container.Env).To(ConsistOf(t.NewCoreEnvironmentVariables(reportsUrl, authProps, ingress, emptyDir, hasPortConfig, builtInPortConfigDisabled, dbSecretProvided))) Expect(container.EnvFrom).To(ConsistOf(t.NewCoreEnvFromSource())) Expect(container.VolumeMounts).To(ConsistOf(t.NewCoreVolumeMounts())) Expect(container.LivenessProbe).To(Equal(t.NewCoreLivenessProbe())) @@ -2979,6 +2921,22 @@ func (t *cryostatTestInput) checkReportsContainer(container *corev1.Container, r test.ExpectResourceRequirements(&container.Resources, resources) } +// func (t *cryostatTestInput) checkStorageContainer(container *corev1.Container, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext) { +// Expect(container.Name).To(Equal(t.Name + "-storage")) +// if t.EnvReportsImageTag == nil { +// Expect(container.Image).To(HavePrefix("quay.io/cryostat/cryostat-storage:")) +// } else { +// Expect(container.Image).To(Equal(*t.EnvReportsImageTag)) +// } +// Expect(container.Ports).To(ConsistOf(t.NewStoragePorts())) +// Expect(container.Env).To(ConsistOf(t.NewStorageEnvironmentVariables(resources))) +// Expect(container.VolumeMounts).To(ConsistOf(t.NewReportsVolumeMounts())) +// Expect(container.LivenessProbe).To(Equal(t.NewReportsLivenessProbe())) +// Expect(container.SecurityContext).To(Equal(securityContext)) + +// test.ExpectResourceRequirements(&container.Resources, resources) +// } + func (t *cryostatTestInput) checkCoreHasEnvironmentVariables(expectedEnvVars []corev1.EnvVar) { deployment := &appsv1.Deployment{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, deployment) diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index 278ff5813..b2dc3209c 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -29,7 +29,10 @@ func (r *Reconciler) reconcileSecrets(ctx context.Context, cr *model.CryostatIns if err := r.reconcileGrafanaSecret(ctx, cr); err != nil { return err } - if err := r.reconcileDatabaseSecret(ctx, cr); err != nil { + if err := r.reconcileDatabaseConnectionSecret(ctx, cr); err != nil { + return err + } + if err := r.reconcileStorageSecret(ctx, cr); err != nil { return err } return r.reconcileJMXSecret(ctx, cr) @@ -98,12 +101,15 @@ func (r *Reconciler) reconcileJMXSecret(ctx context.Context, cr *model.CryostatI // databaseSecretNameSuffix is the suffix to be appended to the name of a // Cryostat CR to name its credentials database secret -const databaseSecretNameSuffix = "-jmx-credentials-db" +const databaseSecretNameSuffix = "-db" + +// databaseSecretConnectionPassKey indexes the database connection password within the Cryostat database Secret +const databaseSecretConnectionPassKey = "CONNECTION_KEY" -// dbSecretUserKey indexes the password within the Cryostat credentials database Secret -const databaseSecretPassKey = "CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD" +// databaseSecretEncryptionKey indexes the database encryption key within the Cryostat database Secret +const databaseSecretEncryptionKey = "ENCRYPTION_KEY" -func (r *Reconciler) reconcileDatabaseSecret(ctx context.Context, cr *model.CryostatInstance) error { +func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr *model.CryostatInstance) error { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name + databaseSecretNameSuffix, @@ -123,7 +129,41 @@ func (r *Reconciler) reconcileDatabaseSecret(ctx context.Context, cr *model.Cryo // Password is generated, so don't regenerate it when updating if secret.CreationTimestamp.IsZero() { - secret.StringData[databaseSecretPassKey] = r.GenPasswd(32) + secret.StringData[databaseSecretConnectionPassKey] = r.GenPasswd(32) + secret.StringData[databaseSecretEncryptionKey] = r.GenPasswd(32) + } + return nil + }) +} + +// storageSecretNameSuffix is the suffix to be appended to the name of a +// Cryostat CR to name its object storage secret +const storageSecretNameSuffix = "-storage-secret-key" + +// storageSecretUserKey indexes the password within the Cryostat storage Secret +const storageSecretPassKey = "SECRET_KEY" + +func (r *Reconciler) reconcileStorageSecret(ctx context.Context, cr *model.CryostatInstance) error { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: cr.Name + storageSecretNameSuffix, + Namespace: cr.InstallNamespace, + }, + } + + // secretProvided := cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil + // if secretProvided { + // return nil // Do not delete default secret to allow reverting to use default if needed + // } + + return r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { + if secret.StringData == nil { + secret.StringData = map[string]string{} + } + + // Password is generated, so don't regenerate it when updating + if secret.CreationTimestamp.IsZero() { + secret.StringData[storageSecretPassKey] = r.GenPasswd(32) } return nil }) diff --git a/internal/test/reconciler.go b/internal/test/reconciler.go index 44428d576..714610ab8 100644 --- a/internal/test/reconciler.go +++ b/internal/test/reconciler.go @@ -29,6 +29,8 @@ type TestReconcilerConfig struct { EnvDisableTLS *bool EnvCoreImageTag *string EnvDatasourceImageTag *string + EnvStorageImageTag *string + EnvDatabaseImageTag *string EnvGrafanaImageTag *string EnvReportsImageTag *string GeneratedPasswords []string @@ -61,6 +63,12 @@ func newTestOSUtils(config *TestReconcilerConfig) *testOSUtils { if config.EnvGrafanaImageTag != nil { envs["RELATED_IMAGE_GRAFANA"] = *config.EnvGrafanaImageTag } + if config.EnvStorageImageTag != nil { + envs["RELATED_IMAGE_STORAGE"] = *config.EnvStorageImageTag + } + if config.EnvDatabaseImageTag != nil { + envs["RELATED_IMAGE_DATABASE"] = *config.EnvDatabaseImageTag + } if config.EnvReportsImageTag != nil { envs["RELATED_IMAGE_REPORTS"] = *config.EnvReportsImageTag } diff --git a/internal/test/resources.go b/internal/test/resources.go index 3454d6da8..a7584499c 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -500,16 +500,6 @@ func (r *TestResources) NewCryostatWithLowResourceLimit() *model.CryostatInstanc return cr } -func (r *TestResources) NewCryostatWithAuthProperties() *model.CryostatInstance { - cr := r.NewCryostat() - cr.Spec.AuthProperties = &operatorv1beta2.AuthorizationProperties{ - ConfigMapName: "authConfigMapName", - Filename: "auth.properties", - ClusterRoleName: "custom-auth-cluster-role", - } - return cr -} - func (r *TestResources) NewCryostatWithBuiltInDiscoveryDisabled() *model.CryostatInstance { cr := r.NewCryostat() cr.Spec.TargetDiscoveryOptions = &operatorv1beta2.TargetDiscoveryOptions{ @@ -936,26 +926,40 @@ func (r *TestResources) OtherGrafanaSecret() *corev1.Secret { } } -func (r *TestResources) NewCredentialsDatabaseSecret() *corev1.Secret { +func (r *TestResources) NewDatabaseSecret() *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-jmx-credentials-db", + Name: r.Name + "-db", Namespace: r.Namespace, }, StringData: map[string]string{ - "CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD": "credentials_database", + "CONNECTION_KEY": "credentials_database", + "ENCRYPTION_KEY": "encryption_key", }, } } -func (r *TestResources) OtherCredentialsDatabaseSecret() *corev1.Secret { +func (r *TestResources) NewStorageSecret() *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-jmx-credentials-db", + Name: r.Name + "-storage-secret-key", Namespace: r.Namespace, }, StringData: map[string]string{ - "CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD": "other-pass", + "SECRET_KEY": "object_storage", + }, + } +} + +func (r *TestResources) OtherDatabaseSecret() *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name + "-db", + Namespace: r.Namespace, + }, + StringData: map[string]string{ + "CONNECTION_KEY": "other-pass", + "ENCRYPTION_KEY": "other-key", }, } } @@ -1258,7 +1262,7 @@ func (r *TestResources) NewGrafanaPorts() []corev1.ContainerPort { func (r *TestResources) NewDatasourcePorts() []corev1.ContainerPort { return []corev1.ContainerPort{ { - ContainerPort: 8080, + ContainerPort: 8989, }, } } @@ -1271,13 +1275,87 @@ func (r *TestResources) NewReportsPorts() []corev1.ContainerPort { } } +func (r *TestResources) NewStoragePorts() []corev1.ContainerPort { + return []corev1.ContainerPort{ + { + ContainerPort: 8080, + }, + { + ContainerPort: 8333, + }, + { + ContainerPort: 8888, + }, + } +} + func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps bool, ingress bool, - emptyDir bool, builtInDiscoveryDisabled bool, hasPortConfig bool, builtInPortConfigDisabled bool, dbSecretProvided bool) []corev1.EnvVar { + emptyDir bool, hasPortConfig bool, builtInPortConfigDisabled bool, dbSecretProvided bool) []corev1.EnvVar { envs := []corev1.EnvVar{ { - Name: "CRYOSTAT_WEB_PORT", + Name: "QUARKUS_HTTP_HOST", + Value: "localhost", + }, + { + Name: "QUARKUS_HTTP_PORT", Value: "8181", }, + { + Name: "QUARKUS_HTTP_PROXY_PROXY_ADDRESS_FORWARDING", + Value: "true", + }, + { + Name: "QUARKUS_HTTP_PROXY_ALLOW_X_FORWARDED", + Value: "true", + }, + { + Name: "QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_HOST", + Value: "true", + }, + { + Name: "QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_PREFIX", + Value: "true", + }, + { + Name: "QUARKUS_HIBERNATE_ORM_DATABASE_GENERATION", + Value: "drop-and-create", + }, + { + Name: "QUARKUS_DATASOURCE_USERNAME", + Value: "cryostat3", + }, + { + Name: "QUARKUS_DATASOURCE_JDBC_URL", + Value: "jdbc:postgresql://localhost:5432/cryostat3", + }, + { + Name: "STORAGE_BUCKETS_ARCHIVE_NAME", + Value: "archivedrecordings", + }, + { + Name: "QUARKUS_S3_ENDPOINT_OVERRIDE", + Value: "http://localhost:8333", + }, + { + Name: "QUARKUS_S3_PATH_STYLE_ACCESS", + Value: "true", + }, + { + Name: "QUARKUS_S3_AWS_REGION", + Value: "us-east-1", + }, + { + Name: "QUARKUS_S3_AWS_CREDENTIALS_TYPE", + Value: "static", + }, + { + Name: "QUARKUS_S3_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID", + Value: "cryostat", + }, + { + Name: "AWS_ACCESS_KEY_ID", + Value: "$(QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID)", + }, { Name: "CRYOSTAT_CONFIG_PATH", Value: "/opt/cryostat.d/conf.d", @@ -1303,46 +1381,65 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps Value: "false", }, { - Name: "CRYOSTAT_TARGET_CACHE_SIZE", + Name: "CRYOSTAT_CONNECTIONS_MAX_OPEN", Value: "-1", }, { - Name: "CRYOSTAT_TARGET_CACHE_TTL", + Name: "CRYOSTAT_CONNECTIONS_TTL", Value: "10", }, { Name: "CRYOSTAT_K8S_NAMESPACES", Value: strings.Join(r.TargetNamespaces, ","), }, + { + Name: "GRAFANA_DATASOURCE_URL", + Value: "http://127.0.0.1:8989", + }, + { + Name: "QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID", + Value: "cryostat", + }, + { + Name: "AWS_SECRET_ACCESS_KEY", + Value: "$(QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY)", + }, } - envs = append(envs, r.NewTargetDiscoveryEnvVar(builtInDiscoveryDisabled, hasPortConfig, builtInPortConfigDisabled)...) - - if !emptyDir { - envs = append(envs, r.DatabaseConfigEnvironmentVariables()...) - } + envs = append(envs, r.NewTargetDiscoveryEnvVar(hasPortConfig, builtInPortConfigDisabled)...) optional := false - secretName := r.NewCredentialsDatabaseSecret().Name + secretName := r.NewDatabaseSecret().Name if dbSecretProvided { secretName = providedDatabaseSecretName } envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD", + Name: "QUARKUS_DATASOURCE_PASSWORD", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: secretName, }, - Key: "CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD", + Key: "CONNECTION_KEY", Optional: &optional, }, }, }, - corev1.EnvVar{ - Name: "GRAFANA_DATASOURCE_URL", - Value: "http://127.0.0.1:8080", + ) + + secretName = r.NewStorageSecret().Name + envs = append(envs, corev1.EnvVar{ + Name: "QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + Key: "SECRET_KEY", + Optional: &optional, + }, }, + }, ) if !r.TLS { @@ -1365,48 +1462,16 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps }) } - if r.OpenShift { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_PLATFORM", - Value: "io.cryostat.platform.internal.OpenShiftPlatformStrategy", - }, - corev1.EnvVar{ - Name: "CRYOSTAT_AUTH_MANAGER", - Value: "io.cryostat.net.openshift.OpenShiftAuthManager", - }, - corev1.EnvVar{ - Name: "CRYOSTAT_OAUTH_CLIENT_ID", - Value: r.Name, - }, - corev1.EnvVar{ - Name: "CRYOSTAT_BASE_OAUTH_ROLE", - Value: "cryostat-operator-oauth-client", - }) - - if authProps { - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_CUSTOM_OAUTH_ROLE", - Value: "custom-auth-cluster-role", - }) - } - envs = append(envs, r.newNetworkEnvironmentVariables()...) - } else if ingress { // On Kubernetes + if r.OpenShift || ingress { envs = append(envs, r.newNetworkEnvironmentVariables()...) } if reportsUrl != "" { envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_REPORT_GENERATOR", + Name: "CRYOSTAT_SERVICES_REPORTS_URL", Value: reportsUrl, }) - } else { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_REPORT_GENERATION_MAX_HEAP", - Value: "200", - }) } if len(r.InsightsURL) > 0 { @@ -1419,35 +1484,6 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps return envs } -func (r *TestResources) DatabaseConfigEnvironmentVariables() []corev1.EnvVar { - return []corev1.EnvVar{ - { - Name: "CRYOSTAT_JDBC_URL", - Value: "jdbc:h2:file:/opt/cryostat.d/conf.d/h2;INIT=create domain if not exists jsonb as varchar", - }, - { - Name: "CRYOSTAT_HBM2DDL", - Value: "update", - }, - { - Name: "CRYOSTAT_JDBC_DRIVER", - Value: "org.h2.Driver", - }, - { - Name: "CRYOSTAT_HIBERNATE_DIALECT", - Value: "org.hibernate.dialect.H2Dialect", - }, - { - Name: "CRYOSTAT_JDBC_USERNAME", - Value: r.Name, - }, - { - Name: "CRYOSTAT_JDBC_PASSWORD", - Value: r.Name, - }, - } -} - func (r *TestResources) newNetworkEnvironmentVariables() []corev1.EnvVar { envs := []corev1.EnvVar{ { @@ -1501,7 +1537,7 @@ func (r *TestResources) NewGrafanaEnvironmentVariables() []corev1.EnvVar { envs := []corev1.EnvVar{ { Name: "JFR_DATASOURCE_URL", - Value: "http://127.0.0.1:8080", + Value: "http://127.0.0.1:8989", }, } if r.TLS { @@ -1522,9 +1558,13 @@ func (r *TestResources) NewGrafanaEnvironmentVariables() []corev1.EnvVar { func (r *TestResources) NewDatasourceEnvironmentVariables() []corev1.EnvVar { return []corev1.EnvVar{ { - Name: "LISTEN_HOST", + Name: "QUARKUS_HTTP_HOST", Value: "127.0.0.1", }, + { + Name: "QUARKUS_HTTP_PORT", + Value: "8989", + }, } } @@ -1569,6 +1609,19 @@ func (r *TestResources) NewReportsEnvironmentVariables(resources *corev1.Resourc return envs } +func (r *TestResources) NewStorageEnvironmentVariables() []corev1.EnvVar { + return []corev1.EnvVar{ + { + Name: "QUARKUS_HTTP_HOST", + Value: "127.0.0.1", + }, + { + Name: "QUARKUS_HTTP_PORT", + Value: "8989", + }, + } +} + func (r *TestResources) NewCoreEnvFromSource() []corev1.EnvFromSource { envsFrom := []corev1.EnvFromSource{ { @@ -1603,38 +1656,22 @@ func (r *TestResources) NewGrafanaEnvFromSource() []corev1.EnvFromSource { } } -func (r *TestResources) NewReportSubprocessHeapEnv() []corev1.EnvVar { - return []corev1.EnvVar{ - { - Name: "CRYOSTAT_REPORT_GENERATION_MAX_HEAP", - Value: "500", - }, - } -} - func (r *TestResources) NewJmxCacheOptionsEnv() []corev1.EnvVar { return []corev1.EnvVar{ { - Name: "CRYOSTAT_TARGET_CACHE_SIZE", + Name: "CRYOSTAT_CONNECTIONS_MAX_OPEN", Value: "10", }, { - Name: "CRYOSTAT_TARGET_CACHE_TTL", + Name: "CRYOSTAT_CONNECTIONS_TTL", Value: "20", }, } } -func (r *TestResources) NewTargetDiscoveryEnvVar(builtInDiscoveryDisabled bool, hasPortConfig bool, builtInPortConfigDisabled bool) []corev1.EnvVar { +func (r *TestResources) NewTargetDiscoveryEnvVar(hasPortConfig bool, builtInPortConfigDisabled bool) []corev1.EnvVar { envs := make([]corev1.EnvVar, 0) - if builtInDiscoveryDisabled { - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_DISABLE_BUILTIN_DISCOVERY", - Value: "true", - }) - } - if hasPortConfig { envs = append(envs, corev1.EnvVar{ @@ -1785,15 +1822,11 @@ func (r *TestResources) NewCoreStartupProbe() *corev1.Probe { } func (r *TestResources) newCoreProbeHandler() corev1.ProbeHandler { - protocol := corev1.URISchemeHTTPS - if !r.TLS { - protocol = corev1.URISchemeHTTP - } return corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Port: intstr.IntOrString{IntVal: 8181}, Path: "/health/liveness", - Scheme: protocol, + Scheme: corev1.URISchemeHTTP, }, } } @@ -1818,7 +1851,7 @@ func (r *TestResources) NewDatasourceLivenessProbe() *corev1.Probe { return &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ Exec: &corev1.ExecAction{ - Command: []string{"curl", "--fail", "http://127.0.0.1:8080"}, + Command: []string{"curl", "--fail", "http://127.0.0.1:8989"}, }, }, } @@ -2512,26 +2545,6 @@ func (r *TestResources) OtherRole() *rbacv1.Role { } } -func (r *TestResources) NewAuthClusterRole() *rbacv1.ClusterRole { - return &rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: "custom-auth-cluster-role", - }, - Rules: []rbacv1.PolicyRule{ - { - Verbs: []string{"get", "update", "patch", "delete"}, - APIGroups: []string{"group"}, - Resources: []string{"resources"}, - }, - { - Verbs: []string{"get", "update", "patch", "delete"}, - APIGroups: []string{"another_group"}, - Resources: []string{"another_resources"}, - }, - }, - } -} - func (r *TestResources) NewRoleBinding(ns string) *rbacv1.RoleBinding { return &rbacv1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ @@ -2657,18 +2670,6 @@ func (r *TestResources) NewOtherTemplateConfigMap() *corev1.ConfigMap { } } -func (r *TestResources) NewAuthPropertiesConfigMap() *corev1.ConfigMap { - return &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "authConfigMapName", - Namespace: r.Namespace, - }, - Data: map[string]string{ - "auth.properties": "CRYOSTAT_RESOURCE=resources.group\nANOTHER_CRYOSTAT_RESOURCE=another_resources.another_group", - }, - } -} - func (r *TestResources) NewNamespace() *corev1.Namespace { return &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ diff --git a/internal/tools/const_generator.go b/internal/tools/const_generator.go index eadea2eeb..116c4e5ee 100644 --- a/internal/tools/const_generator.go +++ b/internal/tools/const_generator.go @@ -28,6 +28,8 @@ const coreImageEnv = "CORE_IMG" const datasourceImageEnv = "DATASOURCE_IMG" const grafanaImageEnv = "GRAFANA_IMG" const reportsImageEnv = "REPORTS_IMG" +const storageImageEnv = "STORAGE_IMG" +const databaseImageEnv = "DATABASE_IMG" // This program generates a const_generated.go file containing image tag // constants for each container image deployed by the operator, along with @@ -41,6 +43,8 @@ func main() { DatasourceImageTag string GrafanaImageTag string ReportsImageTag string + StorageImageTag string + DatabaseImageTag string }{ AppName: getEnvVar(appNameEnv), OperatorVersion: getEnvVar(operatorVersionEnv), @@ -48,6 +52,8 @@ func main() { DatasourceImageTag: getEnvVar(datasourceImageEnv), GrafanaImageTag: getEnvVar(grafanaImageEnv), ReportsImageTag: getEnvVar(reportsImageEnv), + StorageImageTag: getEnvVar(storageImageEnv), + DatabaseImageTag: getEnvVar(databaseImageEnv), } // Create the source file to generate @@ -91,4 +97,10 @@ const DefaultGrafanaImageTag = "{{ .GrafanaImageTag }}" // Default image tag for the Grafana dashboard image const DefaultReportsImageTag = "{{ .ReportsImageTag }}" + +// Default image tag for the Storage image +const DefaultStorageImageTag = "{{ .StorageImageTag }}" + +// Default image tag for the Database image +const DefaultDatabaseImageTag = "{{ .DatabaseImageTag }}" `)) From 9593e8a6bd5ad90be0cd892c7ab4b6a9a1217ec8 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Thu, 25 Apr 2024 13:31:31 -0400 Subject: [PATCH 26/53] build(insights): consume out-of-tree Insights module (#800) * build(insights): consume out-of-tree Insights module * Upgrade dependencies * Fix environment variable name * Remove unneeded replace directives --- bundle.Dockerfile | 2 +- ...yostat-operator.clusterserviceversion.yaml | 68 +- .../operator.cryostat.io_cryostats.yaml | 721 +++++++++--------- bundle/metadata/annotations.yaml | 2 +- .../bases/operator.cryostat.io_cryostats.yaml | 719 +++++++++-------- config/manager/manager.yaml | 2 +- ...yostat-operator.clusterserviceversion.yaml | 2 +- config/rbac/role.yaml | 60 +- config/samples/sample-app-agent.yaml | 6 + go.mod | 99 ++- go.sum | 655 +++------------- internal/controllers/cryostat_controller.go | 8 + internal/controllers/insights/apicast.go | 104 --- internal/controllers/insights/insights.go | 375 --------- .../insights/insights_controller.go | 142 ---- .../insights/insights_controller_test.go | 266 ------- .../insights/insights_controller_unit_test.go | 149 ---- .../insights/insights_suite_test.go | 96 --- internal/controllers/insights/setup.go | 162 ---- internal/controllers/insights/setup_test.go | 162 ---- internal/controllers/insights/test/manager.go | 68 -- .../controllers/insights/test/resources.go | 393 ---------- internal/controllers/insights/test/utils.go | 66 -- internal/controllers/reconciler_test.go | 54 +- internal/main.go | 44 +- internal/test/resources.go | 65 +- internal/webhooks/validator.go | 20 +- internal/webhooks/validator_test.go | 3 +- internal/webhooks/webhook_suite_test.go | 16 +- 29 files changed, 1114 insertions(+), 3415 deletions(-) delete mode 100644 internal/controllers/insights/apicast.go delete mode 100644 internal/controllers/insights/insights.go delete mode 100644 internal/controllers/insights/insights_controller.go delete mode 100644 internal/controllers/insights/insights_controller_test.go delete mode 100644 internal/controllers/insights/insights_controller_unit_test.go delete mode 100644 internal/controllers/insights/insights_suite_test.go delete mode 100644 internal/controllers/insights/setup.go delete mode 100644 internal/controllers/insights/setup_test.go delete mode 100644 internal/controllers/insights/test/manager.go delete mode 100644 internal/controllers/insights/test/resources.go delete mode 100644 internal/controllers/insights/test/utils.go diff --git a/bundle.Dockerfile b/bundle.Dockerfile index b3a677365..8f2467e7d 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -6,7 +6,7 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=cryostat-operator LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.32.0 +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.31.0 LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index e9ad2edfd..01181eb8f 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-04-16T21:08:10Z" + createdAt: "2024-04-25T15:33:04Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -69,7 +69,7 @@ metadata: } } } - operators.operatorframework.io/builder: operator-sdk-v1.32.0 + operators.operatorframework.io/builder: operator-sdk-v1.31.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: github.com/cryostatio/cryostat-operator support: Cryostat Community @@ -760,7 +760,7 @@ spec: - description: Security Context to apply to the JFR Data Source container. displayName: Data Source Security Context path: securityOptions.dataSourceSecurityContext - - description: Security Context to apply to the storage container. + - description: Security Context to apply to the database container. displayName: Database Security Context path: securityOptions.databaseSecurityContext - description: Security Context to apply to the Grafana container. @@ -899,15 +899,6 @@ spec: spec: clusterPermissions: - rules: - - apiGroups: - - "" - resources: - - configmaps - - configmaps/finalizers - - secrets - - services - verbs: - - '*' - apiGroups: - "" resources: @@ -937,19 +928,22 @@ spec: verbs: - get - apiGroups: - - apps + - "" + resourceNames: + - pull-secret resources: - - daemonsets - - deployments - - replicasets - - statefulsets + - secrets verbs: - - '*' + - get + - list + - watch - apiGroups: - apps resources: + - daemonsets - deployments - - deployments/finalizers + - replicasets + - statefulsets verbs: - '*' - apiGroups: @@ -1114,7 +1108,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: NAMESPACE + - name: OPERATOR_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace @@ -1197,6 +1191,40 @@ spec: verbs: - create - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - update + - watch + - apiGroups: + - "" + resources: + - configmaps/finalizers + - secrets + - services + verbs: + - create + - get + - list + - update + - watch + - apiGroups: + - apps + resources: + - deployments + - deployments/finalizers + verbs: + - create + - get + - list + - update + - watch - apiGroups: - monitoring.coreos.com resources: diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index ebdfb45cc..1c51814e6 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -158,7 +158,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -166,7 +166,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -193,25 +193,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -222,7 +222,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -237,9 +237,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -248,7 +248,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -261,7 +261,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -270,9 +270,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -287,20 +287,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -331,30 +331,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -367,7 +367,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -377,8 +377,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -414,20 +414,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -435,13 +436,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -472,7 +473,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -480,7 +481,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -507,25 +508,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -536,7 +537,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -551,9 +552,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -562,7 +563,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -575,7 +576,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -584,9 +585,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -601,20 +602,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -645,30 +646,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -681,7 +682,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -691,8 +692,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -728,20 +729,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -749,13 +751,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -786,7 +788,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -794,7 +796,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -821,25 +823,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -850,7 +852,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -865,9 +867,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -876,7 +878,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -889,7 +891,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -898,9 +900,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -915,20 +917,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -959,30 +961,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -995,7 +997,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -1005,8 +1007,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -1042,20 +1044,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -1063,13 +1066,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -1179,7 +1182,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object schedulingOptions: @@ -2232,8 +2236,9 @@ spec: defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". + configured seccomp profile location. Must be set + if type is "Localhost". Must NOT be set for any + other type. type: string type: description: "type indicates which kind of seccomp @@ -2301,15 +2306,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork + of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -2442,8 +2443,9 @@ spec: defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". + configured seccomp profile location. Must be set + if type is "Localhost". Must NOT be set for any + other type. type: string type: description: "type indicates which kind of seccomp @@ -2476,15 +2478,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork + of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -2555,7 +2553,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object dataSourceResources: @@ -2603,7 +2602,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object grafanaResources: @@ -2651,7 +2651,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object type: object @@ -3694,7 +3695,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -3726,15 +3728,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -3863,7 +3862,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -3895,15 +3895,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4031,7 +4028,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -4063,15 +4061,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4199,7 +4194,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -4231,15 +4227,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4340,7 +4333,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -4405,15 +4399,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4541,7 +4532,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -4573,15 +4565,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4902,7 +4891,8 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: @@ -5230,7 +5220,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -5238,7 +5228,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -5265,25 +5255,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -5294,7 +5284,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -5309,9 +5299,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -5320,7 +5310,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -5333,7 +5323,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -5342,9 +5332,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -5359,20 +5349,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -5403,30 +5393,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -5439,7 +5429,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -5449,8 +5439,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -5486,20 +5476,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -5507,13 +5498,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -5544,7 +5535,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -5552,7 +5543,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -5579,25 +5570,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -5608,7 +5599,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -5623,9 +5614,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -5634,7 +5625,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -5647,7 +5638,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -5656,9 +5647,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -5673,20 +5664,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -5717,30 +5708,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -5753,7 +5744,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -5763,8 +5754,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -5800,20 +5791,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -5821,13 +5813,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -5937,7 +5929,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object schedulingOptions: @@ -6990,8 +6983,9 @@ spec: defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". + configured seccomp profile location. Must be set + if type is "Localhost". Must NOT be set for any + other type. type: string type: description: "type indicates which kind of seccomp @@ -7059,15 +7053,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork + of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -7200,8 +7190,9 @@ spec: defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". + configured seccomp profile location. Must be set + if type is "Localhost". Must NOT be set for any + other type. type: string type: description: "type indicates which kind of seccomp @@ -7234,15 +7225,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork + of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -7313,7 +7300,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object dataSourceResources: @@ -7361,7 +7349,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object grafanaResources: @@ -7409,7 +7398,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object type: object @@ -8452,7 +8442,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -8484,15 +8475,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -8621,7 +8609,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -8653,15 +8642,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -8674,7 +8660,7 @@ spec: type: object type: object databaseSecurityContext: - description: Security Context to apply to the storage container. + description: Security Context to apply to the database container. properties: allowPrivilegeEscalation: description: 'AllowPrivilegeEscalation controls whether a @@ -8789,7 +8775,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -8821,15 +8808,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -8957,7 +8941,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -8989,15 +8974,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -9098,7 +9080,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -9163,15 +9146,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -9299,7 +9279,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -9331,15 +9312,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -9634,7 +9612,8 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index 70e2c7764..fc9f8edfc 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -5,7 +5,7 @@ annotations: operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: cryostat-operator operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.metrics.builder: operator-sdk-v1.32.0 + operators.operatorframework.io.metrics.builder: operator-sdk-v1.31.0 operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 7b688916f..d6f3d88fe 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -148,7 +148,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -156,7 +156,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -183,25 +183,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -212,7 +212,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -227,9 +227,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -238,7 +238,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -251,7 +251,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -260,9 +260,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -277,20 +277,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -321,30 +321,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -357,7 +357,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -367,8 +367,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -404,20 +404,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -425,13 +426,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -462,7 +463,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -470,7 +471,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -497,25 +498,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -526,7 +527,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -541,9 +542,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -552,7 +553,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -565,7 +566,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -574,9 +575,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -591,20 +592,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -635,30 +636,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -671,7 +672,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -681,8 +682,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -718,20 +719,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -739,13 +741,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -776,7 +778,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -784,7 +786,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -811,25 +813,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -840,7 +842,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -855,9 +857,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -866,7 +868,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -879,7 +881,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -888,9 +890,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -905,20 +907,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -949,30 +951,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -985,7 +987,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -995,8 +997,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -1032,20 +1034,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -1053,13 +1056,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -1169,7 +1172,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object schedulingOptions: @@ -2222,8 +2226,9 @@ spec: defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". + configured seccomp profile location. Must be set + if type is "Localhost". Must NOT be set for any + other type. type: string type: description: "type indicates which kind of seccomp @@ -2291,15 +2296,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork + of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -2432,8 +2433,9 @@ spec: defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". + configured seccomp profile location. Must be set + if type is "Localhost". Must NOT be set for any + other type. type: string type: description: "type indicates which kind of seccomp @@ -2466,15 +2468,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork + of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -2545,7 +2543,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object dataSourceResources: @@ -2593,7 +2592,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object grafanaResources: @@ -2641,7 +2641,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object type: object @@ -3684,7 +3685,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -3716,15 +3718,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -3853,7 +3852,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -3885,15 +3885,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4021,7 +4018,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -4053,15 +4051,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4189,7 +4184,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -4221,15 +4217,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4330,7 +4323,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -4395,15 +4389,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4531,7 +4522,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -4563,15 +4555,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -4892,7 +4881,8 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: @@ -5220,7 +5210,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -5228,7 +5218,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -5255,25 +5245,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -5284,7 +5274,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -5299,9 +5289,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -5310,7 +5300,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -5323,7 +5313,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -5332,9 +5322,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -5349,20 +5339,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -5393,30 +5383,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -5429,7 +5419,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -5439,8 +5429,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -5476,20 +5466,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -5497,13 +5488,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -5534,7 +5525,7 @@ spec: between ingresses/services. properties: defaultBackend: - description: DefaultBackend is the backend that should + description: defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests @@ -5542,7 +5533,7 @@ spec: Ingress controller. properties: resource: - description: Resource is an ObjectRef to another Kubernetes + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive @@ -5569,25 +5560,25 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a Service as a Backend. + description: service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced service. The + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced service. A + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name of the port + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the numerical port + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with "Name". format: int32 @@ -5598,7 +5589,7 @@ spec: type: object type: object ingressClassName: - description: IngressClassName is the name of an IngressClass + description: ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller @@ -5613,9 +5604,9 @@ spec: honor that annotation if present. type: string rules: - description: A list of host rules used to configure the - Ingress. If unspecified, or no rule matches, all traffic - is sent to the default backend. + description: rules is a list of host rules used to configure + the Ingress. If unspecified, or no rule matches, all + traffic is sent to the default backend. items: description: IngressRule represents the rules mapping the paths under a specified host to the related backend @@ -5624,7 +5615,7 @@ spec: with the matching IngressRuleValue. properties: host: - description: "Host is the fully qualified domain + description: "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs @@ -5637,7 +5628,7 @@ spec: Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified - IngressRuleValue. \n Host can be \"precise\" which + IngressRuleValue. \n host can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single @@ -5646,9 +5637,9 @@ spec: DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the - Host field in the following way: 1. If Host is + Host field in the following way: 1. If host is precise, the request matches this rule if the - http host header is equal to Host. 2. If Host + http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule." @@ -5663,20 +5654,20 @@ spec: or ''#''.' properties: paths: - description: A collection of paths that map - requests to backends. + description: paths is a collection of paths + that map requests to backends. items: description: HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend. properties: backend: - description: Backend defines the referenced + description: backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: Resource is an ObjectRef + description: resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name @@ -5707,30 +5698,30 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: Service references a - Service as a Backend. This is a + description: service references a + service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: Name is the referenced + description: name is the referenced service. The service must exist in the same namespace as the Ingress object. type: string port: - description: Port of the referenced + description: port of the referenced service. A port name or port number is required for a IngressServiceBackend. properties: name: - description: Name is the name + description: name is the name of the port on the Service. This is a mutually exclusive setting with "Number". type: string number: - description: Number is the + description: number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive @@ -5743,7 +5734,7 @@ spec: type: object type: object path: - description: Path is matched against the + description: path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional "path" part of @@ -5753,8 +5744,8 @@ spec: or "Prefix". type: string pathType: - description: 'PathType determines the - interpretation of the Path matching. + description: 'pathType determines the + interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on @@ -5790,20 +5781,21 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. + description: tls represents the TLS configuration. Currently + the Ingress only supports a single TLS port, 443. If + multiple members of this list specify different hosts, + they will be multiplexed on the same port according + to the hostname specified through the SNI TLS extension, + if the ingress controller fulfilling the ingress supports + SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -5811,13 +5803,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -5927,7 +5919,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object schedulingOptions: @@ -6980,8 +6973,9 @@ spec: defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". + configured seccomp profile location. Must be set + if type is "Localhost". Must NOT be set for any + other type. type: string type: description: "type indicates which kind of seccomp @@ -7049,15 +7043,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork + of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -7190,8 +7180,9 @@ spec: defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must only be - set if type is "Localhost". + configured seccomp profile location. Must be set + if type is "Localhost". Must NOT be set for any + other type. type: string type: description: "type indicates which kind of seccomp @@ -7224,15 +7215,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored by - components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. - All of a Pod's containers must have the same effective + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). In - addition, if HostProcess is true then HostNetwork + of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -7303,7 +7290,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object dataSourceResources: @@ -7351,7 +7339,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object grafanaResources: @@ -7399,7 +7388,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object type: object @@ -8442,7 +8432,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -8474,15 +8465,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -8611,7 +8599,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -8643,15 +8632,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -8779,7 +8765,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -8811,15 +8798,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -8947,7 +8931,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -8979,15 +8964,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -9088,7 +9070,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -9153,15 +9136,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -9289,7 +9269,8 @@ spec: in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile - location. Must only be set if type is "Localhost". + location. Must be set if type is "Localhost". Must NOT + be set for any other type. type: string type: description: "type indicates which kind of seccomp profile @@ -9321,15 +9302,12 @@ spec: type: string hostProcess: description: HostProcess determines if a container should - be run as a 'Host Process' container. This field is - alpha-level and will only be honored by components that - enable the WindowsHostProcessContainers feature flag. - Setting this field without the feature flag will result - in errors when validating the Pod. All of a Pod's containers - must have the same effective HostProcess value (it is - not allowed to have a mix of HostProcess containers - and non-HostProcess containers). In addition, if HostProcess - is true then HostNetwork must also be set to true. + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. type: boolean runAsUserName: description: The UserName in Windows to run the entrypoint @@ -9624,7 +9602,8 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 277a0b7df..a8788a81e 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -49,7 +49,7 @@ spec: env: - name: WATCH_NAMESPACE value: "" - - name: NAMESPACE + - name: OPERATOR_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index c5fd8c9d5..de327d0f2 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -305,7 +305,7 @@ spec: - description: Security Context to apply to the JFR Data Source container. displayName: Data Source Security Context path: securityOptions.dataSourceSecurityContext - - description: Security Context to apply to the storage container. + - description: Security Context to apply to the database container. displayName: Database Security Context path: securityOptions.databaseSecurityContext - description: Security Context to apply to the Grafana container. diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index ed997e797..cbdf8900e 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -5,15 +5,6 @@ metadata: creationTimestamp: null name: role rules: -- apiGroups: - - "" - resources: - - configmaps - - configmaps/finalizers - - secrets - - services - verbs: - - '*' - apiGroups: - "" resources: @@ -43,19 +34,22 @@ rules: verbs: - get - apiGroups: - - apps + - "" + resourceNames: + - pull-secret resources: - - daemonsets - - deployments - - replicasets - - statefulsets + - secrets verbs: - - '*' + - get + - list + - watch - apiGroups: - apps resources: + - daemonsets - deployments - - deployments/finalizers + - replicasets + - statefulsets verbs: - '*' - apiGroups: @@ -192,6 +186,40 @@ metadata: name: role namespace: system rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - update + - watch +- apiGroups: + - "" + resources: + - configmaps/finalizers + - secrets + - services + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - apps + resources: + - deployments + - deployments/finalizers + verbs: + - create + - get + - list + - update + - watch - apiGroups: - monitoring.coreos.com resources: diff --git a/config/samples/sample-app-agent.yaml b/config/samples/sample-app-agent.yaml index 5969ce47c..d3cf7ca7c 100644 --- a/config/samples/sample-app-agent.yaml +++ b/config/samples/sample-app-agent.yaml @@ -42,6 +42,12 @@ spec: name: cryostat-sample-keystore - name: JAVA_OPTS_APPEND value: |- + -Dquarkus.http.host=0.0.0.0 + -Djava.util.logging.manager=org.jboss.logmanager.LogManager + -Dcom.sun.management.jmxremote.port=9097 + -Dcom.sun.management.jmxremote.ssl=false + -Dcom.sun.management.jmxremote.authenticate=false + -javaagent:/deployments/app/cryostat-agent.jar -Djavax.net.ssl.trustStore=/var/run/secrets/myapp/truststore.p12 -Djavax.net.ssl.trustStorePassword=$(KEYSTORE_PASS) image: quay.io/andrewazores/quarkus-test:latest diff --git a/go.mod b/go.mod index db9c8957d..315b827e3 100644 --- a/go.mod +++ b/go.mod @@ -3,87 +3,82 @@ module github.com/cryostatio/cryostat-operator go 1.21 require ( + github.com/RedHatInsights/runtimes-inventory-operator v0.0.0-20240327135922-5705da62073c github.com/blang/semver/v4 v4.0.0 - github.com/cert-manager/cert-manager v1.11.5 - github.com/go-logr/logr v1.3.0 + github.com/cert-manager/cert-manager v1.13.5 + github.com/go-logr/logr v1.4.1 github.com/google/go-cmp v0.6.0 - github.com/onsi/ginkgo/v2 v2.6.1 - github.com/onsi/gomega v1.24.2 - github.com/openshift/api v0.0.0-20230406152840-ce21e3fe5da2 // release-4.15 - github.com/operator-framework/api v0.17.3 - k8s.io/api v0.26.10 - k8s.io/apimachinery v0.26.10 - k8s.io/client-go v0.26.10 - sigs.k8s.io/controller-runtime v0.14.7 + github.com/onsi/ginkgo/v2 v2.17.1 + github.com/onsi/gomega v1.33.0 + 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.9 + k8s.io/apimachinery v0.28.9 + k8s.io/client-go v0.28.9 + sigs.k8s.io/controller-runtime v0.16.5 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.9.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.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/swag v0.19.14 // 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/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/gnostic v0.6.9 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.6 // 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.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - github.com/sirupsen/logrus v1.9.0 // 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/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.4.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // 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.23.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + golang.org/x/tools v0.17.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/protobuf v1.33.0 // 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.26.10 // indirect - k8s.io/component-base v0.26.10 // indirect - k8s.io/klog/v2 v2.80.1 // indirect - k8s.io/kube-openapi v0.0.0-20221207184640-f3cff1453715 // indirect - k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 // indirect - sigs.k8s.io/gateway-api v0.6.0 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + k8s.io/apiextensions-apiserver v0.28.4 // indirect + k8s.io/component-base v0.28.4 // 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 + 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 ) -// Fix for CVE-2020-26160 -replace github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt v3.2.1+incompatible - // Fix for CVE-2022-28948 replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 - -// Fix for CVE-2021-3121 -replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 - -// Fix for CVE-2022-1996 -replace github.com/emicklei/go-restful => github.com/emicklei/go-restful v2.16.0+incompatible diff --git a/go.sum b/go.sum index 0460050f6..385cde0b4 100644 --- a/go.sum +++ b/go.sum @@ -1,659 +1,246 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/RedHatInsights/runtimes-inventory-operator v0.0.0-20240327135922-5705da62073c h1:Dl3eCF6o2IUMzIi+V0RpZIii2nOUFPWI3gB/ZE2TcZY= +github.com/RedHatInsights/runtimes-inventory-operator v0.0.0-20240327135922-5705da62073c/go.mod h1:DhoPtaJhm/8OOJjp8lrDJAmdMsjo4mDJBzHYvChegnM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +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/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cert-manager/cert-manager v1.11.5 h1:K2LurvwIE4hIhODQZnkOW6ljYe3lVMAliS/to+gI05o= -github.com/cert-manager/cert-manager v1.11.5/go.mod h1:zNOyoTEwdn9Rtj5Or2pjBY1Bqwtw4vBElP2fKSP8/g8= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cert-manager/cert-manager v1.13.5 h1:kSO9FnOQEuIox5FbtZnxWSSlYUV+7nBprL+U43YSnO0= +github.com/cert-manager/cert-manager v1.13.5/go.mod h1:4+c8TrwH3Q809Zxv6f8sgVbzdNcgOCl3sd55pr7r/EI= 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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +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/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= -github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/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-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 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.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= -github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +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= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 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/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/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 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/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +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.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +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= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/onsi/ginkgo/v2 v2.6.1 h1:1xQPCjcqYw/J5LchOcp4/2q/jzJFjiAOc25chhnDw+Q= -github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/gomega v1.24.2 h1:J/tulyYK6JwBldPViHJReihxxZ+22FHs0piGjQAvoUE= -github.com/onsi/gomega v1.24.2/go.mod h1:gs3J10IS7Z7r7eXRoNJIrNqU4ToQukCJhFtKrWgHWnk= -github.com/openshift/api v0.0.0-20230406152840-ce21e3fe5da2 h1:lpKBKpI8or60mSEEKrpS67cevp8XaW8vfmXSwCZXKd0= -github.com/openshift/api v0.0.0-20230406152840-ce21e3fe5da2/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= -github.com/operator-framework/api v0.17.3 h1:wddE1SLKTNiIzwt28DbBIO+vPG2GOV6dkB9xBkDfT3o= -github.com/operator-framework/api v0.17.3/go.mod h1:34tb98EwTN5SZLkgoxwvRkhMJKLHUWHOrrcv1ZwvEeA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= +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/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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +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/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/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +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/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +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/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +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/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +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= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +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/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 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.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +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/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/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.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= 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.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= -gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +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.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.26.10 h1:skTnrDR0r8dg4MMLf6YZIzugxNM0BjFsWKPkNc5kOvk= -k8s.io/api v0.26.10/go.mod h1:ou/H3yviqrHtP/DSPVTfsc7qNfmU06OhajytJfYXkXw= -k8s.io/apiextensions-apiserver v0.26.10 h1:wAriTUc6l7gUqJKOxhmXnYo/VNJzk4oh4QLCUR4Uq+k= -k8s.io/apiextensions-apiserver v0.26.10/go.mod h1:N2qhlxkhJLSoC4f0M1/1lNG627b45SYqnOPEVFoQXw4= -k8s.io/apimachinery v0.26.10 h1:aE+J2KIbjctFqPp3Y0q4Wh2PD+l1p2g3Zp4UYjSvtGU= -k8s.io/apimachinery v0.26.10/go.mod h1:iT1ZP4JBP34wwM+ZQ8ByPEQ81u043iqAcsJYftX9amM= -k8s.io/client-go v0.26.10 h1:4mDzl+1IrfRxh4Ro0s65JRGJp14w77gSMUTjACYWVRo= -k8s.io/client-go v0.26.10/go.mod h1:sh74ig838gCckU4ElYclWb24lTesPdEDPnlyg5vcbkA= -k8s.io/component-base v0.26.10 h1:vl3Gfe5aC09mNxfnQtTng7u3rnBVrShOK3MAkqEleb0= -k8s.io/component-base v0.26.10/go.mod h1:/IDdENUHG5uGxqcofZajovYXE9KSPzJ4yQbkYQt7oN0= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20221207184640-f3cff1453715 h1:tBEbstoM+K0FiBV5KGAKQ0kuvf54v/hwpldiJt69w1s= -k8s.io/kube-openapi v0.0.0-20221207184640-f3cff1453715/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= -k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.14.7 h1:Vrnm2vk9ZFlRkXATHz0W0wXcqNl7kPat8q2JyxVy0Q8= -sigs.k8s.io/controller-runtime v0.14.7/go.mod h1:ErTs3SJCOujNUnTz4AS+uh8hp6DHMo1gj6fFndJT1X8= -sigs.k8s.io/gateway-api v0.6.0 h1:v2FqrN2ROWZLrSnI2o91taHR8Sj3s+Eh3QU7gLNWIqA= -sigs.k8s.io/gateway-api v0.6.0/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +k8s.io/api v0.28.9 h1:E7VEXXCAlSrp+08zq4zgd+ko6Ttu0Mw+XoXlIkDTVW0= +k8s.io/api v0.28.9/go.mod h1:AnCsDYf3SHjfa8mPG5LGYf+iF4mie+3peLQR51MMCgw= +k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU= +k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM= +k8s.io/apimachinery v0.28.9 h1:aXz4Zxsw+Pk4KhBerAtKRxNN1uSMWKfciL/iOdBfXvA= +k8s.io/apimachinery v0.28.9/go.mod h1:zUG757HaKs6Dc3iGtKjzIpBfqTM4yiRsEe3/E7NX15o= +k8s.io/client-go v0.28.9 h1:mmMvejwc/KDjMLmDpyaxkWNzlWRCJ6ht7Qsbsnwn39Y= +k8s.io/client-go v0.28.9/go.mod h1:GFDy3rUNId++WGrr0hRaBrs+y1eZz5JtVZODEalhRMo= +k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo= +k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU= +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.5 h1:yr1cEJbX08xsTW6XEIzT13KHHmIyX8Umvme2cULvFZw= +sigs.k8s.io/controller-runtime v0.16.5/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= +sigs.k8s.io/gateway-api v0.8.0 h1:isQQ3Jx2qFP7vaA3ls0846F0Amp9Eq14P08xbSwVbQg= +sigs.k8s.io/gateway-api v0.8.0/go.mod h1:okOnjPNBFbIS/Rw9kAhuIUaIkLhTKEu+ARIuXk2dgaM= +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= diff --git a/internal/controllers/cryostat_controller.go b/internal/controllers/cryostat_controller.go index 37541e6b1..8a4042bf2 100644 --- a/internal/controllers/cryostat_controller.go +++ b/internal/controllers/cryostat_controller.go @@ -69,6 +69,14 @@ func NewCryostatReconciler(config *ReconcilerConfig) (*CryostatReconciler, error // +kubebuilder:rbac:groups=console.openshift.io,resources=consolelinks,verbs=get;create;list;update;delete // +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=* +// RBAC for Insights controller, remove these when moving to a separate container +// +kubebuilder:rbac:namespace=system,groups=apps,resources=deployments;deployments/finalizers,verbs=create;update;get;list;watch +// +kubebuilder:rbac:namespace=system,groups="",resources=services;secrets;configmaps/finalizers,verbs=create;update;get;list;watch +// +kubebuilder:rbac:namespace=system,groups="",resources=configmaps,verbs=create;update;delete;get;list;watch +// +kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions,verbs=get;list;watch +// OLM doesn't let us specify RBAC for openshift-config namespace, so we need a cluster-wide permission +// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch,resourceNames=pull-secret + // Reconcile processes a Cryostat CR and manages a Cryostat installation accordingly func (r *CryostatReconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { reqLogger := r.Log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name) diff --git a/internal/controllers/insights/apicast.go b/internal/controllers/insights/apicast.go deleted file mode 100644 index 8ae5ade4f..000000000 --- a/internal/controllers/insights/apicast.go +++ /dev/null @@ -1,104 +0,0 @@ -// 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 insights - -import ( - "bytes" - "text/template" -) - -type apiCastConfigParams struct { - FrontendDomains string - BackendInsightsDomain string - HeaderValue string - UserAgent string - ProxyDomain string -} - -var apiCastConfigTemplate = template.Must(template.New("").Parse(`{ - "services": [ - { - "id": "1", - "backend_version": "1", - "proxy": { - "hosts": [{{ .FrontendDomains }}], - "api_backend": "https://{{ .BackendInsightsDomain }}:443/", - "backend": { "endpoint": "http://127.0.0.1:8081", "host": "backend" }, - "policy_chain": [ - { - "name": "default_credentials", - "version": "builtin", - "configuration": { - "auth_type": "user_key", - "user_key": "dummy_key" - } - }, - {{- if .ProxyDomain }} - { - "name": "apicast.policy.http_proxy", - "configuration": { - "https_proxy": "http://{{ .ProxyDomain }}/", - "http_proxy": "http://{{ .ProxyDomain }}/" - } - }, - {{- end }} - { - "name": "headers", - "version": "builtin", - "configuration": { - "request": [ - { - "op": "set", - "header": "Authorization", - "value_type": "plain", - "value": "Bearer {{ .HeaderValue }}" - }, - { - "op": "set", - "header": "User-Agent", - "value_type": "plain", - "value": "{{ .UserAgent }}" - } - ] - } - }, - { - "name": "apicast.policy.apicast" - } - ], - "proxy_rules": [ - { - "http_method": "POST", - "pattern": "/", - "metric_system_name": "hits", - "delta": 1, - "parameters": [], - "querystring_parameters": {} - } - ] - } - } - ] -}`)) - -func getAPICastConfig(params *apiCastConfigParams) (*string, error) { - buf := &bytes.Buffer{} - err := apiCastConfigTemplate.Execute(buf, params) - if err != nil { - return nil, err - } - result := buf.String() - return &result, nil -} diff --git a/internal/controllers/insights/insights.go b/internal/controllers/insights/insights.go deleted file mode 100644 index 5d500442c..000000000 --- a/internal/controllers/insights/insights.go +++ /dev/null @@ -1,375 +0,0 @@ -// 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 insights - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "strings" - - "github.com/cryostatio/cryostat-operator/internal/controllers" - "github.com/cryostatio/cryostat-operator/internal/controllers/common" - "github.com/cryostatio/cryostat-operator/internal/controllers/constants" - configv1 "github.com/openshift/api/config/v1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -func (r *InsightsReconciler) reconcileInsights(ctx context.Context) error { - err := r.reconcilePullSecret(ctx) - if err != nil { - return err - } - err = r.reconcileProxyDeployment(ctx) - if err != nil { - return err - } - return r.reconcileProxyService(ctx) -} - -func (r *InsightsReconciler) reconcilePullSecret(ctx context.Context) error { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: ProxySecretName, - Namespace: r.Namespace, - }, - } - owner := &corev1.ConfigMap{} - err := r.Client.Get(ctx, types.NamespacedName{Name: InsightsConfigMapName, - Namespace: r.Namespace}, owner) - if err != nil { - return err - } - - token, err := r.getTokenFromPullSecret(ctx) - if err != nil { - return err - } - - userAgent, err := r.getUserAgentString(ctx) - if err != nil { - return err - } - - params := &apiCastConfigParams{ - FrontendDomains: fmt.Sprintf("\"%s\",\"%s.%s.svc.cluster.local\"", ProxyServiceName, ProxyServiceName, r.Namespace), - BackendInsightsDomain: r.backendDomain, - ProxyDomain: r.proxyDomain, - HeaderValue: *token, - UserAgent: *userAgent, - } - config, err := getAPICastConfig(params) - if err != nil { - return err - } - - return r.createOrUpdateProxySecret(ctx, secret, owner, *config) -} - -func (r *InsightsReconciler) reconcileProxyDeployment(ctx context.Context) error { - deploy := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: ProxyDeploymentName, - Namespace: r.Namespace, - }, - } - owner := &corev1.ConfigMap{} - err := r.Client.Get(ctx, types.NamespacedName{Name: InsightsConfigMapName, - Namespace: r.Namespace}, owner) - if err != nil { - return err - } - - return r.createOrUpdateProxyDeployment(ctx, deploy, owner) -} - -func (r *InsightsReconciler) reconcileProxyService(ctx context.Context) error { - svc := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: ProxyServiceName, - Namespace: r.Namespace, - }, - } - owner := &corev1.ConfigMap{} - err := r.Client.Get(ctx, types.NamespacedName{Name: InsightsConfigMapName, - Namespace: r.Namespace}, owner) - if err != nil { - return err - } - - return r.createOrUpdateProxyService(ctx, svc, owner) -} - -func (r *InsightsReconciler) getTokenFromPullSecret(ctx context.Context) (*string, error) { - // Get the global pull secret - pullSecret := &corev1.Secret{} - err := r.Client.Get(ctx, types.NamespacedName{Namespace: "openshift-config", Name: "pull-secret"}, pullSecret) - if err != nil { - return nil, err - } - - // Look for the .dockerconfigjson key within it - dockerConfigRaw, pres := pullSecret.Data[corev1.DockerConfigJsonKey] - if !pres { - return nil, fmt.Errorf("no %s key present in pull secret", corev1.DockerConfigJsonKey) - } - - // Unmarshal the .dockerconfigjson into a struct - dockerConfig := struct { - Auths map[string]struct { - Auth string `json:"auth"` - } `json:"auths"` - }{} - err = json.Unmarshal(dockerConfigRaw, &dockerConfig) - if err != nil { - return nil, err - } - - // Look for the "cloud.openshift.com" auth - openshiftAuth, pres := dockerConfig.Auths["cloud.openshift.com"] - if !pres { - return nil, errors.New("no \"cloud.openshift.com\" auth within pull secret") - } - - token := strings.TrimSpace(openshiftAuth.Auth) - if strings.Contains(token, "\n") || strings.Contains(token, "\r") { - return nil, fmt.Errorf("invalid cloud.openshift.com token") - } - return &token, nil -} - -func (r *InsightsReconciler) getUserAgentString(ctx context.Context) (*string, error) { - cv := &configv1.ClusterVersion{} - err := r.Client.Get(ctx, types.NamespacedName{Name: "version"}, cv) - if err != nil { - return nil, err - } - - userAgent := fmt.Sprintf("cryostat-operator/%s cluster/%s", controllers.OperatorVersion, cv.Spec.ClusterID) - return &userAgent, nil -} - -func (r *InsightsReconciler) createOrUpdateProxySecret(ctx context.Context, secret *corev1.Secret, owner metav1.Object, - config string) error { - op, err := controllerutil.CreateOrUpdate(ctx, r.Client, secret, func() error { - // Set the config map as controller - if err := controllerutil.SetControllerReference(owner, secret, r.Scheme); err != nil { - return err - } - // Add the APICast config.json - if secret.StringData == nil { - secret.StringData = map[string]string{} - } - secret.StringData["config.json"] = config - return nil - }) - if err != nil { - return err - } - r.Log.Info(fmt.Sprintf("Secret %s", op), "name", secret.Name, "namespace", secret.Namespace) - return nil -} - -func (r *InsightsReconciler) createOrUpdateProxyDeployment(ctx context.Context, deploy *appsv1.Deployment, owner metav1.Object) error { - op, err := controllerutil.CreateOrUpdate(ctx, r.Client, deploy, func() error { - labels := map[string]string{"app": ProxyDeploymentName} - annotations := map[string]string{} - common.MergeLabelsAndAnnotations(&deploy.ObjectMeta, labels, annotations) - // Set the config map as controller - if err := controllerutil.SetControllerReference(owner, deploy, r.Scheme); err != nil { - return err - } - // Immutable, only updated when the deployment is created - if deploy.CreationTimestamp.IsZero() { - // Selector is immutable, avoid modifying if possible - deploy.Spec.Selector = &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "app": ProxyDeploymentName, - }, - } - } - - // Update pod template spec - r.createOrUpdateProxyPodSpec(deploy) - // Update pod template metadata - common.MergeLabelsAndAnnotations(&deploy.Spec.Template.ObjectMeta, labels, annotations) - return nil - }) - if err != nil { - return err - } - r.Log.Info(fmt.Sprintf("Deployment %s", op), "name", deploy.Name, "namespace", deploy.Namespace) - return nil -} - -func (r *InsightsReconciler) createOrUpdateProxyService(ctx context.Context, svc *corev1.Service, owner metav1.Object) error { - op, err := controllerutil.CreateOrUpdate(ctx, r.Client, svc, func() error { - // Update labels and annotations - labels := map[string]string{"app": ProxyDeploymentName} - annotations := map[string]string{} - common.MergeLabelsAndAnnotations(&svc.ObjectMeta, labels, annotations) - - // Set the config map as controller - if err := controllerutil.SetControllerReference(owner, svc, r.Scheme); err != nil { - return err - } - // Update the service type - svc.Spec.Type = corev1.ServiceTypeClusterIP - svc.Spec.Selector = map[string]string{ - "app": ProxyDeploymentName, - } - svc.Spec.Ports = []corev1.ServicePort{ - { - Name: "proxy", - Port: ProxyServicePort, - TargetPort: intstr.FromString("proxy"), - }, - { - Name: "management", - Port: 8090, - TargetPort: intstr.FromString("management"), - }, - } - return nil - }) - if err != nil { - return err - } - r.Log.Info(fmt.Sprintf("Service %s", op), "name", svc.Name, "namespace", svc.Namespace) - return nil -} - -const ( - defaultProxyCPURequest = "50m" - defaultProxyCPULimit = "200m" - defaultProxyMemRequest = "64Mi" - defaultProxyMemLimit = "128Mi" -) - -func (r *InsightsReconciler) createOrUpdateProxyPodSpec(deploy *appsv1.Deployment) { - privEscalation := false - nonRoot := true - readOnlyMode := int32(0440) - - podSpec := &deploy.Spec.Template.Spec - // Create the container if it doesn't exist - var container *corev1.Container - if deploy.CreationTimestamp.IsZero() { - podSpec.Containers = []corev1.Container{{}} - } - container = &podSpec.Containers[0] - - // Set fields that are hard-coded by operator - container.Name = ProxyDeploymentName - container.Image = r.proxyImageTag - container.Env = []corev1.EnvVar{ - { - Name: "THREESCALE_CONFIG_FILE", - Value: "/tmp/gateway-configuration-volume/config.json", - }, - } - container.VolumeMounts = []corev1.VolumeMount{ - { - Name: "gateway-configuration-volume", - MountPath: "/tmp/gateway-configuration-volume", - ReadOnly: true, - }, - } - container.Ports = []corev1.ContainerPort{ - { - Name: "proxy", - ContainerPort: ProxyServicePort, - }, - { - Name: "management", - ContainerPort: 8090, - }, - { - Name: "metrics", - ContainerPort: 9421, - }, - } - container.SecurityContext = &corev1.SecurityContext{ - AllowPrivilegeEscalation: &privEscalation, - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{constants.CapabilityAll}, - }, - } - container.LivenessProbe = &corev1.Probe{ - InitialDelaySeconds: 10, - TimeoutSeconds: 5, - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/status/live", - Port: intstr.FromInt(8090), - }, - }, - } - container.ReadinessProbe = &corev1.Probe{ - InitialDelaySeconds: 15, - PeriodSeconds: 30, - TimeoutSeconds: 5, - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/status/ready", - Port: intstr.FromInt(8090), - }, - }, - } - - // Set resource requirements only on creation, this allows - // the user to modify them if they wish - if deploy.CreationTimestamp.IsZero() { - container.Resources = corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse(defaultProxyCPURequest), - corev1.ResourceMemory: resource.MustParse(defaultProxyMemRequest), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse(defaultProxyCPULimit), - corev1.ResourceMemory: resource.MustParse(defaultProxyMemLimit), - }, - } - } - - podSpec.Volumes = []corev1.Volume{ // TODO detect change and redeploy - { - Name: "gateway-configuration-volume", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: ProxySecretName, - Items: []corev1.KeyToPath{ - { - Key: "config.json", - Path: "config.json", - Mode: &readOnlyMode, - }, - }, - }, - }, - }, - } - podSpec.SecurityContext = &corev1.PodSecurityContext{ - RunAsNonRoot: &nonRoot, - SeccompProfile: common.SeccompProfile(true), - } -} diff --git a/internal/controllers/insights/insights_controller.go b/internal/controllers/insights/insights_controller.go deleted file mode 100644 index 9e70969f4..000000000 --- a/internal/controllers/insights/insights_controller.go +++ /dev/null @@ -1,142 +0,0 @@ -// 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 insights - -import ( - "context" - "errors" - - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/cryostatio/cryostat-operator/internal/controllers/common" - "github.com/go-logr/logr" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -// InsightsReconciler reconciles the Insights proxy for Cryostat agents -type InsightsReconciler struct { - *InsightsReconcilerConfig - backendDomain string - proxyDomain string - proxyImageTag string -} - -// InsightsReconcilerConfig contains configuration to create an InsightsReconciler -type InsightsReconcilerConfig struct { - client.Client - Log logr.Logger - Scheme *runtime.Scheme - Namespace string - common.OSUtils -} - -const ( - InsightsConfigMapName = "insights-proxy" - ProxyDeploymentName = InsightsConfigMapName - ProxyServiceName = ProxyDeploymentName - ProxyServicePort = 8080 - ProxySecretName = "apicastconf" - EnvInsightsBackendDomain = "INSIGHTS_BACKEND_DOMAIN" - EnvInsightsProxyDomain = "INSIGHTS_PROXY_DOMAIN" - EnvInsightsEnabled = "INSIGHTS_ENABLED" - // Environment variable to override the Insights proxy image - EnvInsightsProxyImageTag = "RELATED_IMAGE_INSIGHTS_PROXY" -) - -// NewInsightsReconciler creates an InsightsReconciler using the provided configuration -func NewInsightsReconciler(config *InsightsReconcilerConfig) (*InsightsReconciler, error) { - backendDomain := config.GetEnv(EnvInsightsBackendDomain) - if len(backendDomain) == 0 { - return nil, errors.New("no backend domain provided for Insights") - } - imageTag := config.GetEnv(EnvInsightsProxyImageTag) - if len(imageTag) == 0 { - return nil, errors.New("no proxy image tag provided for Insights") - } - proxyDomain := config.GetEnv(EnvInsightsProxyDomain) - - return &InsightsReconciler{ - InsightsReconcilerConfig: config, - backendDomain: backendDomain, - proxyDomain: proxyDomain, - proxyImageTag: imageTag, - }, nil -} - -// +kubebuilder:rbac:groups=apps,resources=deployments;deployments/finalizers,verbs=* -// +kubebuilder:rbac:groups="",resources=services;secrets;configmaps;configmaps/finalizers,verbs=* -// +kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions,verbs=get;list;watch - -// Reconcile processes the Insights proxy deployment and configures it accordingly -func (r *InsightsReconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { - reqLogger := r.Log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name) - reqLogger.Info("Reconciling Insights Proxy") - - // Reconcile all Insights support - err := r.reconcileInsights(ctx) - if err != nil { - return reconcile.Result{}, err - } - return reconcile.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *InsightsReconciler) SetupWithManager(mgr ctrl.Manager) error { - c := ctrl.NewControllerManagedBy(mgr). - Named("insights"). - // Filter controller to watch only specific objects we care about - Watches(&source.Kind{Type: &corev1.Secret{}}, - handler.EnqueueRequestsFromMapFunc(r.isPullSecretOrProxyConfig)). - Watches(&source.Kind{Type: &appsv1.Deployment{}}, - handler.EnqueueRequestsFromMapFunc(r.isProxyDeployment)). - Watches(&source.Kind{Type: &corev1.Service{}}, - handler.EnqueueRequestsFromMapFunc(r.isProxyService)) - return c.Complete(r) -} - -func (r *InsightsReconciler) isPullSecretOrProxyConfig(secret client.Object) []reconcile.Request { - if !(secret.GetNamespace() == "openshift-config" && secret.GetName() == "pull-secret") && - !(secret.GetNamespace() == r.Namespace && secret.GetName() == ProxySecretName) { - return nil - } - return r.proxyDeploymentRequest() -} - -func (r *InsightsReconciler) isProxyDeployment(deploy client.Object) []reconcile.Request { - if deploy.GetNamespace() != r.Namespace || deploy.GetName() != ProxyDeploymentName { - return nil - } - return r.proxyDeploymentRequest() -} - -func (r *InsightsReconciler) isProxyService(svc client.Object) []reconcile.Request { - if svc.GetNamespace() != r.Namespace || svc.GetName() != ProxyServiceName { - return nil - } - return r.proxyDeploymentRequest() -} - -func (r *InsightsReconciler) proxyDeploymentRequest() []reconcile.Request { - req := reconcile.Request{NamespacedName: types.NamespacedName{Namespace: r.Namespace, Name: ProxyDeploymentName}} - return []reconcile.Request{req} -} diff --git a/internal/controllers/insights/insights_controller_test.go b/internal/controllers/insights/insights_controller_test.go deleted file mode 100644 index 7afd13f9c..000000000 --- a/internal/controllers/insights/insights_controller_test.go +++ /dev/null @@ -1,266 +0,0 @@ -// 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 insights_test - -import ( - "context" - - "github.com/cryostatio/cryostat-operator/internal/controllers/insights" - insightstest "github.com/cryostatio/cryostat-operator/internal/controllers/insights/test" - "github.com/cryostatio/cryostat-operator/internal/test" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -type insightsTestInput struct { - client ctrlclient.Client - controller *insights.InsightsReconciler - objs []ctrlclient.Object - *insightstest.TestUtilsConfig - *insightstest.InsightsTestResources -} - -var _ = Describe("InsightsController", func() { - var t *insightsTestInput - - Describe("reconciling a request", func() { - BeforeEach(func() { - t = &insightsTestInput{ - TestUtilsConfig: &insightstest.TestUtilsConfig{ - EnvInsightsEnabled: &[]bool{true}[0], - EnvInsightsBackendDomain: &[]string{"insights.example.com"}[0], - EnvInsightsProxyImageTag: &[]string{"example.com/proxy:latest"}[0], - }, - InsightsTestResources: &insightstest.InsightsTestResources{ - TestResources: &test.TestResources{ - Namespace: "test", - }, - }, - } - t.objs = []ctrlclient.Object{ - t.NewNamespace(), - t.NewGlobalPullSecret(), - t.NewClusterVersion(), - t.NewOperatorDeployment(), - t.NewProxyConfigMap(), - } - }) - - JustBeforeEach(func() { - s := test.NewTestScheme() - logger := zap.New() - logf.SetLogger(logger) - - // Set a CreationTimestamp for created objects to match a real API server - // TODO When using envtest instead of fake client, this is probably no longer needed - err := test.SetCreationTimestamp(t.objs...) - Expect(err).ToNot(HaveOccurred()) - t.client = fake.NewClientBuilder().WithScheme(s).WithObjects(t.objs...).Build() - - config := &insights.InsightsReconcilerConfig{ - Client: test.NewClientWithTimestamp(test.NewTestClient(t.client, t.TestResources)), - Scheme: s, - Log: logger, - Namespace: t.Namespace, - OSUtils: insightstest.NewTestOSUtils(t.TestUtilsConfig), - } - t.controller, err = insights.NewInsightsReconciler(config) - Expect(err).ToNot(HaveOccurred()) - }) - - Context("successfully creates required resources", func() { - Context("with defaults", func() { - JustBeforeEach(func() { - result, err := t.reconcile() - Expect(err).ToNot(HaveOccurred()) - Expect(result).To(Equal(reconcile.Result{})) - }) - It("should create the APICast config secret", func() { - expected := t.NewInsightsProxySecret() - actual := &corev1.Secret{} - err := t.client.Get(context.Background(), types.NamespacedName{ - Name: expected.Name, - Namespace: expected.Namespace, - }, actual) - Expect(err).ToNot(HaveOccurred()) - - Expect(actual.Labels).To(Equal(expected.Labels)) - Expect(actual.Annotations).To(Equal(expected.Annotations)) - Expect(metav1.IsControlledBy(actual, t.NewProxyConfigMap())).To(BeTrue()) - Expect(actual.StringData).To(HaveLen(1)) - Expect(actual.StringData).To(HaveKey("config.json")) - Expect(actual.StringData["config.json"]).To(MatchJSON(expected.StringData["config.json"])) - }) - It("should create the proxy deployment", func() { - expected := t.NewInsightsProxyDeployment() - actual := &appsv1.Deployment{} - err := t.client.Get(context.Background(), types.NamespacedName{ - Name: expected.Name, - Namespace: expected.Namespace, - }, actual) - Expect(err).ToNot(HaveOccurred()) - - t.checkProxyDeployment(actual, expected) - }) - It("should create the proxy service", func() { - expected := t.NewInsightsProxyService() - actual := &corev1.Service{} - err := t.client.Get(context.Background(), types.NamespacedName{ - Name: expected.Name, - Namespace: expected.Namespace, - }, actual) - Expect(err).ToNot(HaveOccurred()) - - Expect(actual.Labels).To(Equal(expected.Labels)) - Expect(actual.Annotations).To(Equal(expected.Annotations)) - Expect(metav1.IsControlledBy(actual, t.NewProxyConfigMap())).To(BeTrue()) - - Expect(actual.Spec.Selector).To(Equal(expected.Spec.Selector)) - Expect(actual.Spec.Type).To(Equal(expected.Spec.Type)) - Expect(actual.Spec.Ports).To(ConsistOf(expected.Spec.Ports)) - }) - }) - Context("with a proxy domain", func() { - BeforeEach(func() { - t.EnvInsightsProxyDomain = &[]string{"proxy.example.com"}[0] - }) - JustBeforeEach(func() { - result, err := t.reconcile() - Expect(err).ToNot(HaveOccurred()) - Expect(result).To(Equal(reconcile.Result{})) - }) - It("should create the APICast config secret", func() { - expected := t.NewInsightsProxySecretWithProxyDomain() - actual := &corev1.Secret{} - err := t.client.Get(context.Background(), types.NamespacedName{ - Name: expected.Name, - Namespace: expected.Namespace, - }, actual) - Expect(err).ToNot(HaveOccurred()) - - Expect(actual.Labels).To(Equal(expected.Labels)) - Expect(actual.Annotations).To(Equal(expected.Annotations)) - Expect(metav1.IsControlledBy(actual, t.NewProxyConfigMap())).To(BeTrue()) - Expect(actual.StringData).To(HaveLen(1)) - Expect(actual.StringData).To(HaveKey("config.json")) - Expect(actual.StringData["config.json"]).To(MatchJSON(expected.StringData["config.json"])) - }) - }) - }) - Context("updating the deployment", func() { - BeforeEach(func() { - t.objs = append(t.objs, - t.NewInsightsProxyDeployment(), - t.NewInsightsProxySecret(), - t.NewInsightsProxyService(), - ) - }) - Context("with resource requirements", func() { - var resources *corev1.ResourceRequirements - - BeforeEach(func() { - resources = &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("100m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("256Mi"), - }, - } - }) - JustBeforeEach(func() { - // Fetch the deployment - deploy := t.getProxyDeployment() - - // Change the resource requirements - deploy.Spec.Template.Spec.Containers[0].Resources = *resources - - // Update the deployment - err := t.client.Update(context.Background(), deploy) - Expect(err).ToNot(HaveOccurred()) - - // Reconcile again - result, err := t.reconcile() - Expect(err).ToNot(HaveOccurred()) - Expect(result).To(Equal(reconcile.Result{})) - }) - It("should leave the custom resource requirements", func() { - // Fetch the deployment again - actual := t.getProxyDeployment() - - // Check only resource requirements differ from defaults - t.Resources = resources - expected := t.NewInsightsProxyDeployment() - t.checkProxyDeployment(actual, expected) - }) - }) - }) - }) -}) - -func (t *insightsTestInput) reconcile() (reconcile.Result, error) { - req := reconcile.Request{NamespacedName: types.NamespacedName{Name: "insights-proxy", Namespace: t.Namespace}} - return t.controller.Reconcile(context.Background(), req) -} - -func (t *insightsTestInput) getProxyDeployment() *appsv1.Deployment { - deploy := t.NewInsightsProxyDeployment() - err := t.client.Get(context.Background(), types.NamespacedName{ - Name: deploy.Name, - Namespace: deploy.Namespace, - }, deploy) - Expect(err).ToNot(HaveOccurred()) - return deploy -} - -func (t *insightsTestInput) checkProxyDeployment(actual, expected *appsv1.Deployment) { - Expect(actual.Labels).To(Equal(expected.Labels)) - Expect(actual.Annotations).To(Equal(expected.Annotations)) - Expect(metav1.IsControlledBy(actual, t.NewProxyConfigMap())).To(BeTrue()) - Expect(actual.Spec.Selector).To(Equal(expected.Spec.Selector)) - - expectedTemplate := expected.Spec.Template - actualTemplate := actual.Spec.Template - Expect(actualTemplate.Labels).To(Equal(expectedTemplate.Labels)) - Expect(actualTemplate.Annotations).To(Equal(expectedTemplate.Annotations)) - Expect(actualTemplate.Spec.SecurityContext).To(Equal(expectedTemplate.Spec.SecurityContext)) - Expect(actualTemplate.Spec.Volumes).To(Equal(expectedTemplate.Spec.Volumes)) - - Expect(actualTemplate.Spec.Containers).To(HaveLen(1)) - expectedContainer := expectedTemplate.Spec.Containers[0] - actualContainer := actualTemplate.Spec.Containers[0] - Expect(actualContainer.Ports).To(ConsistOf(expectedContainer.Ports)) - Expect(actualContainer.Env).To(ConsistOf(expectedContainer.Env)) - Expect(actualContainer.EnvFrom).To(ConsistOf(expectedContainer.EnvFrom)) - Expect(actualContainer.VolumeMounts).To(ConsistOf(expectedContainer.VolumeMounts)) - Expect(actualContainer.LivenessProbe).To(Equal(expectedContainer.LivenessProbe)) - Expect(actualContainer.StartupProbe).To(Equal(expectedContainer.StartupProbe)) - Expect(actualContainer.SecurityContext).To(Equal(expectedContainer.SecurityContext)) - - test.ExpectResourceRequirements(&actualContainer.Resources, &expectedContainer.Resources) -} diff --git a/internal/controllers/insights/insights_controller_unit_test.go b/internal/controllers/insights/insights_controller_unit_test.go deleted file mode 100644 index ccaf682e2..000000000 --- a/internal/controllers/insights/insights_controller_unit_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// 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 insights - -import ( - insightstest "github.com/cryostatio/cryostat-operator/internal/controllers/insights/test" - "github.com/cryostatio/cryostat-operator/internal/test" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - - ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -type insightsUnitTestInput struct { - client ctrlclient.Client - controller *InsightsReconciler - objs []ctrlclient.Object - *insightstest.TestUtilsConfig - *insightstest.InsightsTestResources -} - -var _ = Describe("InsightsController", func() { - var t *insightsUnitTestInput - - Describe("configuring watches", func() { - - BeforeEach(func() { - t = &insightsUnitTestInput{ - TestUtilsConfig: &insightstest.TestUtilsConfig{ - EnvInsightsEnabled: &[]bool{true}[0], - EnvInsightsBackendDomain: &[]string{"insights.example.com"}[0], - EnvInsightsProxyImageTag: &[]string{"example.com/proxy:latest"}[0], - EnvNamespace: &[]string{"test"}[0], - }, - InsightsTestResources: &insightstest.InsightsTestResources{ - TestResources: &test.TestResources{ - Namespace: "test", - }, - }, - } - t.objs = []ctrlclient.Object{ - t.NewNamespace(), - t.NewGlobalPullSecret(), - t.NewOperatorDeployment(), - } - }) - - JustBeforeEach(func() { - s := test.NewTestScheme() - logger := zap.New() - logf.SetLogger(logger) - - // Set a CreationTimestamp for created objects to match a real API server - // TODO When using envtest instead of fake client, this is probably no longer needed - err := test.SetCreationTimestamp(t.objs...) - Expect(err).ToNot(HaveOccurred()) - t.client = fake.NewClientBuilder().WithScheme(s).WithObjects(t.objs...).Build() - - config := &InsightsReconcilerConfig{ - Client: test.NewClientWithTimestamp(test.NewTestClient(t.client, t.TestResources)), - Scheme: s, - Log: logger, - Namespace: t.Namespace, - OSUtils: insightstest.NewTestOSUtils(t.TestUtilsConfig), - } - t.controller, err = NewInsightsReconciler(config) - Expect(err).ToNot(HaveOccurred()) - }) - - Context("for secrets", func() { - It("should reconcile global pull secret", func() { - result := t.controller.isPullSecretOrProxyConfig(t.NewGlobalPullSecret()) - Expect(result).To(ConsistOf(t.deploymentReconcileRequest())) - }) - It("should reconcile APICast secret", func() { - result := t.controller.isPullSecretOrProxyConfig(t.NewInsightsProxySecret()) - Expect(result).To(ConsistOf(t.deploymentReconcileRequest())) - }) - It("should not reconcile a secret in another namespace", func() { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: t.NewGlobalPullSecret().Name, - Namespace: "other", - }, - } - result := t.controller.isPullSecretOrProxyConfig(secret) - Expect(result).To(BeEmpty()) - }) - }) - - Context("for deployments", func() { - It("should reconcile proxy deployment", func() { - result := t.controller.isProxyDeployment(t.NewInsightsProxyDeployment()) - Expect(result).To(ConsistOf(t.deploymentReconcileRequest())) - }) - It("should not reconcile a deployment in another namespace", func() { - deploy := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: t.NewInsightsProxyDeployment().Name, - Namespace: "other", - }, - } - result := t.controller.isProxyDeployment(deploy) - Expect(result).To(BeEmpty()) - }) - }) - - Context("for services", func() { - It("should reconcile proxy service", func() { - result := t.controller.isProxyService(t.NewInsightsProxyService()) - Expect(result).To(ConsistOf(t.deploymentReconcileRequest())) - }) - It("should not reconcile a service in another namespace", func() { - svc := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: t.NewInsightsProxyService().Name, - Namespace: "other", - }, - } - result := t.controller.isProxyService(svc) - Expect(result).To(BeEmpty()) - }) - }) - }) -}) - -func (t *insightsUnitTestInput) deploymentReconcileRequest() reconcile.Request { - return reconcile.Request{NamespacedName: types.NamespacedName{Name: "insights-proxy", Namespace: t.Namespace}} -} diff --git a/internal/controllers/insights/insights_suite_test.go b/internal/controllers/insights/insights_suite_test.go deleted file mode 100644 index 35a3d501b..000000000 --- a/internal/controllers/insights/insights_suite_test.go +++ /dev/null @@ -1,96 +0,0 @@ -// 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 insights_test - -import ( - "fmt" - "path/filepath" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "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" - - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" - - certv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - configv1 "github.com/openshift/api/config/v1" - consolev1 "github.com/openshift/api/console/v1" - routev1 "github.com/openshift/api/route/v1" - // +kubebuilder:scaffold:imports -) - -// 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 - -func TestInsights(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Insights Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "config", "crd", "bases"), - }, - ErrorIfCRDPathMissing: true, - } - fmt.Println(testEnv.CRDDirectoryPaths) - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = operatorv1beta1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = certv1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = consolev1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = routev1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = configv1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/internal/controllers/insights/setup.go b/internal/controllers/insights/setup.go deleted file mode 100644 index 2146ff08e..000000000 --- a/internal/controllers/insights/setup.go +++ /dev/null @@ -1,162 +0,0 @@ -// 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 insights - -import ( - "context" - "fmt" - "net/url" - "strings" - - "github.com/cryostatio/cryostat-operator/internal/controllers/common" - "github.com/cryostatio/cryostat-operator/internal/controllers/constants" - "github.com/go-logr/logr" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -type InsightsIntegration struct { - Manager ctrl.Manager - Log *logr.Logger - common.OSUtils -} - -func NewInsightsIntegration(mgr ctrl.Manager, log *logr.Logger) *InsightsIntegration { - return &InsightsIntegration{ - Manager: mgr, - Log: log, - OSUtils: &common.DefaultOSUtils{}, - } -} - -func (i *InsightsIntegration) Setup() (*url.URL, error) { - var proxyUrl *url.URL - namespace := i.getOperatorNamespace() - // This will happen when running the operator locally - if len(namespace) == 0 { - i.Log.Info("Operator namespace not detected") - return nil, nil - } - - ctx := context.Background() - if i.isInsightsEnabled() { - err := i.createInsightsController(namespace) - if err != nil { - i.Log.Error(err, "unable to add controller to manager", "controller", "Insights") - return nil, err - } - // Create a Config Map to be used as a parent of all Insights Proxy related objects - err = i.createConfigMap(ctx, namespace) - if err != nil { - i.Log.Error(err, "failed to create config map for Insights") - return nil, err - } - proxyUrl = i.getProxyURL(namespace) - } else { - // Delete any previously created Config Map (and its children) - err := i.deleteConfigMap(ctx, namespace) - if err != nil { - i.Log.Error(err, "failed to delete config map for Insights") - return nil, err - } - - } - return proxyUrl, nil -} - -func (i *InsightsIntegration) isInsightsEnabled() bool { - return strings.ToLower(i.GetEnv(EnvInsightsEnabled)) == "true" -} - -func (i *InsightsIntegration) getOperatorNamespace() string { - return i.GetEnv("NAMESPACE") -} - -func (i *InsightsIntegration) createInsightsController(namespace string) error { - config := &InsightsReconcilerConfig{ - Client: i.Manager.GetClient(), - Log: ctrl.Log.WithName("controllers").WithName("Insights"), - Scheme: i.Manager.GetScheme(), - Namespace: namespace, - OSUtils: i.OSUtils, - } - controller, err := NewInsightsReconciler(config) - if err != nil { - return err - } - if err := controller.SetupWithManager(i.Manager); err != nil { - return err - } - return nil -} - -func (i *InsightsIntegration) createConfigMap(ctx context.Context, namespace string) error { - // The config map should be owned by the operator deployment to ensure it and its descendants are garbage collected - owner := &appsv1.Deployment{} - // Use the APIReader instead of the cache, since the cache may not be synced yet - err := i.Manager.GetAPIReader().Get(ctx, types.NamespacedName{ - Name: constants.OperatorDeploymentName, Namespace: namespace}, owner) - if err != nil { - return err - } - - cm := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: InsightsConfigMapName, - Namespace: namespace, - }, - } - err = controllerutil.SetControllerReference(owner, cm, i.Manager.GetScheme()) - if err != nil { - return err - } - - err = i.Manager.GetClient().Create(ctx, cm, &client.CreateOptions{}) - if err == nil { - i.Log.Info("Config Map for Insights created", "name", cm.Name, "namespace", cm.Namespace) - } - // This may already exist if the pod restarted - return client.IgnoreAlreadyExists(err) -} - -func (i *InsightsIntegration) deleteConfigMap(ctx context.Context, namespace string) error { - // Children will be garbage collected - cm := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: InsightsConfigMapName, - Namespace: namespace, - }, - } - - err := i.Manager.GetClient().Delete(ctx, cm, &client.DeleteOptions{}) - if err == nil { - i.Log.Info("Config Map for Insights deleted", "name", cm.Name, "namespace", cm.Namespace) - } - // This may not exist if no config map was previously created - return client.IgnoreNotFound(err) -} - -func (i *InsightsIntegration) getProxyURL(namespace string) *url.URL { - return &url.URL{ - Scheme: "http", // TODO add https support (r.IsCertManagerInstalled) - Host: fmt.Sprintf("%s.%s.svc.cluster.local:%d", ProxyServiceName, namespace, - ProxyServicePort), - } -} diff --git a/internal/controllers/insights/setup_test.go b/internal/controllers/insights/setup_test.go deleted file mode 100644 index 22eb436a3..000000000 --- a/internal/controllers/insights/setup_test.go +++ /dev/null @@ -1,162 +0,0 @@ -// 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 insights_test - -import ( - "context" - - "github.com/cryostatio/cryostat-operator/internal/controllers/insights" - insightstest "github.com/cryostatio/cryostat-operator/internal/controllers/insights/test" - "github.com/cryostatio/cryostat-operator/internal/test" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - kerrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" -) - -var _ = Describe("InsightsIntegration", func() { - var t *insightsTestInput - - Describe("setting up", func() { - var integration *insights.InsightsIntegration - - BeforeEach(func() { - t = &insightsTestInput{ - TestUtilsConfig: &insightstest.TestUtilsConfig{ - EnvInsightsEnabled: &[]bool{true}[0], - EnvInsightsBackendDomain: &[]string{"insights.example.com"}[0], - EnvInsightsProxyImageTag: &[]string{"example.com/proxy:latest"}[0], - EnvNamespace: &[]string{"test"}[0], - }, - InsightsTestResources: &insightstest.InsightsTestResources{ - TestResources: &test.TestResources{ - Namespace: "test", - }, - }, - } - t.objs = []ctrlclient.Object{ - t.NewNamespace(), - t.NewGlobalPullSecret(), - t.NewOperatorDeployment(), - } - }) - - JustBeforeEach(func() { - s := test.NewTestScheme() - logger := zap.New() - logf.SetLogger(logger) - - // Set a CreationTimestamp for created objects to match a real API server - // TODO When using envtest instead of fake client, this is probably no longer needed - err := test.SetCreationTimestamp(t.objs...) - Expect(err).ToNot(HaveOccurred()) - t.client = fake.NewClientBuilder().WithScheme(s).WithObjects(t.objs...).Build() - - manager := insightstest.NewFakeManager(test.NewClientWithTimestamp(test.NewTestClient(t.client, t.TestResources)), - s, &logger) - integration = insights.NewInsightsIntegration(manager, &logger) - integration.OSUtils = insightstest.NewTestOSUtils(t.TestUtilsConfig) - }) - - Context("with defaults", func() { - It("should return proxy URL", func() { - result, err := integration.Setup() - Expect(err).ToNot(HaveOccurred()) - Expect(result).ToNot(BeNil()) - Expect(result.String()).To(Equal("http://insights-proxy.test.svc.cluster.local:8080")) - }) - - It("should create config map", func() { - _, err := integration.Setup() - Expect(err).ToNot(HaveOccurred()) - - expected := t.NewProxyConfigMap() - actual := &corev1.ConfigMap{} - err = t.client.Get(context.Background(), types.NamespacedName{ - Name: expected.Name, - Namespace: expected.Namespace, - }, actual) - Expect(err).ToNot(HaveOccurred()) - - Expect(actual.Labels).To(Equal(expected.Labels)) - Expect(actual.Annotations).To(Equal(expected.Annotations)) - Expect(metav1.IsControlledBy(actual, t.NewOperatorDeployment())).To(BeTrue()) - Expect(actual.Data).To(BeEmpty()) - }) - }) - - Context("with Insights disabled", func() { - BeforeEach(func() { - t.EnvInsightsEnabled = &[]bool{false}[0] - t.objs = append(t.objs, - t.NewProxyConfigMap(), - ) - }) - - It("should return nil", func() { - result, err := integration.Setup() - Expect(err).ToNot(HaveOccurred()) - Expect(result).To(BeNil()) - }) - - It("should delete config map", func() { - _, err := integration.Setup() - Expect(err).ToNot(HaveOccurred()) - - expected := t.NewProxyConfigMap() - actual := &corev1.ConfigMap{} - err = t.client.Get(context.Background(), types.NamespacedName{ - Name: expected.Name, - Namespace: expected.Namespace, - }, actual) - Expect(err).To(HaveOccurred()) - Expect(kerrors.IsNotFound(err)).To(BeTrue()) - }) - }) - - Context("when run out-of-cluster", func() { - BeforeEach(func() { - t.EnvNamespace = nil - }) - - It("should return nil", func() { - result, err := integration.Setup() - Expect(err).ToNot(HaveOccurred()) - Expect(result).To(BeNil()) - }) - - It("should not create config map", func() { - _, err := integration.Setup() - Expect(err).ToNot(HaveOccurred()) - - expected := t.NewProxyConfigMap() - actual := &corev1.ConfigMap{} - err = t.client.Get(context.Background(), types.NamespacedName{ - Name: expected.Name, - Namespace: expected.Namespace, - }, actual) - Expect(err).To(HaveOccurred()) - Expect(kerrors.IsNotFound(err)).To(BeTrue()) - }) - }) - }) -}) diff --git a/internal/controllers/insights/test/manager.go b/internal/controllers/insights/test/manager.go deleted file mode 100644 index ebcd764e7..000000000 --- a/internal/controllers/insights/test/manager.go +++ /dev/null @@ -1,68 +0,0 @@ -// 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 ( - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -type FakeManager struct { - ctrl.Manager - client client.Client - scheme *runtime.Scheme - logger *logr.Logger -} - -func NewFakeManager(client client.Client, scheme *runtime.Scheme, logger *logr.Logger) *FakeManager { - return &FakeManager{ - client: client, - scheme: scheme, - logger: logger, - } -} - -func (m *FakeManager) GetClient() client.Client { - return m.client -} - -func (m *FakeManager) GetScheme() *runtime.Scheme { - return m.scheme -} - -func (m *FakeManager) GetAPIReader() client.Reader { - // May need to change if not using a fake client - return m.client -} - -func (m *FakeManager) GetControllerOptions() v1alpha1.ControllerConfigurationSpec { - return v1alpha1.ControllerConfigurationSpec{} -} - -func (m *FakeManager) GetLogger() logr.Logger { - return *m.logger -} - -func (m *FakeManager) SetFields(interface{}) error { - return nil -} - -func (m *FakeManager) Add(manager.Runnable) error { - return nil -} diff --git a/internal/controllers/insights/test/resources.go b/internal/controllers/insights/test/resources.go deleted file mode 100644 index 8c7937059..000000000 --- a/internal/controllers/insights/test/resources.go +++ /dev/null @@ -1,393 +0,0 @@ -// 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" - configv1 "github.com/openshift/api/config/v1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" -) - -type InsightsTestResources struct { - *test.TestResources - Resources *corev1.ResourceRequirements -} - -const expectedOperatorVersion = "3.0.0-dev" - -func (r *InsightsTestResources) NewGlobalPullSecret() *corev1.Secret { - config := `{"auths":{"example.com":{"auth":"hello"},"cloud.openshift.com":{"auth":"world"}}}` - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pull-secret", - Namespace: "openshift-config", - }, - Data: map[string][]byte{ - corev1.DockerConfigJsonKey: []byte(config), - }, - } -} - -func (r *InsightsTestResources) NewOperatorDeployment() *appsv1.Deployment { - return &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "cryostat-operator-controller-manager", - Namespace: r.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "control-plane": "controller-manager", - }, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "control-plane": "controller-manager", - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "manager", - Image: "example.com/operator:latest", - }, - }, - }, - }, - }, - } -} - -func (r *InsightsTestResources) NewProxyConfigMap() *corev1.ConfigMap { - return &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "insights-proxy", - Namespace: r.Namespace, - }, - } -} - -func (r *InsightsTestResources) NewInsightsProxySecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "apicastconf", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "config.json": fmt.Sprintf(`{ - "services": [ - { - "id": "1", - "backend_version": "1", - "proxy": { - "hosts": ["insights-proxy","insights-proxy.%s.svc.cluster.local"], - "api_backend": "https://insights.example.com:443/", - "backend": { "endpoint": "http://127.0.0.1:8081", "host": "backend" }, - "policy_chain": [ - { - "name": "default_credentials", - "version": "builtin", - "configuration": { - "auth_type": "user_key", - "user_key": "dummy_key" - } - }, - { - "name": "headers", - "version": "builtin", - "configuration": { - "request": [ - { - "op": "set", - "header": "Authorization", - "value_type": "plain", - "value": "Bearer world" - }, - { - "op": "set", - "header": "User-Agent", - "value_type": "plain", - "value": "cryostat-operator/%s cluster/abcde" - } - ] - } - }, - { - "name": "apicast.policy.apicast" - } - ], - "proxy_rules": [ - { - "http_method": "POST", - "pattern": "/", - "metric_system_name": "hits", - "delta": 1, - "parameters": [], - "querystring_parameters": {} - } - ] - } - } - ] - }`, r.Namespace, expectedOperatorVersion), - }, - } -} - -func (r *InsightsTestResources) NewInsightsProxySecretWithProxyDomain() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "apicastconf", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "config.json": fmt.Sprintf(`{ - "services": [ - { - "id": "1", - "backend_version": "1", - "proxy": { - "hosts": ["insights-proxy","insights-proxy.%s.svc.cluster.local"], - "api_backend": "https://insights.example.com:443/", - "backend": { "endpoint": "http://127.0.0.1:8081", "host": "backend" }, - "policy_chain": [ - { - "name": "default_credentials", - "version": "builtin", - "configuration": { - "auth_type": "user_key", - "user_key": "dummy_key" - } - }, - { - "name": "apicast.policy.http_proxy", - "configuration": { - "https_proxy": "http://proxy.example.com/", - "http_proxy": "http://proxy.example.com/" - } - }, - { - "name": "headers", - "version": "builtin", - "configuration": { - "request": [ - { - "op": "set", - "header": "Authorization", - "value_type": "plain", - "value": "Bearer world" - }, - { - "op": "set", - "header": "User-Agent", - "value_type": "plain", - "value": "cryostat-operator/%s cluster/abcde" - } - ] - } - }, - { - "name": "apicast.policy.apicast" - } - ], - "proxy_rules": [ - { - "http_method": "POST", - "pattern": "/", - "metric_system_name": "hits", - "delta": 1, - "parameters": [], - "querystring_parameters": {} - } - ] - } - } - ] - }`, r.Namespace, expectedOperatorVersion), - }, - } -} - -func (r *InsightsTestResources) NewInsightsProxyDeployment() *appsv1.Deployment { - var resources *corev1.ResourceRequirements - if r.Resources != nil { - resources = r.Resources - } else { - resources = &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("50m"), - corev1.ResourceMemory: resource.MustParse("64Mi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("200m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - } - } - return &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "insights-proxy", - Namespace: r.Namespace, - Labels: map[string]string{ - "app": "insights-proxy", - }, - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "app": "insights-proxy", - }, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "app": "insights-proxy", - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "insights-proxy", - Image: "example.com/proxy:latest", - Env: []corev1.EnvVar{ - { - Name: "THREESCALE_CONFIG_FILE", - Value: "/tmp/gateway-configuration-volume/config.json", - }, - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "gateway-configuration-volume", - MountPath: "/tmp/gateway-configuration-volume", - ReadOnly: true, - }, - }, - Ports: []corev1.ContainerPort{ - { - Name: "proxy", - ContainerPort: 8080, - }, - { - Name: "management", - ContainerPort: 8090, - }, - { - Name: "metrics", - ContainerPort: 9421, - }, - }, - Resources: *resources, - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: &[]bool{false}[0], - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{"ALL"}, - }, - }, - LivenessProbe: &corev1.Probe{ - InitialDelaySeconds: 10, - TimeoutSeconds: 5, - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/status/live", - Port: intstr.FromInt(8090), - }, - }, - }, - ReadinessProbe: &corev1.Probe{ - InitialDelaySeconds: 15, - PeriodSeconds: 30, - TimeoutSeconds: 5, - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/status/ready", - Port: intstr.FromInt(8090), - }, - }, - }, - }, - }, - Volumes: []corev1.Volume{ - { - Name: "gateway-configuration-volume", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: "apicastconf", - Items: []corev1.KeyToPath{ - { - Key: "config.json", - Path: "config.json", - Mode: &[]int32{0440}[0], - }, - }, - }, - }, - }, - }, - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - }, - }, - }, - }, - } -} - -func (r *InsightsTestResources) NewInsightsProxyService() *corev1.Service { - return &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: "insights-proxy", - Namespace: r.Namespace, - Labels: map[string]string{ - "app": "insights-proxy", - }, - }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - Selector: map[string]string{ - "app": "insights-proxy", - }, - Ports: []corev1.ServicePort{ - { - Name: "proxy", - Port: 8080, - TargetPort: intstr.FromString("proxy"), - }, - { - Name: "management", - Port: 8090, - TargetPort: intstr.FromString("management"), - }, - }, - }, - } -} - -func (r *InsightsTestResources) NewClusterVersion() *configv1.ClusterVersion { - return &configv1.ClusterVersion{ - ObjectMeta: metav1.ObjectMeta{ - Name: "version", - }, - Spec: configv1.ClusterVersionSpec{ - ClusterID: "abcde", - }, - } -} diff --git a/internal/controllers/insights/test/utils.go b/internal/controllers/insights/test/utils.go deleted file mode 100644 index 9b27c685b..000000000 --- a/internal/controllers/insights/test/utils.go +++ /dev/null @@ -1,66 +0,0 @@ -// 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 ( - "strconv" -) - -// TestUtilsConfig groups parameters used to create a test OSUtils -type TestUtilsConfig struct { - EnvInsightsEnabled *bool - EnvInsightsProxyImageTag *string - EnvInsightsBackendDomain *string - EnvInsightsProxyDomain *string - EnvNamespace *string -} - -type testOSUtils struct { - envs map[string]string -} - -func NewTestOSUtils(config *TestUtilsConfig) *testOSUtils { - envs := map[string]string{} - if config.EnvInsightsEnabled != nil { - envs["INSIGHTS_ENABLED"] = strconv.FormatBool(*config.EnvInsightsEnabled) - } - if config.EnvInsightsProxyImageTag != nil { - envs["RELATED_IMAGE_INSIGHTS_PROXY"] = *config.EnvInsightsProxyImageTag - } - if config.EnvInsightsBackendDomain != nil { - envs["INSIGHTS_BACKEND_DOMAIN"] = *config.EnvInsightsBackendDomain - } - if config.EnvInsightsProxyDomain != nil { - envs["INSIGHTS_PROXY_DOMAIN"] = *config.EnvInsightsProxyDomain - } - if config.EnvNamespace != nil { - envs["NAMESPACE"] = *config.EnvNamespace - } - return &testOSUtils{envs: envs} -} - -func (o *testOSUtils) GetFileContents(path string) ([]byte, error) { - // Unused - return nil, nil -} - -func (o *testOSUtils) GetEnv(name string) string { - return o.envs[name] -} - -func (o *testOSUtils) GenPasswd(length int) string { - // Unused - return "" -} diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index e8fcde9ab..be8d8bac6 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -90,7 +90,8 @@ func (c *controllerTest) commonJustBeforeEach(t *cryostatTestInput) { // TODO When using envtest instead of fake client, this is probably no longer needed err := test.SetCreationTimestamp(t.objs...) Expect(err).ToNot(HaveOccurred()) - t.Client = fake.NewClientBuilder().WithScheme(s).WithObjects(t.objs...).Build() + t.Client = fake.NewClientBuilder().WithScheme(s).WithObjects(t.objs...). + WithStatusSubresource(&operatorv1beta2.Cryostat{}, &certv1.Certificate{}, &openshiftv1.Route{}).Build() t.controller, err = c.constructorFunc(t.newReconcilerConfig(s, t.Client)) Expect(err).ToNot(HaveOccurred()) } @@ -1938,7 +1939,15 @@ func (c *controllerTest) commonTests() { t.reconcileCryostatFully() }) It("should update the Ingresses", func() { - t.expectIngresses() + expected := t.NewGrafanaIngress() + metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "other-grafana", "annotation") + metav1.SetMetaDataLabel(&expected.ObjectMeta, "other-grafana", "label") + t.checkIngress(expected) + + expected = t.NewCoreIngress() + metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "other", "annotation") + metav1.SetMetaDataLabel(&expected.ObjectMeta, "other", "label") + t.checkIngress(expected) }) }) Context("networkConfig for one of the services is nil", func() { @@ -2217,26 +2226,13 @@ func (t *cryostatTestInput) reconcileCryostatFully() { }).WithTimeout(time.Minute).WithPolling(time.Millisecond).Should(Equal(reconcile.Result{})) } -func (t *cryostatTestInput) reconcileCryostatFullyWithError() error { - var reconcileErr error - Eventually(func() error { - result, err := t.reconcile() - if err == nil { - Expect(result).ToNot(Equal(reconcile.Result{})) - } - reconcileErr = err - return err - }).WithTimeout(time.Minute).WithPolling(time.Millisecond).Should(Not(BeNil())) - return reconcileErr -} - func (t *cryostatTestInput) reconcileDeletedCryostat() { - // Simulate deletion by setting DeletionTimestamp cr := t.getCryostatInstance() - delTime := metav1.Unix(0, 1598045501618*int64(time.Millisecond)) - cr.Object.SetDeletionTimestamp(&delTime) - t.updateCryostatInstance(cr) + // Check that the finalizer is set, then delete + Expect(controllerutil.ContainsFinalizer(cr.Object, "operator.cryostat.io/cryostat.finalizer")) + err := t.Client.Delete(context.Background(), cr.Object) + Expect(err).ToNot(HaveOccurred()) // Reconcile again t.reconcileCryostatFully() @@ -2372,21 +2368,17 @@ func (t *cryostatTestInput) expectNoRoutes() { } func (t *cryostatTestInput) expectIngresses() { - cr := t.getCryostatInstance() - expectedConfig := cr.Spec.NetworkOptions + t.checkIngress(t.NewCoreIngress()) + t.checkIngress(t.NewGrafanaIngress()) +} +func (t *cryostatTestInput) checkIngress(expected *netv1.Ingress) { ingress := &netv1.Ingress{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, ingress) - Expect(err).ToNot(HaveOccurred()) - Expect(ingress.Annotations).To(Equal(expectedConfig.CoreConfig.Annotations)) - Expect(ingress.Labels).To(Equal(expectedConfig.CoreConfig.Labels)) - Expect(ingress.Spec).To(Equal(*expectedConfig.CoreConfig.IngressSpec)) - - err = t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana", Namespace: t.Namespace}, ingress) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, ingress) Expect(err).ToNot(HaveOccurred()) - Expect(ingress.Annotations).To(Equal(expectedConfig.GrafanaConfig.Annotations)) - Expect(ingress.Labels).To(Equal(expectedConfig.GrafanaConfig.Labels)) - Expect(ingress.Spec).To(Equal(*expectedConfig.GrafanaConfig.IngressSpec)) + Expect(ingress.Annotations).To(Equal(expected.Annotations)) + Expect(ingress.Labels).To(Equal(expected.Labels)) + Expect(ingress.Spec).To(Equal(expected.Spec)) } func (t *cryostatTestInput) expectNoIngresses() { diff --git a/internal/main.go b/internal/main.go index 6c51865af..51a746763 100644 --- a/internal/main.go +++ b/internal/main.go @@ -36,13 +36,15 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" + "github.com/RedHatInsights/runtimes-inventory-operator/pkg/insights" operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" 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/insights" + "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/webhooks" // +kubebuilder:scaffold:imports ) @@ -71,12 +73,15 @@ func main() { var metricsAddr string var enableLeaderElection bool var probeAddr string + var secureMetrics bool var enableHTTP2 bool flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") + flag.BoolVar(&secureMetrics, "metrics-secure", false, + "If set the metrics endpoint is served securely") flag.BoolVar(&enableHTTP2, "enable-http2", false, "If HTTP/2 should be enabled for the metrics and webhook servers.") opts := zap.Options{ Development: true, @@ -86,28 +91,40 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - // Customize the webhook server to disable HTTP/2 by default + // if the enable-http2 flag is false (the default), http/2 should be disabled + // due to its vulnerabilities. More specifically, disabling http/2 will + // prevent from being vulnerable to the HTTP/2 Stream Cancelation and + // Rapid Reset CVEs. For more information see: + // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 + // - https://github.com/advisories/GHSA-4374-p667-p6c8 disableHTTP2 := func(c *tls.Config) { - if enableHTTP2 { - return - } + setupLog.Info("disabling http/2") c.NextProtos = []string{"http/1.1"} } - webhookServer := &webhook.Server{ - TLSOpts: []func(config *tls.Config){disableHTTP2}, + + tlsOpts := []func(*tls.Config){} + if !enableHTTP2 { + tlsOpts = append(tlsOpts, disableHTTP2) } + webhookServer := webhook.NewServer(webhook.Options{ + TLSOpts: tlsOpts, + }) + // FIXME Disable metrics until this issue is resolved: // https://github.com/operator-framework/operator-sdk/issues/4684 metricsAddr = "0" mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - MetricsBindAddress: metricsAddr, - Port: 9443, + Scheme: scheme, + Metrics: metricsserver.Options{ + BindAddress: metricsAddr, + SecureServing: secureMetrics, + TLSOpts: tlsOpts, + }, + WebhookServer: webhookServer, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionID: "d696d7ab.redhat.com", - WebhookServer: webhookServer, }) if err != nil { setupLog.Error(err, "unable to start manager") @@ -144,9 +161,12 @@ func main() { } // Optionally enable Insights integration. Will only be enabled if INSIGHTS_ENABLED is true + operatorNamespace := os.Getenv("OPERATOR_NAMESPACE") + userAgentPrefix := fmt.Sprintf("cryostat-operator/%s", controllers.OperatorVersion) var insightsURL *url.URL if openShift { - insightsURL, err = insights.NewInsightsIntegration(mgr, &setupLog).Setup() + insightsURL, err = insights.NewInsightsIntegration(mgr, constants.OperatorDeploymentName, + operatorNamespace, userAgentPrefix, &setupLog).Setup() if err != nil { setupLog.Error(err, "failed to set up Insights integration") } diff --git a/internal/test/resources.go b/internal/test/resources.go index a7584499c..e7d3529b4 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -2307,14 +2307,71 @@ func (r *TestResources) OtherGrafanaRoute() *routev1.Route { } } +func (r *TestResources) NewCoreIngress() *netv1.Ingress { + return r.newIngress(r.Name, 8181, map[string]string{"custom": "annotation"}, + map[string]string{"my": "label", "custom": "label"}) +} + +func (r *TestResources) NewGrafanaIngress() *netv1.Ingress { + return r.newIngress(r.Name+"-grafana", 3000, map[string]string{"grafana": "annotation"}, + map[string]string{"my": "label", "grafana": "label"}) +} + +func (r *TestResources) newIngress(name string, svcPort int32, annotations, labels map[string]string) *netv1.Ingress { + pathtype := netv1.PathTypePrefix + + annotations["nginx.ingress.kubernetes.io/backend-protocol"] = "HTTPS" + labels["app"] = r.Name + labels["component"] = "cryostat" + + var ingressTLS []netv1.IngressTLS + if r.ExternalTLS { + ingressTLS = []netv1.IngressTLS{{}} + } + return &netv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: r.Namespace, + Annotations: annotations, + Labels: labels, + }, + Spec: netv1.IngressSpec{ + Rules: []netv1.IngressRule{ + { + Host: name + ".example.com", + IngressRuleValue: netv1.IngressRuleValue{ + HTTP: &netv1.HTTPIngressRuleValue{ + Paths: []netv1.HTTPIngressPath{ + { + Path: "/", + PathType: &pathtype, + Backend: netv1.IngressBackend{ + Service: &netv1.IngressServiceBackend{ + Name: name, + Port: netv1.ServiceBackendPort{ + Number: svcPort, + }, + }, + }, + }, + }, + }, + }, + }, + }, + TLS: ingressTLS, + }, + } +} + func (r *TestResources) OtherCoreIngress() *netv1.Ingress { pathtype := netv1.PathTypePrefix return &netv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: r.Name, Namespace: r.Namespace, - Annotations: map[string]string{"custom": "annotation"}, - Labels: map[string]string{"custom": "label"}, + Annotations: map[string]string{"other": "annotation"}, + Labels: map[string]string{"other": "label", "app": "not-cryostat"}, }, Spec: netv1.IngressSpec{ Rules: []netv1.IngressRule{ @@ -2350,8 +2407,8 @@ func (r *TestResources) OtherGrafanaIngress() *netv1.Ingress { ObjectMeta: metav1.ObjectMeta{ Name: r.Name + "-grafana", Namespace: r.Namespace, - Annotations: map[string]string{"grafana": "annotation"}, - Labels: map[string]string{"grafana": "label"}, + Annotations: map[string]string{"other-grafana": "annotation"}, + Labels: map[string]string{"other-grafana": "label", "app": "not-grafana"}, }, Spec: netv1.IngressSpec{ Rules: []netv1.IngressRule{ diff --git a/internal/webhooks/validator.go b/internal/webhooks/validator.go index f1b3dd910..5b66d5482 100644 --- a/internal/webhooks/validator.go +++ b/internal/webhooks/validator.go @@ -35,19 +35,19 @@ type CryostatValidator struct { var _ admission.CustomValidator = &CryostatValidator{} // ValidateCreate validates a Create operation on a Cryostat -func (r *CryostatValidator) ValidateCreate(ctx context.Context, obj runtime.Object) error { +func (r *CryostatValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { return r.validate(ctx, obj, "create") } // ValidateCreate validates an Update operation on a Cryostat -func (r *CryostatValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) error { +func (r *CryostatValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { return r.validate(ctx, newObj, "update") } // ValidateCreate validates a Delete operation on a Cryostat -func (r *CryostatValidator) ValidateDelete(ctx context.Context, obj runtime.Object) error { +func (r *CryostatValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { // Nothing to validate on deletion - return nil + return nil, nil } type ErrNotPermitted struct { @@ -68,17 +68,17 @@ func (e *ErrNotPermitted) Error() string { var _ error = &ErrNotPermitted{} -func (r *CryostatValidator) validate(ctx context.Context, obj runtime.Object, op string) error { +func (r *CryostatValidator) validate(ctx context.Context, obj runtime.Object, op string) (admission.Warnings, error) { cr, ok := obj.(*operatorv1beta2.Cryostat) if !ok { - return fmt.Errorf("expected a Cryostat, but received a %T", obj) + return nil, fmt.Errorf("expected a Cryostat, but received a %T", obj) } r.Log.Info(fmt.Sprintf("validate %s", op), "name", cr.Name, "namespace", cr.Namespace) // Look up the user who made this request req, err := admission.RequestFromContext(ctx) if err != nil { - return fmt.Errorf("no admission request found in context: %w", err) + return nil, fmt.Errorf("no admission request found in context: %w", err) } userInfo := req.UserInfo @@ -103,15 +103,15 @@ func (r *CryostatValidator) validate(ctx context.Context, obj runtime.Object, op err := r.Client.Create(ctx, sar) if err != nil { - return fmt.Errorf("failed to check permissions: %w", err) + return nil, fmt.Errorf("failed to check permissions: %w", err) } if !sar.Status.Allowed { - return NewErrNotPermitted(op, namespace) + return nil, NewErrNotPermitted(op, namespace) } } - return nil + return nil, nil } func translateExtra(extra map[string]authnv1.ExtraValue) map[string]authzv1.ExtraValue { diff --git a/internal/webhooks/validator_test.go b/internal/webhooks/validator_test.go index 584976ac0..c370c56d2 100644 --- a/internal/webhooks/validator_test.go +++ b/internal/webhooks/validator_test.go @@ -27,7 +27,6 @@ import ( corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/rest" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -195,5 +194,5 @@ var _ = Describe("CryostatValidator", func() { func expectErrNotPermitted(actual error, op string, namespace string) { expectedErr := webhooks.NewErrNotPermitted(op, namespace) Expect(kerrors.IsForbidden(actual)).To(BeTrue(), "expected Forbidden API error") - Expect(kerrors.ReasonForError(actual)).To(Equal(metav1.StatusReason(expectedErr.Error()))) + Expect(actual.Error()).To(ContainSubstring(expectedErr.Error())) } diff --git a/internal/webhooks/webhook_suite_test.go b/internal/webhooks/webhook_suite_test.go index 7d7dca37f..dbdf7d147 100644 --- a/internal/webhooks/webhook_suite_test.go +++ b/internal/webhooks/webhook_suite_test.go @@ -39,6 +39,8 @@ import ( "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 @@ -95,12 +97,14 @@ var _ = BeforeSuite(func() { // start webhook server using Manager webhookInstallOptions := &testEnv.WebhookInstallOptions mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: k8sScheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", + 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()) From a26ff9cc9f81f710182e7b6121b4ebef831d0af2 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Fri, 26 Apr 2024 17:41:07 -0400 Subject: [PATCH 27/53] feat(auth): deploy openshift auth proxy (#799) --- Makefile | 8 + api/v1beta2/cryostat_types.go | 8 + api/v1beta2/zz_generated.deepcopy.go | 6 + ...c.authorization.k8s.io_v1_clusterrole.yaml | 1 + ...yostat-operator.clusterserviceversion.yaml | 18 +- .../operator.cryostat.io_cryostats.yaml | 215 ++++++++++++++++++ .../bases/operator.cryostat.io_cryostats.yaml | 215 ++++++++++++++++++ config/default/image_tag_patch.yaml | 4 + ...yostat-operator.clusterserviceversion.yaml | 8 + config/rbac/cryostat_role.yaml | 1 + hack/image_tag_patch.yaml.in | 4 + .../resource_definitions.go | 131 +++++++++-- internal/controllers/const_generated.go | 6 + internal/controllers/constants/constants.go | 23 +- internal/controllers/reconciler.go | 20 +- internal/controllers/reconciler_test.go | 25 +- internal/controllers/services.go | 4 +- internal/test/reconciler.go | 26 ++- internal/test/resources.go | 16 +- internal/test/scorecard/common_utils.go | 2 +- internal/tools/const_generator.go | 12 + 21 files changed, 700 insertions(+), 53 deletions(-) diff --git a/Makefile b/Makefile index 9d9a63ac9..536066819 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,14 @@ CORE_NAMESPACE ?= $(DEFAULT_NAMESPACE) CORE_NAME ?= cryostat CORE_VERSION ?= 3.0.0-snapshot export CORE_IMG ?= $(CORE_NAMESPACE)/$(CORE_NAME):$(CORE_VERSION) +OAUTH2_PROXY_NAMESPACE ?= quay.io/oauth2-proxy +OAUTH2_PROXY_NAME ?= oauth2-proxy +OAUTH2_PROXY_VERSION ?= latest +export OAUTH2_PROXY_IMG ?= $(OAUTH2_PROXY_NAMESPACE)/$(OAUTH2_PROXY_NAME):$(OAUTH2_PROXY_VERSION) +OPENSHIFT_OAUTH_PROXY_NAMESPACE ?= quay.io/openshift +OPENSHIFT_OAUTH_PROXY_NAME ?= origin-oauth-proxy +OPENSHIFT_OAUTH_PROXY_VERSION ?= latest +export OPENSHIFT_OAUTH_PROXY_IMG ?= $(OPENSHIFT_OAUTH_PROXY_NAMESPACE)/$(OPENSHIFT_OAUTH_PROXY_NAME):$(OPENSHIFT_OAUTH_PROXY_VERSION) DATASOURCE_NAMESPACE ?= $(DEFAULT_NAMESPACE) DATASOURCE_NAME ?= jfr-datasource DATASOURCE_VERSION ?= latest diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 118c57aef..1c6732897 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -118,6 +118,10 @@ type ResourceMetadata struct { } type ResourceConfigList struct { + // Resource requirements for the auth proxy. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + AuthProxyResources corev1.ResourceRequirements `json:"authProxyResources,omitempty"` // Resource requirements for the Cryostat application. If specifying a memory limit, at least 768MiB is recommended. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} @@ -500,6 +504,10 @@ type SecurityOptions struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` + // Security Context to apply to the auth proxy container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + AuthProxySecurityContext *corev1.SecurityContext `json:"authProxySecurityContext,omitempty"` // Security Context to apply to the Cryostat application container. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 94b9e5f5f..9c3b8ac6b 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -564,6 +564,7 @@ func (in *ReportsServiceConfig) DeepCopy() *ReportsServiceConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceConfigList) DeepCopyInto(out *ResourceConfigList) { *out = *in + in.AuthProxyResources.DeepCopyInto(&out.AuthProxyResources) in.CoreResources.DeepCopyInto(&out.CoreResources) in.DataSourceResources.DeepCopyInto(&out.DataSourceResources) in.GrafanaResources.DeepCopyInto(&out.GrafanaResources) @@ -650,6 +651,11 @@ func (in *SecurityOptions) DeepCopyInto(out *SecurityOptions) { *out = new(corev1.PodSecurityContext) (*in).DeepCopyInto(*out) } + if in.AuthProxySecurityContext != nil { + in, out := &in.AuthProxySecurityContext, &out.AuthProxySecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } if in.CoreSecurityContext != nil { in, out := &in.CoreSecurityContext, &out.CoreSecurityContext *out = new(corev1.SecurityContext) diff --git a/bundle/manifests/cryostat-operator-cryostat_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/cryostat-operator-cryostat_rbac.authorization.k8s.io_v1_clusterrole.yaml index fc184afa0..b23431210 100644 --- a/bundle/manifests/cryostat-operator-cryostat_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/bundle/manifests/cryostat-operator-cryostat_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -13,6 +13,7 @@ rules: - apiGroups: - authorization.k8s.io resources: + - subjectaccessreviews - selfsubjectaccessreviews verbs: - create diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 01181eb8f..5b938a04b 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-04-25T15:33:04Z" + createdAt: "2024-04-26T21:39:27Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -701,6 +701,11 @@ spec: - description: Resource requirements for the Cryostat deployment. displayName: Resources path: resources + - description: Resource requirements for the auth proxy. + displayName: Auth Proxy Resources + path: resources.authProxyResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Cryostat application. If specifying a memory limit, at least 768MiB is recommended. displayName: Core Resources @@ -754,6 +759,9 @@ spec: path: securityOptions x-descriptors: - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the auth proxy container. + displayName: Auth Proxy Security Context + path: securityOptions.authProxySecurityContext - description: Security Context to apply to the Cryostat application container. displayName: Core Security Context path: securityOptions.coreSecurityContext @@ -1096,6 +1104,10 @@ spec: command: - /manager env: + - name: RELATED_IMAGE_OAUTH2_PROXY + value: quay.io/oauth2-proxy/oauth2-proxy:latest + - name: RELATED_IMAGE_OPENSHIFT_OAUTH_PROXY + value: quay.io/openshift/origin-oauth-proxy:latest - name: RELATED_IMAGE_CORE value: quay.io/cryostat/cryostat:3.0.0-snapshot - name: RELATED_IMAGE_DATASOURCE @@ -1266,6 +1278,10 @@ spec: provider: name: The Cryostat Community relatedImages: + - image: quay.io/oauth2-proxy/oauth2-proxy:latest + name: oauth2-proxy + - image: quay.io/openshift/origin-oauth-proxy:latest + name: openshift-oauth-proxy - image: quay.io/cryostat/cryostat:3.0.0-snapshot name: core - image: quay.io/cryostat/jfr-datasource:latest diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 1c51814e6..0f89e5eae 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -7254,6 +7254,55 @@ spec: resources: description: Resource requirements for the Cryostat deployment. properties: + authProxyResources: + description: Resource requirements for the auth proxy. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object coreResources: description: Resource requirements for the Cryostat application. If specifying a memory limit, at least 768MiB is recommended. @@ -8325,6 +8374,172 @@ spec: description: Options to configure the Security Contexts for the Cryostat application. properties: + authProxySecurityContext: + description: Security Context to apply to the auth proxy container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object coreSecurityContext: description: Security Context to apply to the Cryostat application container. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index d6f3d88fe..fe760fd79 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -7244,6 +7244,55 @@ spec: resources: description: Resource requirements for the Cryostat deployment. properties: + authProxyResources: + description: Resource requirements for the auth proxy. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object coreResources: description: Resource requirements for the Cryostat application. If specifying a memory limit, at least 768MiB is recommended. @@ -8315,6 +8364,172 @@ spec: description: Options to configure the Security Contexts for the Cryostat application. properties: + authProxySecurityContext: + description: Security Context to apply to the auth proxy container. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object coreSecurityContext: description: Security Context to apply to the Cryostat application container. diff --git a/config/default/image_tag_patch.yaml b/config/default/image_tag_patch.yaml index 443332fd6..4bad37204 100644 --- a/config/default/image_tag_patch.yaml +++ b/config/default/image_tag_patch.yaml @@ -9,6 +9,10 @@ spec: containers: - name: manager env: + - name: RELATED_IMAGE_OAUTH2_PROXY + value: "quay.io/oauth2-proxy/oauth2-proxy:latest" + - name: RELATED_IMAGE_OPENSHIFT_OAUTH_PROXY + value: "quay.io/openshift/origin-oauth-proxy:latest" - name: RELATED_IMAGE_CORE value: "quay.io/cryostat/cryostat:3.0.0-snapshot" - name: RELATED_IMAGE_DATASOURCE diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index de327d0f2..3580f47b6 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -246,6 +246,11 @@ spec: - description: Resource requirements for the Cryostat deployment. displayName: Resources path: resources + - description: Resource requirements for the auth proxy. + displayName: Auth Proxy Resources + path: resources.authProxyResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Cryostat application. If specifying a memory limit, at least 768MiB is recommended. displayName: Core Resources @@ -299,6 +304,9 @@ spec: path: securityOptions x-descriptors: - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Security Context to apply to the auth proxy container. + displayName: Auth Proxy Security Context + path: securityOptions.authProxySecurityContext - description: Security Context to apply to the Cryostat application container. displayName: Core Security Context path: securityOptions.coreSecurityContext diff --git a/config/rbac/cryostat_role.yaml b/config/rbac/cryostat_role.yaml index 99396be36..56184b018 100644 --- a/config/rbac/cryostat_role.yaml +++ b/config/rbac/cryostat_role.yaml @@ -14,6 +14,7 @@ rules: - apiGroups: - authorization.k8s.io resources: + - subjectaccessreviews - selfsubjectaccessreviews verbs: - create diff --git a/hack/image_tag_patch.yaml.in b/hack/image_tag_patch.yaml.in index fab913267..d661f2d47 100644 --- a/hack/image_tag_patch.yaml.in +++ b/hack/image_tag_patch.yaml.in @@ -9,6 +9,10 @@ spec: containers: - name: manager env: + - name: RELATED_IMAGE_OAUTH2_PROXY + value: "${OAUTH2_PROXY_IMG}" + - name: RELATED_IMAGE_OPENSHIFT_OAUTH_PROXY + value: "${OPENSHIFT_OAUTH_PROXY_IMG}" - name: RELATED_IMAGE_CORE value: "${CORE_IMG}" - name: RELATED_IMAGE_DATASOURCE diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 470f1dd5e..060c9499c 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -34,21 +34,24 @@ import ( // ImageTags contains container image tags for each of the images to deploy type ImageTags struct { - CoreImageTag string - DatasourceImageTag string - GrafanaImageTag string - ReportsImageTag string - StorageImageTag string - DatabaseImageTag string + OAuth2ProxyImageTag string + OpenShiftOAuthProxyImageTag string + CoreImageTag string + DatasourceImageTag string + GrafanaImageTag string + ReportsImageTag string + StorageImageTag string + DatabaseImageTag string } type ServiceSpecs struct { - CoreURL *url.URL - GrafanaURL *url.URL - ReportsURL *url.URL - InsightsURL *url.URL - StorageURL *url.URL - DatabaseURL *url.URL + AuthProxyURL *url.URL + CoreURL *url.URL + GrafanaURL *url.URL + ReportsURL *url.URL + InsightsURL *url.URL + StorageURL *url.URL + DatabaseURL *url.URL } // TLSConfig contains TLS-related information useful when creating other objects @@ -66,6 +69,8 @@ type TLSConfig struct { } const ( + defaultAuthProxyCpuRequest string = "50m" + defaultAuthProxyMemoryRequest string = "100Mi" defaultCoreCpuRequest string = "500m" defaultCoreMemoryRequest string = "256Mi" defaultJfrDatasourceCpuRequest string = "200m" @@ -247,6 +252,7 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima NewJfrDatasourceContainer(cr, imageTags.DatasourceImageTag), NewStorageContainer(cr, imageTags.StorageImageTag, tls), newDatabaseContainer(cr, imageTags.DatabaseImageTag, tls), + NewAuthProxyContainer(cr, specs, imageTags.OAuth2ProxyImageTag, imageTags.OpenShiftOAuthProxyImageTag, tls, openshift), } volumes := newVolumeForCR(cr) @@ -572,6 +578,101 @@ func NewPodForReports(cr *model.CryostatInstance, imageTags *ImageTags, tls *TLS } } +func NewAuthProxyContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{} + if cr.Spec.Resources != nil { + resources = cr.Spec.Resources.AuthProxyResources.DeepCopy() + } + populateResourceRequest(resources, defaultAuthProxyCpuRequest, defaultAuthProxyMemoryRequest) + return resources +} + +func NewAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, oauth2ProxyImageTag string, openshiftAuthProxyImageTag string, + tls *TLSConfig, openshift bool) corev1.Container { + // if (openshift) { + return NewOpenShiftAuthProxyContainer(cr, specs, openshiftAuthProxyImageTag, tls) + // } + // return NewOAuth2ProxyContainer(cr, specs, oauth2ProxyImageTag, tls) +} + +func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag string, + tls *TLSConfig) corev1.Container { + var containerSc *corev1.SecurityContext + if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.AuthProxySecurityContext != nil { + containerSc = cr.Spec.SecurityOptions.AuthProxySecurityContext + } else { + privEscalation := false + containerSc = &corev1.SecurityContext{ + AllowPrivilegeEscalation: &privEscalation, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{constants.CapabilityAll}, + }, + } + } + + probeHandler := corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, + Path: "/ping", + Scheme: corev1.URISchemeHTTP, + }, + } + + basicAuthEnabled := false + args := []string{ + fmt.Sprintf("--skip-provider-button=%t", !basicAuthEnabled), + fmt.Sprintf("--upstream=http://localhost:%d/", constants.CryostatHTTPContainerPort), + fmt.Sprintf("--upstream=http://localhost:%d/grafana/", constants.GrafanaContainerPort), + fmt.Sprintf("--upstream=http://localhost:%d/storage/", constants.StoragePort), + "--cookie-secret=REPLACEME", + fmt.Sprintf("--openshift-service-account=%s", cr.Name), + "--proxy-websockets=true", + fmt.Sprintf("--http-address=0.0.0.0:%d", constants.AuthProxyHttpContainerPort), + fmt.Sprintf( + `--openshift-sar=[{"group":"","name":"","namespace":"%s","resource":"pods","subresource":"exec","verb":"create","version":""}]`, + cr.InstallNamespace, + ), + fmt.Sprintf( + `--openshift-delegate-urls={"/":{"group":"","name":"","namespace":"%s","resource":"pods","subresource":"exec","verb":"create","version":""}}`, + cr.InstallNamespace, + ), + "--bypass-auth-for=^/health", + "--proxy-prefix=/oauth2", + } + // if tls != nil { + // "--https-address=:8443", + // "--tls-cert=/etc/tls/private/tls.crt", + // "--tls-key=/etc/tls/private/tls.key", + // } else { + args = append(args, "--https-address=") + // } + + return corev1.Container{ + Name: cr.Name + "-auth-proxy", + Image: imageTag, + ImagePullPolicy: getPullPolicy(imageTag), + // VolumeMounts: mounts, + Ports: []corev1.ContainerPort{ + { + ContainerPort: constants.AuthProxyHttpContainerPort, + }, + }, + // Env: envs, + // EnvFrom: envsFrom, + Resources: *NewAuthProxyContainerResource(cr), + LivenessProbe: &corev1.Probe{ + ProbeHandler: probeHandler, + }, + SecurityContext: containerSc, + Args: args, + } +} + +// func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag string, +// tls *TLSConfig) corev1.Container { + +// } + func NewCoreContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { resources := &corev1.ResourceRequirements{} if cr.Spec.Resources != nil { @@ -679,7 +780,11 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Value: "false", }, { - Name: "CRYOSTAT_K8S_NAMESPACES", + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_ENABLED", + Value: "true", + }, + { + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_NAMESPACES", Value: strings.Join(cr.TargetNamespaces, ","), }, } diff --git a/internal/controllers/const_generated.go b/internal/controllers/const_generated.go index d96a17a87..41ae4e3e4 100644 --- a/internal/controllers/const_generated.go +++ b/internal/controllers/const_generated.go @@ -7,6 +7,12 @@ const AppName = "Cryostat" // Version of the Cryostat Operator const OperatorVersion = "3.0.0-dev" +// Default image tag for the OAuth2 Proxy +const DefaultOAuth2ProxyImageTag = "quay.io/oauth2-proxy/oauth2-proxy:latest" + +// Default image tag for the OpenShift OAuth Proxy +const DefaultOpenShiftOAuthProxyImageTag = "quay.io/openshift/origin-oauth-proxy:latest" + // Default image tag for the core application image const DefaultCoreImageTag = "quay.io/cryostat/cryostat:3.0.0-snapshot" diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index 0e89f2f6a..d417b62ff 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -20,17 +20,18 @@ import ( ) const ( - CryostatHTTPContainerPort int32 = 8181 - CryostatJMXContainerPort int32 = 9091 - GrafanaContainerPort int32 = 3000 - DatasourceContainerPort int32 = 8989 - ReportsContainerPort int32 = 10000 - StoragePort int32 = 8333 - DatabasePort int32 = 5432 - LoopbackAddress string = "127.0.0.1" - OperatorNamePrefix string = "cryostat-operator-" - OperatorDeploymentName string = "cryostat-operator-controller-manager" - HttpPortName string = "http" + AuthProxyHttpContainerPort int32 = 4180 + CryostatHTTPContainerPort int32 = 8181 + CryostatJMXContainerPort int32 = 9091 + GrafanaContainerPort int32 = 3000 + DatasourceContainerPort int32 = 8989 + ReportsContainerPort int32 = 10000 + StoragePort int32 = 8333 + DatabasePort int32 = 5432 + LoopbackAddress string = "127.0.0.1" + OperatorNamePrefix string = "cryostat-operator-" + OperatorDeploymentName string = "cryostat-operator-controller-manager" + HttpPortName string = "http" // CAKey is the key for a CA certificate within a TLS secret CAKey = certMeta.TLSCAKey // Hostname alias for loopback address, to be used for health checks diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index ce23a86ee..7049e0421 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -81,6 +81,12 @@ type Reconciler struct { // Name used for Finalizer that handles Cryostat deletion const cryostatFinalizer = "operator.cryostat.io/cryostat.finalizer" +// Environment variable to override the OAuth2 Proxy image +const oauth2ProxyImageTagEnv = "RELATED_IMAGE_OAUTH2_PROXY" + +// Environment variable to override the core application image +const openshiftOauthProxyImageTagEnv = "RELATED_IMAGE_OPENSHIFT_OAUTH_PROXY" + // Environment variable to override the core application image const coreImageTagEnv = "RELATED_IMAGE_CORE" @@ -364,12 +370,14 @@ func (r *Reconciler) reconcileReports(ctx context.Context, reqLogger logr.Logger func (r *Reconciler) getImageTags() *resources.ImageTags { return &resources.ImageTags{ - 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), + 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), } } diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index be8d8bac6..3bfd96fa2 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -986,12 +986,16 @@ func (c *controllerTest) commonTests() { reportsImg := "my/reports-image:1.0.0-SNAPSHOT" storageImg := "my/storage-image:1.0.0-dev" databaseImg := "my/database-image:1.0.0-dev" + oauth2ProxyImg := "my/auth-proxy:1.0.0-dev" + openshiftAuthProxyImg := "my/openshift-auth-proxy:1.0.0-dev" t.EnvCoreImageTag = &coreImg t.EnvDatasourceImageTag = &datasourceImg t.EnvGrafanaImageTag = &grafanaImg t.EnvReportsImageTag = &reportsImg t.EnvDatabaseImageTag = &databaseImg t.EnvStorageImageTag = &storageImg + t.EnvOAuth2ProxyImageTag = &oauth2ProxyImg + t.EnvOpenShiftOAuthProxyImageTag = &openshiftAuthProxyImg }) It("should create deployment with the expected tags", func() { t.expectMainDeployment() @@ -999,7 +1003,7 @@ func (c *controllerTest) commonTests() { }) It("should set ImagePullPolicy to Always", func() { containers := mainDeploy.Spec.Template.Spec.Containers - Expect(containers).To(HaveLen(5)) + Expect(containers).To(HaveLen(6)) for _, container := range containers { Expect(container.ImagePullPolicy).To(Equal(corev1.PullAlways)) } @@ -1016,12 +1020,16 @@ func (c *controllerTest) commonTests() { reportsImg := "my/reports-image:1.0.0" storageImg := "my/storage-image:1.0.0" databaseImg := "my/database-image:1.0.0" + oauth2ProxyImg := "my/authproxy-image:1.0.0" + openshiftAuthProxyImg := "my/openshift-authproxy-image:1.0.0" t.EnvCoreImageTag = &coreImg t.EnvDatasourceImageTag = &datasourceImg t.EnvGrafanaImageTag = &grafanaImg t.EnvReportsImageTag = &reportsImg t.EnvDatabaseImageTag = &databaseImg t.EnvStorageImageTag = &storageImg + t.EnvOAuth2ProxyImageTag = &oauth2ProxyImg + t.EnvOpenShiftOAuthProxyImageTag = &openshiftAuthProxyImg }) JustBeforeEach(func() { t.reconcileCryostatFully() @@ -1032,8 +1040,9 @@ func (c *controllerTest) commonTests() { }) It("should set ImagePullPolicy to IfNotPresent", func() { containers := mainDeploy.Spec.Template.Spec.Containers - Expect(containers).To(HaveLen(5)) + Expect(containers).To(HaveLen(6)) for _, container := range containers { + fmt.Println(container.Image) Expect(container.ImagePullPolicy).To(Equal(corev1.PullIfNotPresent)) } reportContainers := reportsDeploy.Spec.Template.Spec.Containers @@ -1049,12 +1058,16 @@ func (c *controllerTest) commonTests() { reportsImg := "my/reports-image@sha256:8a23ca5e8c8a343789b8c14558a44a49d35ecd130c18e62edf0d1ad9ce88d37d" storageImg := "my/storage-image@sha256:8b23ca5e8c8a343789b8c14558a44a49d35ecd130c18e62edf0d1ad9ce88d37d" databaseImg := "my/database-image@sha256:8c23ca5e8c8a343789b8c14558a44a49d35ecd130c18e62edf0d1ad9ce88d37d" + oauth2ProxyImage := "my/authproxy-image@sha256:8c23ca5e8c8a343789b8c14558a44a49d35ecd130c18e62edf0d1ad9ce88d37d" + openshiftAuthProxyImage := "my/openshift-authproxy-image@sha256:8c23ca5e8c8a343789b8c14558a44a49d35ecd130c18e62edf0d1ad9ce88d37d" t.EnvCoreImageTag = &coreImg t.EnvDatasourceImageTag = &datasourceImg t.EnvGrafanaImageTag = &grafanaImg t.EnvReportsImageTag = &reportsImg t.EnvDatabaseImageTag = &databaseImg t.EnvStorageImageTag = &storageImg + t.EnvOAuth2ProxyImageTag = &oauth2ProxyImage + t.EnvOpenShiftOAuthProxyImageTag = &openshiftAuthProxyImage }) It("should create deployment with the expected tags", func() { t.expectMainDeployment() @@ -1062,7 +1075,7 @@ func (c *controllerTest) commonTests() { }) It("should set ImagePullPolicy to IfNotPresent", func() { containers := mainDeploy.Spec.Template.Spec.Containers - Expect(containers).To(HaveLen(5)) + Expect(containers).To(HaveLen(6)) for _, container := range containers { Expect(container.ImagePullPolicy).To(Equal(corev1.PullIfNotPresent)) } @@ -1077,10 +1090,14 @@ func (c *controllerTest) commonTests() { datasourceImg := "my/datasource-image:latest" grafanaImg := "my/grafana-image:latest" reportsImg := "my/reports-image:latest" + oauth2ProxyImg := "my/authproxy-image:latest" + openshiftAuthProxyImg := "my/openshift-authproxy-image:latest" t.EnvCoreImageTag = &coreImg t.EnvDatasourceImageTag = &datasourceImg t.EnvGrafanaImageTag = &grafanaImg t.EnvReportsImageTag = &reportsImg + t.EnvOAuth2ProxyImageTag = &oauth2ProxyImg + t.EnvOpenShiftOAuthProxyImageTag = &openshiftAuthProxyImg }) It("should create deployment with the expected tags", func() { t.expectMainDeployment() @@ -1088,7 +1105,7 @@ func (c *controllerTest) commonTests() { }) It("should set ImagePullPolicy to Always", func() { containers := mainDeploy.Spec.Template.Spec.Containers - Expect(containers).To(HaveLen(5)) + Expect(containers).To(HaveLen(6)) for _, container := range containers { Expect(container.ImagePullPolicy).To(Equal(corev1.PullAlways)) } diff --git a/internal/controllers/services.go b/internal/controllers/services.go index 9a4c87408..7147a773f 100644 --- a/internal/controllers/services.go +++ b/internal/controllers/services.go @@ -51,7 +51,7 @@ func (r *Reconciler) reconcileCoreService(ctx context.Context, cr *model.Cryosta { Name: "http", Port: *config.HTTPPort, - TargetPort: intstr.IntOrString{IntVal: constants.CryostatHTTPContainerPort}, + TargetPort: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, }, { Name: "jfr-jmx", @@ -165,7 +165,7 @@ func configureCoreService(cr *model.CryostatInstance) *operatorv1beta2.CoreServi // Apply default HTTP and JMX port if not provided if config.HTTPPort == nil { - httpPort := constants.CryostatHTTPContainerPort + httpPort := constants.AuthProxyHttpContainerPort config.HTTPPort = &httpPort } if config.JMXPort == nil { diff --git a/internal/test/reconciler.go b/internal/test/reconciler.go index 714610ab8..6972373c8 100644 --- a/internal/test/reconciler.go +++ b/internal/test/reconciler.go @@ -25,15 +25,17 @@ import ( // TestReconcilerConfig groups parameters used to create a test Reconciler type TestReconcilerConfig struct { - Client client.Client - EnvDisableTLS *bool - EnvCoreImageTag *string - EnvDatasourceImageTag *string - EnvStorageImageTag *string - EnvDatabaseImageTag *string - EnvGrafanaImageTag *string - EnvReportsImageTag *string - GeneratedPasswords []string + Client client.Client + EnvDisableTLS *bool + EnvOAuth2ProxyImageTag *string + EnvOpenShiftOAuthProxyImageTag *string + EnvCoreImageTag *string + EnvDatasourceImageTag *string + EnvStorageImageTag *string + EnvDatabaseImageTag *string + EnvGrafanaImageTag *string + EnvReportsImageTag *string + GeneratedPasswords []string } func NewTestReconcilerTLS(config *TestReconcilerConfig) common.ReconcilerTLS { @@ -72,6 +74,12 @@ func newTestOSUtils(config *TestReconcilerConfig) *testOSUtils { if config.EnvReportsImageTag != nil { envs["RELATED_IMAGE_REPORTS"] = *config.EnvReportsImageTag } + if config.EnvOAuth2ProxyImageTag != nil { + envs["RELATED_IMAGE_OAUTH2_PROXY"] = *config.EnvOAuth2ProxyImageTag + } + if config.EnvOpenShiftOAuthProxyImageTag != nil { + envs["RELATED_IMAGE_OPENSHIFT_OAUTH_PROXY"] = *config.EnvOpenShiftOAuthProxyImageTag + } return &testOSUtils{envs: envs, passwords: config.GeneratedPasswords} } diff --git a/internal/test/resources.go b/internal/test/resources.go index e7d3529b4..0e046e795 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -699,8 +699,8 @@ func (r *TestResources) NewCryostatService() *corev1.Service { Ports: []corev1.ServicePort{ { Name: "http", - Port: 8181, - TargetPort: intstr.FromInt(8181), + Port: 4180, + TargetPort: intstr.FromInt(4180), }, { Name: "jfr-jmx", @@ -880,7 +880,7 @@ func (r *TestResources) NewTestService() *corev1.Service { Ports: []corev1.ServicePort{ { Name: "test", - Port: 8181, + Port: 4180, }, }, }, @@ -1389,7 +1389,11 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps Value: "10", }, { - Name: "CRYOSTAT_K8S_NAMESPACES", + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_ENABLED", + Value: "true", + }, + { + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_NAMESPACES", Value: strings.Join(r.TargetNamespaces, ","), }, { @@ -2197,7 +2201,7 @@ func (r *TestResources) NewReportSecurityContext(cr *model.CryostatInstance) *co } func (r *TestResources) NewCoreRoute() *routev1.Route { - return r.newRoute(r.Name, 8181) + return r.newRoute(r.Name, 4180) } func (r *TestResources) NewCustomCoreRoute() *routev1.Route { @@ -2308,7 +2312,7 @@ func (r *TestResources) OtherGrafanaRoute() *routev1.Route { } func (r *TestResources) NewCoreIngress() *netv1.Ingress { - return r.newIngress(r.Name, 8181, map[string]string{"custom": "annotation"}, + return r.newIngress(r.Name, 4180, map[string]string{"custom": "annotation"}, map[string]string{"my": "label", "custom": "label"}) } diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index 91bb99163..71b7803b0 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -313,7 +313,7 @@ func configureIngress(name string, cryostatSpec *operatorv1beta2.CryostatSpec) { Service: &netv1.IngressServiceBackend{ Name: name, Port: netv1.ServiceBackendPort{ - Number: 8181, + Number: 4180, }, }, }, diff --git a/internal/tools/const_generator.go b/internal/tools/const_generator.go index 116c4e5ee..dc2bb4f92 100644 --- a/internal/tools/const_generator.go +++ b/internal/tools/const_generator.go @@ -24,6 +24,8 @@ import ( const appNameEnv = "APP_NAME" const operatorVersionEnv = "OPERATOR_VERSION" +const oauth2ProxyImageEnv = "OAUTH2_PROXY_IMG" +const openshiftOauthProxyImageEnv = "OPENSHIFT_OAUTH_PROXY_IMG" const coreImageEnv = "CORE_IMG" const datasourceImageEnv = "DATASOURCE_IMG" const grafanaImageEnv = "GRAFANA_IMG" @@ -39,6 +41,8 @@ func main() { consts := struct { AppName string OperatorVersion string + OAuth2ProxyImageTag string + OpenShiftOAuthProxyImageTag string CoreImageTag string DatasourceImageTag string GrafanaImageTag string @@ -48,6 +52,8 @@ func main() { }{ AppName: getEnvVar(appNameEnv), OperatorVersion: getEnvVar(operatorVersionEnv), + OAuth2ProxyImageTag: getEnvVar(oauth2ProxyImageEnv), + OpenShiftOAuthProxyImageTag: getEnvVar(openshiftOauthProxyImageEnv), CoreImageTag: getEnvVar(coreImageEnv), DatasourceImageTag: getEnvVar(datasourceImageEnv), GrafanaImageTag: getEnvVar(grafanaImageEnv), @@ -86,6 +92,12 @@ const AppName = "{{ .AppName }}" // Version of the Cryostat Operator const OperatorVersion = "{{ .OperatorVersion }}" +// Default image tag for the OAuth2 Proxy +const DefaultOAuth2ProxyImageTag = "{{ .OAuth2ProxyImageTag }}" + +// Default image tag for the OpenShift OAuth Proxy +const DefaultOpenShiftOAuthProxyImageTag = "{{ .OpenShiftOAuthProxyImageTag }}" + // Default image tag for the core application image const DefaultCoreImageTag = "{{ .CoreImageTag }}" From d455719eee5eac03872eb42d5cfe149335064c05 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Mon, 29 Apr 2024 17:11:18 -0400 Subject: [PATCH 28/53] feat(auth): add configuration for htpasswd basic auth (#802) --- api/v1beta2/cryostat_types.go | 23 +++++++++ api/v1beta2/zz_generated.deepcopy.go | 50 +++++++++++++++++++ ...yostat-operator.clusterserviceversion.yaml | 23 ++++++++- .../operator.cryostat.io_cryostats.yaml | 16 ++++++ .../bases/operator.cryostat.io_cryostats.yaml | 16 ++++++ ...yostat-operator.clusterserviceversion.yaml | 21 ++++++++ .../resource_definitions.go | 38 ++++++++++++-- 7 files changed, 182 insertions(+), 5 deletions(-) diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 1c6732897..7689fa659 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -69,6 +69,10 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec Resources *ResourceConfigList `json:"resources,omitempty"` + // Additional configuration options for the authorization proxy. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Options",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} + AuthorizationOptions *AuthorizationOptions `json:"authorizationOptions,omitempty"` // Override default authorization properties for Cryostat on OpenShift. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} @@ -481,6 +485,25 @@ type TemplateConfigMap struct { Filename string `json:"filename"` } +// Authorization options provide additional configurations for the auth proxy. +type AuthorizationOptions struct { + // Reference to a secret and file name containing the Basic authentication htpasswd file + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} + BasicAuth *SecretFile `json:"basicAuth,omitempty"` +} + +type SecretFile struct { + // Name of the secret to reference. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} + SecretName *string `json:"secretName,omitempty"` + // Name of the file within the secret. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + Filename *string `json:"filename,omitempty"` +} + // Authorization properties provide custom permission mapping between Cryostat resources to Kubernetes resources. // If the mapping is updated, Cryostat must be manually restarted. type AuthorizationProperties struct { diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 9c3b8ac6b..050a5ff88 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -56,6 +56,26 @@ func (in *Affinity) DeepCopy() *Affinity { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthorizationOptions) DeepCopyInto(out *AuthorizationOptions) { + *out = *in + if in.BasicAuth != nil { + in, out := &in.BasicAuth, &out.BasicAuth + *out = new(SecretFile) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizationOptions. +func (in *AuthorizationOptions) DeepCopy() *AuthorizationOptions { + if in == nil { + return nil + } + out := new(AuthorizationOptions) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthorizationProperties) DeepCopyInto(out *AuthorizationProperties) { *out = *in @@ -231,6 +251,11 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { *out = new(ResourceConfigList) (*in).DeepCopyInto(*out) } + if in.AuthorizationOptions != nil { + in, out := &in.AuthorizationOptions, &out.AuthorizationOptions + *out = new(AuthorizationOptions) + (*in).DeepCopyInto(*out) + } if in.AuthProperties != nil { in, out := &in.AuthProperties, &out.AuthProperties *out = new(AuthorizationProperties) @@ -643,6 +668,31 @@ func (in *SchedulingConfiguration) DeepCopy() *SchedulingConfiguration { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretFile) DeepCopyInto(out *SecretFile) { + *out = *in + if in.SecretName != nil { + in, out := &in.SecretName, &out.SecretName + *out = new(string) + **out = **in + } + if in.Filename != nil { + in, out := &in.Filename, &out.Filename + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretFile. +func (in *SecretFile) DeepCopy() *SecretFile { + if in == nil { + return nil + } + out := new(SecretFile) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecurityOptions) DeepCopyInto(out *SecurityOptions) { *out = *in diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 5b938a04b..2594ec1ea 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-04-26T21:39:27Z" + createdAt: "2024-04-26T21:51:07Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -553,6 +553,27 @@ spec: path: authProperties.filename x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text + - description: Additional configuration options for the authorization proxy. + displayName: Authorization Options + path: authorizationOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Reference to a secret and file name containing the Basic authentication + htpasswd file + displayName: Basic Auth + path: authorizationOptions.basicAuth + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: Name of the file within the secret. + displayName: Filename + path: authorizationOptions.basicAuth.filename + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: Name of the secret to reference. + displayName: Secret Name + path: authorizationOptions.basicAuth.secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. displayName: Event Templates path: eventTemplates diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 0f89e5eae..dabd5b441 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -5150,6 +5150,22 @@ spec: - configMapName - filename type: object + authorizationOptions: + description: Additional configuration options for the authorization + proxy. + properties: + basicAuth: + description: Reference to a secret and file name containing the + Basic authentication htpasswd file + properties: + filename: + description: Name of the file within the secret. + type: string + secretName: + description: Name of the secret to reference. + type: string + type: object + type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index fe760fd79..6b1484a27 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -5140,6 +5140,22 @@ spec: - configMapName - filename type: object + authorizationOptions: + description: Additional configuration options for the authorization + proxy. + properties: + basicAuth: + description: Reference to a secret and file name containing the + Basic authentication htpasswd file + properties: + filename: + description: Name of the file within the secret. + type: string + secretName: + description: Name of the secret to reference. + type: string + type: object + type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 3580f47b6..a5a31ba7b 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -98,6 +98,27 @@ spec: path: authProperties.filename x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text + - description: Additional configuration options for the authorization proxy. + displayName: Authorization Options + path: authorizationOptions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Reference to a secret and file name containing the Basic authentication + htpasswd file + displayName: Basic Auth + path: authorizationOptions.basicAuth + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: Name of the file within the secret. + displayName: Filename + path: authorizationOptions.basicAuth.filename + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: Name of the secret to reference. + displayName: Secret Name + path: authorizationOptions.basicAuth.secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. displayName: Event Templates path: eventTemplates diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 060c9499c..41f5d6e6a 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -70,7 +70,7 @@ type TLSConfig struct { const ( defaultAuthProxyCpuRequest string = "50m" - defaultAuthProxyMemoryRequest string = "100Mi" + defaultAuthProxyMemoryRequest string = "120Mi" defaultCoreCpuRequest string = "500m" defaultCoreMemoryRequest string = "256Mi" defaultJfrDatasourceCpuRequest string = "200m" @@ -339,6 +339,19 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima } volumes = append(volumes, certVolume) + if isBasicAuthEnabled(cr) { + volumes = append(volumes, + corev1.Volume{ + Name: "auth-proxy-htpasswd", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: *cr.Spec.AuthorizationOptions.BasicAuth.SecretName, + }, + }, + }, + ) + } + // Add any EventTemplates as volumes for _, template := range cr.Spec.EventTemplates { eventTemplateVolume := corev1.Volume{ @@ -618,9 +631,7 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp }, } - basicAuthEnabled := false args := []string{ - fmt.Sprintf("--skip-provider-button=%t", !basicAuthEnabled), fmt.Sprintf("--upstream=http://localhost:%d/", constants.CryostatHTTPContainerPort), fmt.Sprintf("--upstream=http://localhost:%d/grafana/", constants.GrafanaContainerPort), fmt.Sprintf("--upstream=http://localhost:%d/storage/", constants.StoragePort), @@ -639,6 +650,22 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp "--bypass-auth-for=^/health", "--proxy-prefix=/oauth2", } + + volumeMounts := []corev1.VolumeMount{} + if isBasicAuthEnabled(cr) { + mountPath := fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s", *cr.Spec.AuthorizationOptions.BasicAuth.SecretName) + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: "auth-proxy-htpasswd", + MountPath: mountPath, + ReadOnly: true, + }) + args = append(args, fmt.Sprintf("--htpasswd-file=%s/%s", mountPath, *cr.Spec.AuthorizationOptions.BasicAuth.Filename)) + } + + args = append(args, + fmt.Sprintf("--skip-provider-button=%t", !isBasicAuthEnabled(cr)), + ) + // if tls != nil { // "--https-address=:8443", // "--tls-cert=/etc/tls/private/tls.crt", @@ -651,7 +678,7 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp Name: cr.Name + "-auth-proxy", Image: imageTag, ImagePullPolicy: getPullPolicy(imageTag), - // VolumeMounts: mounts, + VolumeMounts: volumeMounts, Ports: []corev1.ContainerPort{ { ContainerPort: constants.AuthProxyHttpContainerPort, @@ -1498,7 +1525,10 @@ func newVolumeForCR(cr *model.CryostatInstance) []corev1.Volume { func useEmptyDir(cr *model.CryostatInstance) bool { return cr.Spec.StorageOptions != nil && cr.Spec.StorageOptions.EmptyDir != nil && cr.Spec.StorageOptions.EmptyDir.Enabled +} +func isBasicAuthEnabled(cr *model.CryostatInstance) bool { + return cr.Spec.AuthorizationOptions != nil && cr.Spec.AuthorizationOptions.BasicAuth != nil && cr.Spec.AuthorizationOptions.BasicAuth.SecretName != nil && cr.Spec.AuthorizationOptions.BasicAuth.Filename != nil } func checkResourceRequestWithLimit(requests, limits corev1.ResourceList) { From b9b0365cd17bea51b256e42afedc8a8fa5060564 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Fri, 3 May 2024 09:25:30 -0400 Subject: [PATCH 29/53] feat(auth): add config option to deploy oauth2_proxy instead of openshift-oauth-proxy (#803) --- api/v1beta2/cryostat_types.go | 23 +- api/v1beta2/zz_generated.deepcopy.go | 31 +++ ...yostat-operator.clusterserviceversion.yaml | 25 +- .../operator.cryostat.io_cryostats.yaml | 60 ++++- .../bases/operator.cryostat.io_cryostats.yaml | 60 ++++- ...yostat-operator.clusterserviceversion.yaml | 23 +- .../resource_definitions.go | 244 +++++++++++++++--- internal/controllers/configmaps.go | 95 +++++++ internal/controllers/reconciler.go | 10 +- internal/controllers/reconciler_test.go | 2 +- internal/controllers/secrets.go | 24 ++ internal/test/resources.go | 21 ++ 12 files changed, 579 insertions(+), 39 deletions(-) diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 7689fa659..f66ed2b0d 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -15,6 +15,7 @@ package v1beta2 import ( + authzv1 "k8s.io/api/authorization/v1" corev1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -487,12 +488,32 @@ type TemplateConfigMap struct { // Authorization options provide additional configurations for the auth proxy. type AuthorizationOptions struct { - // Reference to a secret and file name containing the Basic authentication htpasswd file + // Configuration for OpenShift RBAC to define which OpenShift user accounts may access the Cryostat application. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="OpenShift SSO" + OpenShiftSSO *OpenShiftSSOConfig `json:"openShiftSSO,omitempty"` + // Reference to a secret and file name containing the Basic authentication htpasswd file. If deploying on OpenShift this + // defines additional user accounts that can access the Cryostat application, on top of the OpenShift user accounts which + // pass the OpenShift SSO Roles checks. If not on OpenShift then this defines the only user accounts that have access. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} BasicAuth *SecretFile `json:"basicAuth,omitempty"` } +type OpenShiftSSOConfig struct { + // Disable OpenShift SSO integration and allow all users to access the application without authentication. This + // will also bypass the BasicAuth, if specified. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable OpenShift SSO",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Disable *bool `json:"disable,omitempty"` + // The SubjectAccessReview or TokenAccessReview that all clients (users visiting the application via web browser as well + // as CLI utilities and other programs presenting Bearer auth tokens) must pass in order to access the application. + // If not specified, the default role required is "create pods/exec" in the Cryostat application's installation namespace. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + AccessReview *authzv1.ResourceAttributes `json:"accessReview,omitempty"` +} + type SecretFile struct { // Name of the secret to reference. // +optional diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 050a5ff88..929146417 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -20,6 +20,7 @@ package v1beta2 import ( + authorizationv1 "k8s.io/api/authorization/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -59,6 +60,11 @@ func (in *Affinity) DeepCopy() *Affinity { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthorizationOptions) DeepCopyInto(out *AuthorizationOptions) { *out = *in + if in.OpenShiftSSO != nil { + in, out := &in.OpenShiftSSO, &out.OpenShiftSSO + *out = new(OpenShiftSSOConfig) + (*in).DeepCopyInto(*out) + } if in.BasicAuth != nil { in, out := &in.BasicAuth, &out.BasicAuth *out = new(SecretFile) @@ -455,6 +461,31 @@ func (in *NetworkConfigurationList) DeepCopy() *NetworkConfigurationList { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenShiftSSOConfig) DeepCopyInto(out *OpenShiftSSOConfig) { + *out = *in + if in.Disable != nil { + in, out := &in.Disable, &out.Disable + *out = new(bool) + **out = **in + } + if in.AccessReview != nil { + in, out := &in.AccessReview, &out.AccessReview + *out = new(authorizationv1.ResourceAttributes) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenShiftSSOConfig. +func (in *OpenShiftSSOConfig) DeepCopy() *OpenShiftSSOConfig { + if in == nil { + return nil + } + out := new(OpenShiftSSOConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OperandMetadata) DeepCopyInto(out *OperandMetadata) { *out = *in diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 2594ec1ea..18202da0e 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-04-26T21:51:07Z" + createdAt: "2024-05-03T13:22:52Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -559,7 +559,10 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:advanced - description: Reference to a secret and file name containing the Basic authentication - htpasswd file + htpasswd file. If deploying on OpenShift this defines additional user accounts + that can access the Cryostat application, on top of the OpenShift user accounts + which pass the OpenShift SSO Roles checks. If not on OpenShift then this + defines the only user accounts that have access. displayName: Basic Auth path: authorizationOptions.basicAuth x-descriptors: @@ -574,6 +577,24 @@ spec: path: authorizationOptions.basicAuth.secretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret + - description: Configuration for OpenShift RBAC to define which OpenShift user + accounts may access the Cryostat application. + displayName: OpenShift SSO + path: authorizationOptions.openShiftSSO + - description: The SubjectAccessReview or TokenAccessReview that all clients + (users visiting the application via web browser as well as CLI utilities + and other programs presenting Bearer auth tokens) must pass in order to + access the application. If not specified, the default role required is "create + pods/exec" in the Cryostat application's installation namespace. + displayName: Access Review + path: authorizationOptions.openShiftSSO.accessReview + - description: Disable OpenShift SSO integration and allow all users to access + the application without authentication. This will also bypass the BasicAuth, + if specified. + displayName: Disable OpenShift SSO + path: authorizationOptions.openShiftSSO.disable + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. displayName: Event Templates path: eventTemplates diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index dabd5b441..460244d0c 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -5156,7 +5156,11 @@ spec: properties: basicAuth: description: Reference to a secret and file name containing the - Basic authentication htpasswd file + Basic authentication htpasswd file. If deploying on OpenShift + this defines additional user accounts that can access the Cryostat + application, on top of the OpenShift user accounts which pass + the OpenShift SSO Roles checks. If not on OpenShift then this + defines the only user accounts that have access. properties: filename: description: Name of the file within the secret. @@ -5165,6 +5169,60 @@ spec: description: Name of the secret to reference. type: string type: object + openShiftSSO: + description: Configuration for OpenShift RBAC to define which + OpenShift user accounts may access the Cryostat application. + properties: + accessReview: + description: The SubjectAccessReview or TokenAccessReview + that all clients (users visiting the application via web + browser as well as CLI utilities and other programs presenting + Bearer auth tokens) must pass in order to access the application. + If not specified, the default role required is "create pods/exec" + in the Cryostat application's installation namespace. + properties: + group: + description: Group is the API Group of the Resource. "*" + means all. + type: string + name: + description: Name is the name of the resource being requested + for a "get" or deleted for a "delete". "" (empty) means + all. + type: string + namespace: + description: Namespace is the namespace of the action + being requested. Currently, there is no distinction + between no namespace and all namespaces "" (empty) is + defaulted for LocalSubjectAccessReviews "" (empty) is + empty for cluster-scoped resources "" (empty) means + "all" for namespace scoped resources from a SubjectAccessReview + or SelfSubjectAccessReview + type: string + resource: + description: Resource is one of the existing resource + types. "*" means all. + type: string + subresource: + description: Subresource is one of the existing resource + types. "" means none. + type: string + verb: + description: 'Verb is a kubernetes resource API verb, + like: get, list, watch, create, update, delete, proxy. "*" + means all.' + type: string + version: + description: Version is the API Version of the Resource. "*" + means all. + type: string + type: object + disable: + description: Disable OpenShift SSO integration and allow all + users to access the application without authentication. + This will also bypass the BasicAuth, if specified. + type: boolean + type: object type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 6b1484a27..4bb2140fc 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -5146,7 +5146,11 @@ spec: properties: basicAuth: description: Reference to a secret and file name containing the - Basic authentication htpasswd file + Basic authentication htpasswd file. If deploying on OpenShift + this defines additional user accounts that can access the Cryostat + application, on top of the OpenShift user accounts which pass + the OpenShift SSO Roles checks. If not on OpenShift then this + defines the only user accounts that have access. properties: filename: description: Name of the file within the secret. @@ -5155,6 +5159,60 @@ spec: description: Name of the secret to reference. type: string type: object + openShiftSSO: + description: Configuration for OpenShift RBAC to define which + OpenShift user accounts may access the Cryostat application. + properties: + accessReview: + description: The SubjectAccessReview or TokenAccessReview + that all clients (users visiting the application via web + browser as well as CLI utilities and other programs presenting + Bearer auth tokens) must pass in order to access the application. + If not specified, the default role required is "create pods/exec" + in the Cryostat application's installation namespace. + properties: + group: + description: Group is the API Group of the Resource. "*" + means all. + type: string + name: + description: Name is the name of the resource being requested + for a "get" or deleted for a "delete". "" (empty) means + all. + type: string + namespace: + description: Namespace is the namespace of the action + being requested. Currently, there is no distinction + between no namespace and all namespaces "" (empty) is + defaulted for LocalSubjectAccessReviews "" (empty) is + empty for cluster-scoped resources "" (empty) means + "all" for namespace scoped resources from a SubjectAccessReview + or SelfSubjectAccessReview + type: string + resource: + description: Resource is one of the existing resource + types. "*" means all. + type: string + subresource: + description: Subresource is one of the existing resource + types. "" means none. + type: string + verb: + description: 'Verb is a kubernetes resource API verb, + like: get, list, watch, create, update, delete, proxy. "*" + means all.' + type: string + version: + description: Version is the API Version of the Resource. "*" + means all. + type: string + type: object + disable: + description: Disable OpenShift SSO integration and allow all + users to access the application without authentication. + This will also bypass the BasicAuth, if specified. + type: boolean + type: object type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index a5a31ba7b..c85c5c395 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -104,7 +104,10 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:advanced - description: Reference to a secret and file name containing the Basic authentication - htpasswd file + htpasswd file. If deploying on OpenShift this defines additional user accounts + that can access the Cryostat application, on top of the OpenShift user accounts + which pass the OpenShift SSO Roles checks. If not on OpenShift then this + defines the only user accounts that have access. displayName: Basic Auth path: authorizationOptions.basicAuth x-descriptors: @@ -119,6 +122,24 @@ spec: path: authorizationOptions.basicAuth.secretName x-descriptors: - urn:alm:descriptor:io.kubernetes:Secret + - description: Configuration for OpenShift RBAC to define which OpenShift user + accounts may access the Cryostat application. + displayName: OpenShift SSO + path: authorizationOptions.openShiftSSO + - description: The SubjectAccessReview or TokenAccessReview that all clients + (users visiting the application via web browser as well as CLI utilities + and other programs presenting Bearer auth tokens) must pass in order to + access the application. If not specified, the default role required is "create + pods/exec" in the Cryostat application's installation namespace. + displayName: Access Review + path: authorizationOptions.openShiftSSO.accessReview + - description: Disable OpenShift SSO integration and allow all users to access + the application without authentication. This will also bypass the BasicAuth, + if specified. + displayName: Disable OpenShift SSO + path: authorizationOptions.openShiftSSO.disable + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. displayName: Event Templates path: eventTemplates diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 41f5d6e6a..a04805f85 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -15,6 +15,7 @@ package resource_definitions import ( + "encoding/json" "fmt" "net/url" "regexp" @@ -26,6 +27,7 @@ import ( "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/controllers/model" appsv1 "k8s.io/api/apps/v1" + authzv1 "k8s.io/api/authorization/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -79,10 +81,12 @@ const ( defaultGrafanaMemoryRequest string = "120Mi" defaultReportCpuRequest string = "200m" defaultReportMemoryRequest string = "384Mi" + OAuth2ConfigFileName string = "alpha_config.json" + OAuth2ConfigFilePath string = "/etc/oauth2_proxy/alpha_config" ) func NewDeploymentForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *ImageTags, - tls *TLSConfig, fsGroup int64, openshift bool) *appsv1.Deployment { + tls *TLSConfig, fsGroup int64, openshift bool) (*appsv1.Deployment, error) { // Force one replica to avoid lock file and PVC contention replicas := int32(1) @@ -140,6 +144,10 @@ func NewDeploymentForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTa } common.MergeLabelsAndAnnotations(&podTemplateMeta, defaultPodLabels, nil) + pod, err := NewPodForCR(cr, specs, imageTags, tls, fsGroup, openshift) + if err != nil { + return nil, err + } return &appsv1.Deployment{ ObjectMeta: deploymentMeta, Spec: appsv1.DeploymentSpec{ @@ -153,14 +161,14 @@ func NewDeploymentForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTa }, Template: corev1.PodTemplateSpec{ ObjectMeta: podTemplateMeta, - Spec: *NewPodForCR(cr, specs, imageTags, tls, fsGroup, openshift), + Spec: *pod, }, Replicas: &replicas, Strategy: appsv1.DeploymentStrategy{ Type: appsv1.RecreateDeploymentStrategyType, }, }, - } + }, nil } func NewDeploymentForReports(cr *model.CryostatInstance, imageTags *ImageTags, tls *TLSConfig, @@ -245,14 +253,18 @@ func NewDeploymentForReports(cr *model.CryostatInstance, imageTags *ImageTags, t } func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *ImageTags, - tls *TLSConfig, fsGroup int64, openshift bool) *corev1.PodSpec { + tls *TLSConfig, fsGroup int64, openshift bool) (*corev1.PodSpec, error) { + authProxy, err := NewAuthProxyContainer(cr, specs, imageTags.OAuth2ProxyImageTag, imageTags.OpenShiftOAuthProxyImageTag, tls, openshift) + if err != nil { + return nil, err + } containers := []corev1.Container{ NewCoreContainer(cr, specs, imageTags.CoreImageTag, tls, openshift), NewGrafanaContainer(cr, imageTags.GrafanaImageTag, tls), NewJfrDatasourceContainer(cr, imageTags.DatasourceImageTag), NewStorageContainer(cr, imageTags.StorageImageTag, tls), newDatabaseContainer(cr, imageTags.DatabaseImageTag, tls), - NewAuthProxyContainer(cr, specs, imageTags.OAuth2ProxyImageTag, imageTags.OpenShiftOAuthProxyImageTag, tls, openshift), + *authProxy, } volumes := newVolumeForCR(cr) @@ -339,10 +351,31 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima } volumes = append(volumes, certVolume) + if !openshift { + // if not deploying openshift-oauth-proxy then we must be deploying oauth2_proxy instead + volumes = append(volumes, corev1.Volume{ + Name: cr.Name + "-oauth2-proxy-cfg", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Name + "-oauth2-proxy-cfg", + }, + Items: []corev1.KeyToPath{ + { + Key: OAuth2ConfigFileName, + Path: OAuth2ConfigFileName, + Mode: &readOnlyMode, + }, + }, + }, + }, + }) + } + if isBasicAuthEnabled(cr) { volumes = append(volumes, corev1.Volume{ - Name: "auth-proxy-htpasswd", + Name: cr.Name + "-auth-proxy-htpasswd", VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ SecretName: *cr.Spec.AuthorizationOptions.BasicAuth.SecretName, @@ -425,7 +458,7 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima NodeSelector: nodeSelector, Affinity: affinity, Tolerations: tolerations, - } + }, nil } func NewReportContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { @@ -601,15 +634,15 @@ func NewAuthProxyContainerResource(cr *model.CryostatInstance) *corev1.ResourceR } func NewAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, oauth2ProxyImageTag string, openshiftAuthProxyImageTag string, - tls *TLSConfig, openshift bool) corev1.Container { - // if (openshift) { - return NewOpenShiftAuthProxyContainer(cr, specs, openshiftAuthProxyImageTag, tls) - // } - // return NewOAuth2ProxyContainer(cr, specs, oauth2ProxyImageTag, tls) + tls *TLSConfig, openshift bool) (*corev1.Container, error) { + if openshift { + return NewOpenShiftAuthProxyContainer(cr, specs, openshiftAuthProxyImageTag, tls) + } + return NewOAuth2ProxyContainer(cr, specs, oauth2ProxyImageTag, tls) } func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag string, - tls *TLSConfig) corev1.Container { + tls *TLSConfig) (*corev1.Container, error) { var containerSc *corev1.SecurityContext if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.AuthProxySecurityContext != nil { containerSc = cr.Spec.SecurityOptions.AuthProxySecurityContext @@ -626,7 +659,7 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp probeHandler := corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Port: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, - Path: "/ping", + Path: "/oauth2/healthz", Scheme: corev1.URISchemeHTTP, }, } @@ -635,27 +668,36 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp fmt.Sprintf("--upstream=http://localhost:%d/", constants.CryostatHTTPContainerPort), fmt.Sprintf("--upstream=http://localhost:%d/grafana/", constants.GrafanaContainerPort), fmt.Sprintf("--upstream=http://localhost:%d/storage/", constants.StoragePort), - "--cookie-secret=REPLACEME", fmt.Sprintf("--openshift-service-account=%s", cr.Name), "--proxy-websockets=true", fmt.Sprintf("--http-address=0.0.0.0:%d", constants.AuthProxyHttpContainerPort), - fmt.Sprintf( - `--openshift-sar=[{"group":"","name":"","namespace":"%s","resource":"pods","subresource":"exec","verb":"create","version":""}]`, - cr.InstallNamespace, - ), - fmt.Sprintf( - `--openshift-delegate-urls={"/":{"group":"","name":"","namespace":"%s","resource":"pods","subresource":"exec","verb":"create","version":""}}`, - cr.InstallNamespace, - ), - "--bypass-auth-for=^/health", "--proxy-prefix=/oauth2", } + if isOpenShiftAuthProxyDisabled(cr) { + args = append(args, "--bypass-auth-for=.*") + } else { + args = append(args, "--bypass-auth-for=^/health(/liveness)?$") + } + + subjectAccessReviewJson, err := json.Marshal([]authzv1.ResourceAttributes{getOpenShiftAccessReview(cr)}) + if err != nil { + return nil, err + } + args = append(args, fmt.Sprintf("--openshift-sar=%s", string(subjectAccessReviewJson))) + + delegateUrls := make(map[string]authzv1.ResourceAttributes) + delegateUrls["/"] = getOpenShiftAccessReview(cr) + tokenReviewJson, err := json.Marshal(delegateUrls) + if err != nil { + return nil, err + } + args = append(args, fmt.Sprintf("--openshift-delegate-urls=%s", string(tokenReviewJson))) volumeMounts := []corev1.VolumeMount{} if isBasicAuthEnabled(cr) { - mountPath := fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s", *cr.Spec.AuthorizationOptions.BasicAuth.SecretName) + mountPath := "/var/run/secrets/operator.cryostat.io" volumeMounts = append(volumeMounts, corev1.VolumeMount{ - Name: "auth-proxy-htpasswd", + Name: cr.Name + "-auth-proxy-htpasswd", MountPath: mountPath, ReadOnly: true, }) @@ -674,7 +716,19 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp args = append(args, "--https-address=") // } - return corev1.Container{ + cookieOptional := false + envsFrom := []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Name + "-oauth2-cookie", + }, + Optional: &cookieOptional, + }, + }, + } + + return &corev1.Container{ Name: cr.Name + "-auth-proxy", Image: imageTag, ImagePullPolicy: getPullPolicy(imageTag), @@ -685,20 +739,148 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp }, }, // Env: envs, - // EnvFrom: envsFrom, + EnvFrom: envsFrom, Resources: *NewAuthProxyContainerResource(cr), LivenessProbe: &corev1.Probe{ ProbeHandler: probeHandler, }, SecurityContext: containerSc, Args: args, + }, nil +} + +func isOpenShiftAuthProxyDisabled(cr *model.CryostatInstance) bool { + if cr.Spec.AuthorizationOptions != nil && cr.Spec.AuthorizationOptions.OpenShiftSSO != nil && cr.Spec.AuthorizationOptions.OpenShiftSSO.Disable != nil { + return *cr.Spec.AuthorizationOptions.OpenShiftSSO.Disable + } + return false +} + +func getOpenShiftAccessReview(cr *model.CryostatInstance) authzv1.ResourceAttributes { + if cr.Spec.AuthorizationOptions != nil && cr.Spec.AuthorizationOptions.OpenShiftSSO != nil && cr.Spec.AuthorizationOptions.OpenShiftSSO.AccessReview != nil { + return *cr.Spec.AuthorizationOptions.OpenShiftSSO.AccessReview + } + return getDefaultOpenShiftAccessRole(cr) +} + +func getDefaultOpenShiftAccessRole(cr *model.CryostatInstance) authzv1.ResourceAttributes { + return authzv1.ResourceAttributes{ + Namespace: cr.InstallNamespace, + Verb: "create", + Group: "", + Version: "", + Resource: "pods", + Subresource: "exec", + Name: "", } } -// func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag string, -// tls *TLSConfig) corev1.Container { +func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag string, + tls *TLSConfig) (*corev1.Container, error) { + var containerSc *corev1.SecurityContext + if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.AuthProxySecurityContext != nil { + containerSc = cr.Spec.SecurityOptions.AuthProxySecurityContext + } else { + privEscalation := false + containerSc = &corev1.SecurityContext{ + AllowPrivilegeEscalation: &privEscalation, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{constants.CapabilityAll}, + }, + } + } + + probeHandler := corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, + Path: "/ping", + Scheme: corev1.URISchemeHTTP, + }, + } + + args := []string{ + fmt.Sprintf("--alpha-config=%s/%s", OAuth2ConfigFilePath, OAuth2ConfigFileName), + } + + envs := []corev1.EnvVar{ + { + Name: "OAUTH2_PROXY_REDIRECT_URL", + Value: fmt.Sprintf("http://localhost:%d/oauth2/callback", constants.AuthProxyHttpContainerPort), + }, + { + Name: "OAUTH2_PROXY_EMAIL_DOMAINS", + Value: "*", + }, + } + + cookieOptional := false + envsFrom := []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Name + "-oauth2-cookie", + }, + Optional: &cookieOptional, + }, + }, + } -// } + volumeMounts := []corev1.VolumeMount{ + { + Name: cr.Name + "-oauth2-proxy-cfg", + MountPath: OAuth2ConfigFilePath, + ReadOnly: true, + }, + } + + if isBasicAuthEnabled(cr) { + mountPath := "/var/run/secrets/operator.cryostat.io" + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: cr.Name + "-auth-proxy-htpasswd", + MountPath: mountPath, + ReadOnly: true, + }) + envs = append(envs, []corev1.EnvVar{ + { + Name: "OAUTH2_PROXY_HTPASSWD_FILE", + Value: mountPath + "/" + *cr.Spec.AuthorizationOptions.BasicAuth.Filename, + }, + { + Name: "OAUTH2_PROXY_HTPASSWD_USER_GROUP", + Value: "write", + }, + { + Name: "OAUTH2_PROXY_SKIP_AUTH_ROUTES", + Value: "^/health(/liveness)?$", + }, + }...) + } else { + envs = append(envs, corev1.EnvVar{ + Name: "OAUTH2_PROXY_SKIP_AUTH_ROUTES", + Value: ".*", + }) + } + + return &corev1.Container{ + Name: cr.Name + "-auth-proxy", + Image: imageTag, + ImagePullPolicy: getPullPolicy(imageTag), + VolumeMounts: volumeMounts, + Ports: []corev1.ContainerPort{ + { + ContainerPort: constants.AuthProxyHttpContainerPort, + }, + }, + Env: envs, + EnvFrom: envsFrom, + Resources: *NewAuthProxyContainerResource(cr), + LivenessProbe: &corev1.Probe{ + ProbeHandler: probeHandler, + }, + SecurityContext: containerSc, + Args: args, + }, nil +} func NewCoreContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { resources := &corev1.ResourceRequirements{} diff --git a/internal/controllers/configmaps.go b/internal/controllers/configmaps.go index 73e6c7003..0f3380fba 100644 --- a/internal/controllers/configmaps.go +++ b/internal/controllers/configmaps.go @@ -16,10 +16,14 @@ package controllers import ( "context" + "encoding/json" "fmt" + resources "github.com/cryostatio/cryostat-operator/internal/controllers/common/resource_definitions" + "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/controllers/model" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) @@ -34,6 +38,87 @@ func (r *Reconciler) reconcileLockConfigMap(ctx context.Context, cr *model.Cryos return r.createOrUpdateConfigMap(ctx, cm, cr.Object) } +type oauth2ProxyAlphaConfig struct { + Server alphaConfigServer `json:"server,omitempty"` + UpstreamConfig alphaConfigUpstreamConfig `json:"upstreamConfig,omitempty"` + Providers []alphaConfigProvider `json:"providers,omitempty"` +} + +type alphaConfigServer struct { + BindAddress string `json:"BindAddress,omitempty"` +} + +type alphaConfigUpstreamConfig struct { + ProxyRawPath bool `json:"proxyRawPath,omitempty"` + Upstreams []alphaConfigUpstream `json:"upstreams,omitempty"` +} + +type alphaConfigProvider struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + ClientId string `json:"clientId,omitempty"` + ClientSecret string `json:"clientSecret,omitempty"` + Provider string `json:"provider,omitempty"` +} + +type alphaConfigUpstream struct { + Id string `json:"id,omitempty"` + Path string `json:"path,omitempty"` + RewriteTarget string `json:"rewriteTarget,omitempty"` + Uri string `json:"uri,omitempty"` + PassHostHeader bool `json:"passHostHeader,omitempty"` + ProxyWebSockets bool `json:"proxyWebSockets,omitempty"` +} + +func (r *Reconciler) reconcileOAuth2ProxyConfig(ctx context.Context, cr *model.CryostatInstance) error { + immutable := true + cfg := &oauth2ProxyAlphaConfig{ + Server: alphaConfigServer{BindAddress: fmt.Sprintf("http://0.0.0.0:%d", constants.AuthProxyHttpContainerPort)}, + UpstreamConfig: alphaConfigUpstreamConfig{ProxyRawPath: true, Upstreams: []alphaConfigUpstream{ + { + Id: "cryostat", + Path: "/", + Uri: fmt.Sprintf("http://localhost:%d", constants.CryostatHTTPContainerPort), + }, + { + Id: "grafana", + Path: "/grafana/", + Uri: fmt.Sprintf("http://localhost:%d", constants.GrafanaContainerPort), + }, + { + Id: "storage", + Path: "^/storage/(.*)$", + RewriteTarget: "/$1", + Uri: fmt.Sprintf("http://localhost:%d", constants.StoragePort), + PassHostHeader: false, + ProxyWebSockets: false, + }, + }}, + Providers: []alphaConfigProvider{{Id: "dummy", Name: "Unused - Sign In Below", ClientId: "CLIENT_ID", ClientSecret: "CLIENT_SECRET", Provider: "google"}}, + } + + data := make(map[string]string) + json, err := json.Marshal(cfg) + if err != nil { + return err + } + data[resources.OAuth2ConfigFileName] = string(json) + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: cr.Name + "-oauth2-proxy-cfg", + Namespace: cr.InstallNamespace, + }, + Immutable: &immutable, + Data: data, + } + + if r.IsOpenShift { + return r.deleteConfigMap(ctx, cm) + } else { + return r.createOrUpdateConfigMap(ctx, cm, cr.Object) + } +} + func (r *Reconciler) createOrUpdateConfigMap(ctx context.Context, cm *corev1.ConfigMap, owner metav1.Object) error { op, err := controllerutil.CreateOrUpdate(ctx, r.Client, cm, func() error { // Set the Cryostat CR as controller @@ -48,3 +133,13 @@ func (r *Reconciler) createOrUpdateConfigMap(ctx context.Context, cm *corev1.Con r.Log.Info(fmt.Sprintf("Config Map %s", op), "name", cm.Name, "namespace", cm.Namespace) return nil } + +func (r *Reconciler) deleteConfigMap(ctx context.Context, cm *corev1.ConfigMap) error { + err := r.Client.Delete(ctx, cm) + if err != nil && !errors.IsNotFound(err) { + r.Log.Error(err, "Could not delete ConfigMap", "name", cm.Name, "namespace", cm.Namespace) + return err + } + r.Log.Info("ConfigMap deleted", "name", cm.Name, "namespace", cm.Namespace) + return nil +} diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index 7049e0421..8ed3a3b25 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -194,6 +194,11 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn return reconcile.Result{}, err } + err = r.reconcileOAuth2ProxyConfig(ctx, cr) + if err != nil { + return reconcile.Result{}, err + } + err = r.reconcilePVC(ctx, cr) if err != nil { return reconcile.Result{}, err @@ -268,7 +273,10 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn return reportsResult, err } - deployment := resources.NewDeploymentForCR(cr, serviceSpecs, imageTags, tlsConfig, *fsGroup, r.IsOpenShift) + deployment, err := resources.NewDeploymentForCR(cr, serviceSpecs, imageTags, tlsConfig, *fsGroup, r.IsOpenShift) + if err != nil { + return reconcile.Result{}, err + } err = r.createOrUpdateDeployment(ctx, deployment, cr.Object) if err != nil { return reconcile.Result{}, err diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 3bfd96fa2..7d8ed2139 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -66,7 +66,7 @@ type cryostatTestInput struct { func (c *controllerTest) commonBeforeEach() *cryostatTestInput { t := &cryostatTestInput{ TestReconcilerConfig: test.TestReconcilerConfig{ - GeneratedPasswords: []string{"grafana", "credentials_database", "encryption_key", "object_storage", "jmx", "keystore"}, + GeneratedPasswords: []string{"auth_cookie_secret", "grafana", "credentials_database", "encryption_key", "object_storage", "jmx", "keystore"}, }, TestResources: &test.TestResources{ Name: "cryostat", diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index b2dc3209c..6118ce55c 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -26,6 +26,9 @@ import ( ) func (r *Reconciler) reconcileSecrets(ctx context.Context, cr *model.CryostatInstance) error { + if err := r.reconcileAuthProxyCookieSecret(ctx, cr); err != nil { + return err + } if err := r.reconcileGrafanaSecret(ctx, cr); err != nil { return err } @@ -38,6 +41,27 @@ func (r *Reconciler) reconcileSecrets(ctx context.Context, cr *model.CryostatIns return r.reconcileJMXSecret(ctx, cr) } +func (r *Reconciler) reconcileAuthProxyCookieSecret(ctx context.Context, cr *model.CryostatInstance) error { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: cr.Name + "-oauth2-cookie", + Namespace: cr.InstallNamespace, + }, + } + + return r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { + if secret.StringData == nil { + secret.StringData = map[string]string{} + } + + // secret is generated, so don't regenerate it when updating + if secret.CreationTimestamp.IsZero() { + secret.StringData["OAUTH2_PROXY_COOKIE_SECRET"] = r.GenPasswd(32) + } + return nil + }) +} + func (r *Reconciler) reconcileGrafanaSecret(ctx context.Context, cr *model.CryostatInstance) error { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ diff --git a/internal/test/resources.go b/internal/test/resources.go index 0e046e795..fe667e290 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -2111,6 +2111,27 @@ func (r *TestResources) newVolumes(certProjections []corev1.VolumeProjection) [] }, }) + if !r.OpenShift { + readOnlyMode := int32(0440) + volumes = append(volumes, corev1.Volume{ + Name: r.Name + "-oauth2-proxy-cfg", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: r.Name + "-oauth2-proxy-cfg", + }, + Items: []corev1.KeyToPath{ + { + Key: "alpha_config.json", + Path: "alpha_config.json", + Mode: &readOnlyMode, + }, + }, + }, + }, + }) + } + return volumes } From c1c350cf7598806695b896a98b4af1bf656a007a Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Fri, 3 May 2024 09:27:40 -0400 Subject: [PATCH 30/53] fix(discovery): correct k8s API discovery configuration (#804) --- .../resource_definitions.go | 59 +++++++++---------- internal/controllers/reconciler_test.go | 6 +- internal/test/resources.go | 40 ++++++++----- 3 files changed, 58 insertions(+), 47 deletions(-) diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index a04805f85..cd3e8036e 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -988,14 +988,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Name: "CRYOSTAT_ENABLE_JDP_BROADCAST", Value: "false", }, - { - Name: "CRYOSTAT_DISCOVERY_KUBERNETES_ENABLED", - Value: "true", - }, - { - Name: "CRYOSTAT_DISCOVERY_KUBERNETES_NAMESPACES", - Value: strings.Join(cr.TargetNamespaces, ","), - }, } mounts := []corev1.VolumeMount{ @@ -1116,7 +1108,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag targetCacheSize := "-1" targetCacheTTL := "10" if cr.Spec.JmxCacheOptions != nil { - if cr.Spec.JmxCacheOptions.TargetCacheSize != 0 { targetCacheSize = strconv.Itoa(int(cr.Spec.JmxCacheOptions.TargetCacheSize)) } @@ -1146,37 +1137,43 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag }, } + k8sDiscoveryEnabled := true + k8sDiscoveryPortNames := "jfr-jmx" + k8sDiscoveryPortNumbers := "9091" if cr.Spec.TargetDiscoveryOptions != nil { - var portNames string + k8sDiscoveryEnabled = !cr.Spec.TargetDiscoveryOptions.BuiltInDiscoveryDisabled + if len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames) > 0 { - portNames = strings.Join(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames[:], ",") + k8sDiscoveryPortNames = strings.Join(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames[:], ",") } else if cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNames { - portNames = "-" - } - if len(portNames) > 0 { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_DISCOVERY_K8S_PORT_NAMES", - Value: portNames, - }, - ) + k8sDiscoveryPortNames = "" } - portNumbers := "" if len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNumbers) > 0 { - portNumbers = strings.Trim(strings.ReplaceAll(fmt.Sprint(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNumbers), " ", ","), "[]") + k8sDiscoveryPortNumbers = strings.Trim(strings.ReplaceAll(fmt.Sprint(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNumbers), " ", ","), "[]") } else if cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNumbers { - portNumbers = "0" - } - if len(portNumbers) > 0 { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_DISCOVERY_K8S_PORT_NUMBERS", - Value: portNumbers, - }, - ) + k8sDiscoveryPortNumbers = "" } } + envs = append(envs, []corev1.EnvVar{ + { + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_ENABLED", + Value: fmt.Sprintf("%t", k8sDiscoveryEnabled), + }, + { + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_NAMESPACES", + Value: strings.Join(cr.TargetNamespaces, ","), + }, + { + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NAMES", + Value: k8sDiscoveryPortNames, + }, + { + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NUMBERS", + Value: k8sDiscoveryPortNumbers, + }, + }..., + ) grafanaVars := []corev1.EnvVar{ { diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 7d8ed2139..484615959 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -2706,6 +2706,7 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, hasPortConfig := cr.Spec.TargetDiscoveryOptions != nil && len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames) > 0 && len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNumbers) > 0 + builtInDiscoveryDisabled := cr.Spec.TargetDiscoveryOptions != nil && cr.Spec.TargetDiscoveryOptions.BuiltInDiscoveryDisabled builtInPortConfigDisabled := cr.Spec.TargetDiscoveryOptions != nil && cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNames && cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNumbers @@ -2715,6 +2716,7 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, cr.Spec.AuthProperties != nil, emptyDir, hasPortConfig, + builtInDiscoveryDisabled, builtInPortConfigDisabled, dbSecretProvided, t.NewCoreContainerResource(cr), t.NewCoreSecurityContext(cr)) @@ -2859,7 +2861,7 @@ func (t *cryostatTestInput) checkDeploymentHasTemplates() { func (t *cryostatTestInput) checkCoreContainer(container *corev1.Container, ingress bool, reportsUrl string, authProps bool, emptyDir bool, - hasPortConfig bool, builtInPortConfigDisabled bool, + hasPortConfig bool, builtInDiscoveryDisabled bool, builtInPortConfigDisabled bool, dbSecretProvided bool, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext) { @@ -2870,7 +2872,7 @@ func (t *cryostatTestInput) checkCoreContainer(container *corev1.Container, ingr Expect(container.Image).To(Equal(*t.EnvCoreImageTag)) } Expect(container.Ports).To(ConsistOf(t.NewCorePorts())) - Expect(container.Env).To(ConsistOf(t.NewCoreEnvironmentVariables(reportsUrl, authProps, ingress, emptyDir, hasPortConfig, builtInPortConfigDisabled, dbSecretProvided))) + Expect(container.Env).To(ConsistOf(t.NewCoreEnvironmentVariables(reportsUrl, authProps, ingress, emptyDir, hasPortConfig, builtInDiscoveryDisabled, builtInPortConfigDisabled, dbSecretProvided))) Expect(container.EnvFrom).To(ConsistOf(t.NewCoreEnvFromSource())) Expect(container.VolumeMounts).To(ConsistOf(t.NewCoreVolumeMounts())) Expect(container.LivenessProbe).To(Equal(t.NewCoreLivenessProbe())) diff --git a/internal/test/resources.go b/internal/test/resources.go index fe667e290..619ca7621 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1290,7 +1290,7 @@ func (r *TestResources) NewStoragePorts() []corev1.ContainerPort { } func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps bool, ingress bool, - emptyDir bool, hasPortConfig bool, builtInPortConfigDisabled bool, dbSecretProvided bool) []corev1.EnvVar { + emptyDir bool, hasPortConfig bool, builtInDiscoveryDisabled bool, builtInPortConfigDisabled bool, dbSecretProvided bool) []corev1.EnvVar { envs := []corev1.EnvVar{ { Name: "QUARKUS_HTTP_HOST", @@ -1388,10 +1388,6 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps Name: "CRYOSTAT_CONNECTIONS_TTL", Value: "10", }, - { - Name: "CRYOSTAT_DISCOVERY_KUBERNETES_ENABLED", - Value: "true", - }, { Name: "CRYOSTAT_DISCOVERY_KUBERNETES_NAMESPACES", Value: strings.Join(r.TargetNamespaces, ","), @@ -1410,7 +1406,7 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps }, } - envs = append(envs, r.NewTargetDiscoveryEnvVar(hasPortConfig, builtInPortConfigDisabled)...) + envs = append(envs, r.NewTargetDiscoveryEnvVars(hasPortConfig, builtInDiscoveryDisabled, builtInPortConfigDisabled)...) optional := false secretName := r.NewDatabaseSecret().Name @@ -1673,29 +1669,45 @@ func (r *TestResources) NewJmxCacheOptionsEnv() []corev1.EnvVar { } } -func (r *TestResources) NewTargetDiscoveryEnvVar(hasPortConfig bool, builtInPortConfigDisabled bool) []corev1.EnvVar { - envs := make([]corev1.EnvVar, 0) +func (r *TestResources) NewTargetDiscoveryEnvVars(hasPortConfig bool, builtInDiscoveryDisabled bool, builtInPortConfigDisabled bool) []corev1.EnvVar { + envs := []corev1.EnvVar{ + { + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_ENABLED", + Value: fmt.Sprintf("%t", !builtInDiscoveryDisabled), + }, + } if hasPortConfig { envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_DISCOVERY_K8S_PORT_NAMES", + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NAMES", Value: "custom-port-name,another-custom-port-name", }, corev1.EnvVar{ - Name: "CRYOSTAT_DISCOVERY_K8S_PORT_NUMBERS", + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NUMBERS", Value: "9092,9090", }, ) } else if builtInPortConfigDisabled { envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_DISCOVERY_K8S_PORT_NAMES", - Value: "-", + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NAMES", + Value: "", + }, + corev1.EnvVar{ + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NUMBERS", + Value: "", + }, + ) + } else { + envs = append(envs, + corev1.EnvVar{ + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NAMES", + Value: "jfr-jmx", }, corev1.EnvVar{ - Name: "CRYOSTAT_DISCOVERY_K8S_PORT_NUMBERS", - Value: "0", + Name: "CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NUMBERS", + Value: "9091", }, ) } From 4a72b4cb25a24de390ad7098eeafa3437e851f6e Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Fri, 3 May 2024 15:45:12 -0400 Subject: [PATCH 31/53] feat(ocp): add optional flag to force platform as openshift (#810) --- config/manager/kustomization.yaml | 9 +++++++++ config/manager/patches/force_openshift_patch.yaml | 3 +++ internal/main.go | 9 +++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 config/manager/patches/force_openshift_patch.yaml diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 55c8015cb..1f89c6724 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -14,3 +14,12 @@ images: - name: controller newName: quay.io/cryostat/cryostat-operator newTag: 3.0.0-dev + +# patchesJson6902: +# - path: patches/force_openshift_patch.yaml +# target: +# group: apps +# kind: Deployment +# name: controller-manager +# namespace: system +# version: v1 diff --git a/config/manager/patches/force_openshift_patch.yaml b/config/manager/patches/force_openshift_patch.yaml new file mode 100644 index 000000000..c3d152ed6 --- /dev/null +++ b/config/manager/patches/force_openshift_patch.yaml @@ -0,0 +1,3 @@ +- op: add + path: /spec/template/spec/containers/0/args/- + value: --force-openshift diff --git a/internal/main.go b/internal/main.go index 51a746763..272f0a6b4 100644 --- a/internal/main.go +++ b/internal/main.go @@ -75,6 +75,7 @@ func main() { var probeAddr string var secureMetrics bool var enableHTTP2 bool + var forceOpenShift bool flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, @@ -83,6 +84,7 @@ func main() { flag.BoolVar(&secureMetrics, "metrics-secure", false, "If set the metrics endpoint is served securely") flag.BoolVar(&enableHTTP2, "enable-http2", false, "If HTTP/2 should be enabled for the metrics and webhook servers.") + flag.BoolVar(&forceOpenShift, "force-openshift", false, "Force the controller to consider current platform as OpenShift") opts := zap.Options{ Development: true, } @@ -138,7 +140,7 @@ func main() { os.Exit(1) } - openShift, err := isOpenShift(dc) + openShift, err := isOpenShift(dc, forceOpenShift) if err != nil { setupLog.Error(err, "could not determine whether manager is running on OpenShift") os.Exit(1) @@ -205,7 +207,10 @@ func main() { } } -func isOpenShift(client discovery.DiscoveryInterface) (bool, error) { +func isOpenShift(client discovery.DiscoveryInterface, forceOpenShift bool) (bool, error) { + if forceOpenShift { + return true, nil + } return discovery.IsResourceEnabled(client, routev1.GroupVersion.WithResource("routes")) } From 6e7e17e332507cd249a672aa4327087fc9bffb99 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Fri, 3 May 2024 16:38:18 -0400 Subject: [PATCH 32/53] fix(csv): add related images for storage and db (#812) --- ...ryostat-operator.clusterserviceversion.yaml | 10 +++++++++- config/default/image_tag_patch.yaml | 4 ++++ config/manager/kustomization.yaml | 18 +++++++++--------- hack/image_tag_patch.yaml.in | 4 ++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 18202da0e..a7d07fe70 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-03T13:22:52Z" + createdAt: "2024-05-03T20:13:14Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -1158,6 +1158,10 @@ spec: value: quay.io/cryostat/cryostat-grafana-dashboard:latest - name: RELATED_IMAGE_REPORTS value: quay.io/cryostat/cryostat-reports:latest + - name: RELATED_IMAGE_STORAGE + value: quay.io/cryostat/cryostat-storage:latest + - name: RELATED_IMAGE_DATABASE + value: quay.io/cryostat/cryostat-db:latest - name: WATCH_NAMESPACE valueFrom: fieldRef: @@ -1332,6 +1336,10 @@ spec: name: grafana - image: quay.io/cryostat/cryostat-reports:latest name: reports + - image: quay.io/cryostat/cryostat-storage:latest + name: storage + - image: quay.io/cryostat/cryostat-db:latest + name: database version: 3.0.0-dev webhookdefinitions: - admissionReviewVersions: diff --git a/config/default/image_tag_patch.yaml b/config/default/image_tag_patch.yaml index 4bad37204..7e674620d 100644 --- a/config/default/image_tag_patch.yaml +++ b/config/default/image_tag_patch.yaml @@ -21,3 +21,7 @@ spec: value: "quay.io/cryostat/cryostat-grafana-dashboard:latest" - name: RELATED_IMAGE_REPORTS value: "quay.io/cryostat/cryostat-reports:latest" + - name: RELATED_IMAGE_STORAGE + value: "quay.io/cryostat/cryostat-storage:latest" + - name: RELATED_IMAGE_DATABASE + value: "quay.io/cryostat/cryostat-db:latest" diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 1f89c6724..68bfbedaa 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -4,6 +4,15 @@ resources: generatorOptions: disableNameSuffixHash: true +# patchesJson6902: +# - path: patches/force_openshift_patch.yaml +# target: +# group: apps +# kind: Deployment +# name: controller-manager +# namespace: system +# version: v1 + configMapGenerator: - files: - controller_manager_config.yaml @@ -14,12 +23,3 @@ images: - name: controller newName: quay.io/cryostat/cryostat-operator newTag: 3.0.0-dev - -# patchesJson6902: -# - path: patches/force_openshift_patch.yaml -# target: -# group: apps -# kind: Deployment -# name: controller-manager -# namespace: system -# version: v1 diff --git a/hack/image_tag_patch.yaml.in b/hack/image_tag_patch.yaml.in index d661f2d47..75ae9f77c 100644 --- a/hack/image_tag_patch.yaml.in +++ b/hack/image_tag_patch.yaml.in @@ -21,3 +21,7 @@ spec: value: "${GRAFANA_IMG}" - name: RELATED_IMAGE_REPORTS value: "${REPORTS_IMG}" + - name: RELATED_IMAGE_STORAGE + value: "${STORAGE_IMG}" + - name: RELATED_IMAGE_DATABASE + value: "${DATABASE_IMG}" From 0a3021f6f4eadaafed0dd3af4ed1b996619f8f85 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Wed, 8 May 2024 11:21:56 -0400 Subject: [PATCH 33/53] chore(cryostat3): various cleanups (#808) --- README.md | 8 - api/v1beta1/cryostat_conversion.go | 56 ++---- api/v1beta2/cryostat_types.go | 53 ++--- api/v1beta2/zz_generated.deepcopy.go | 87 ++++---- ...yostat-operator.clusterserviceversion.yaml | 99 ++++----- .../operator.cryostat.io_cryostats.yaml | 190 ++++++++++++------ .../bases/operator.cryostat.io_cryostats.yaml | 190 ++++++++++++------ ...yostat-operator.clusterserviceversion.yaml | 97 ++++----- docs/config.md | 72 +++---- .../resource_definitions.go | 188 +++++++---------- internal/controllers/constants/constants.go | 5 + internal/controllers/ingresses.go | 1 + internal/controllers/reconciler_test.go | 54 +---- internal/controllers/routes.go | 1 + internal/controllers/secrets.go | 45 +---- internal/test/resources.go | 154 ++++---------- 16 files changed, 588 insertions(+), 712 deletions(-) diff --git a/README.md b/README.md index acd009cf7..e2f29b6d8 100644 --- a/README.md +++ b/README.md @@ -31,14 +31,6 @@ at the URL provided by: ``` kubectl get cryostat -o jsonpath='{$.items[0].status.applicationUrl}' ``` -The Grafana credentials can be obtained with: -```shell -CRYOSTAT_NAME=$(kubectl get cryostat -o jsonpath='{$.items[0].metadata.name}') -# Username -kubectl get secret ${CRYOSTAT_NAME}-grafana-basic -o jsonpath='{$.data.GF_SECURITY_ADMIN_USER}' | base64 -d -# Password -kubectl get secret ${CRYOSTAT_NAME}-grafana-basic -o jsonpath='{$.data.GF_SECURITY_ADMIN_PASSWORD}' | base64 -d -``` The JMX authentication credentials for Cryostat itself can be obtained with: ```shell CRYOSTAT_NAME=$(kubectl get cryostat -o jsonpath='{$.items[0].metadata.name}') diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index de2b74a35..301ca0b4f 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -49,20 +49,18 @@ func convertSpecTo(src *CryostatSpec, dst *operatorv1beta2.CryostatSpec) { dst.ServiceOptions = convertServiceOptionsTo(src.ServiceOptions) dst.NetworkOptions = convertNetworkOptionsTo(src.NetworkOptions) dst.ReportOptions = convertReportOptionsTo(src.ReportOptions) - dst.JmxCacheOptions = convertJmxCacheOptionsTo(src.JmxCacheOptions) + dst.TargetConnectionCacheOptions = convertJmxCacheOptionsTo(src.JmxCacheOptions) dst.Resources = convertResourceOptionsTo(src.Resources) - dst.AuthProperties = convertAuthPropertiesTo(src.AuthProperties) dst.SecurityOptions = convertSecurityOptionsTo(src.SecurityOptions) dst.SchedulingOptions = convertSchedulingOptionsTo(src.SchedulingOptions) dst.TargetDiscoveryOptions = convertTargetDiscoveryTo(src.TargetDiscoveryOptions) - dst.JmxCredentialsDatabaseOptions = convertDatabaseOptionsTo(src.JmxCredentialsDatabaseOptions) + dst.DatabaseOptions = convertDatabaseOptionsTo(src.JmxCredentialsDatabaseOptions) dst.OperandMetadata = convertOperandMetadataTo(src.OperandMetadata) } func convertStatusTo(src *CryostatStatus, dst *operatorv1beta2.CryostatStatus) { dst.ApplicationURL = src.ApplicationURL dst.Conditions = src.Conditions - dst.GrafanaSecret = src.GrafanaSecret } func convertCertSecretsTo(srcCerts []CertificateSecret) []operatorv1beta2.CertificateSecret { @@ -214,10 +212,10 @@ func convertSchedulingOptionsTo(srcOpts *SchedulingConfiguration) *operatorv1bet return dstOpts } -func convertJmxCacheOptionsTo(srcOpts *JmxCacheOptions) *operatorv1beta2.JmxCacheOptions { - var dstOpts *operatorv1beta2.JmxCacheOptions +func convertJmxCacheOptionsTo(srcOpts *JmxCacheOptions) *operatorv1beta2.TargetConnectionCacheOptions { + var dstOpts *operatorv1beta2.TargetConnectionCacheOptions if srcOpts != nil { - dstOpts = &operatorv1beta2.JmxCacheOptions{ + dstOpts = &operatorv1beta2.TargetConnectionCacheOptions{ TargetCacheSize: srcOpts.TargetCacheSize, TargetCacheTTL: srcOpts.TargetCacheTTL, } @@ -237,18 +235,6 @@ func convertResourceOptionsTo(srcOpts *ResourceConfigList) *operatorv1beta2.Reso return dstOpts } -func convertAuthPropertiesTo(srcProps *AuthorizationProperties) *operatorv1beta2.AuthorizationProperties { - var dstProps *operatorv1beta2.AuthorizationProperties - if srcProps != nil { - dstProps = &operatorv1beta2.AuthorizationProperties{ - ClusterRoleName: srcProps.ClusterRoleName, - ConfigMapName: srcProps.ConfigMapName, - Filename: srcProps.Filename, - } - } - return dstProps -} - func convertSecurityOptionsTo(srcOpts *SecurityOptions) *operatorv1beta2.SecurityOptions { var dstOpts *operatorv1beta2.SecurityOptions if srcOpts != nil { @@ -276,11 +262,11 @@ func convertTargetDiscoveryTo(srcOpts *TargetDiscoveryOptions) *operatorv1beta2. return dstOpts } -func convertDatabaseOptionsTo(srcOpts *JmxCredentialsDatabaseOptions) *operatorv1beta2.JmxCredentialsDatabaseOptions { - var dstOpts *operatorv1beta2.JmxCredentialsDatabaseOptions +func convertDatabaseOptionsTo(srcOpts *JmxCredentialsDatabaseOptions) *operatorv1beta2.DatabaseOptions { + var dstOpts *operatorv1beta2.DatabaseOptions if srcOpts != nil { - dstOpts = &operatorv1beta2.JmxCredentialsDatabaseOptions{ - DatabaseSecretName: srcOpts.DatabaseSecretName, + dstOpts = &operatorv1beta2.DatabaseOptions{ + SecretName: srcOpts.DatabaseSecretName, } } return dstOpts @@ -332,20 +318,18 @@ func convertSpecFrom(src *operatorv1beta2.CryostatSpec, dst *CryostatSpec) { dst.ServiceOptions = convertServiceOptionsFrom(src.ServiceOptions) dst.NetworkOptions = convertNetworkOptionsFrom(src.NetworkOptions) dst.ReportOptions = convertReportOptionsFrom(src.ReportOptions) - dst.JmxCacheOptions = convertJmxCacheOptionsFrom(src.JmxCacheOptions) + dst.JmxCacheOptions = convertJmxCacheOptionsFrom(src.TargetConnectionCacheOptions) dst.Resources = convertResourceOptionsFrom(src.Resources) - dst.AuthProperties = convertAuthPropertiesFrom(src.AuthProperties) dst.SecurityOptions = convertSecurityOptionsFrom(src.SecurityOptions) dst.SchedulingOptions = convertSchedulingOptionsFrom(src.SchedulingOptions) dst.TargetDiscoveryOptions = convertTargetDiscoveryFrom(src.TargetDiscoveryOptions) - dst.JmxCredentialsDatabaseOptions = convertDatabaseOptionsFrom(src.JmxCredentialsDatabaseOptions) + dst.JmxCredentialsDatabaseOptions = convertDatabaseOptionsFrom(src.DatabaseOptions) dst.OperandMetadata = convertOperandMetadataFrom(src.OperandMetadata) } func convertStatusFrom(src *operatorv1beta2.CryostatStatus, dst *CryostatStatus) { dst.ApplicationURL = src.ApplicationURL dst.Conditions = src.Conditions - dst.GrafanaSecret = src.GrafanaSecret } func convertCertSecretsFrom(srcCerts []operatorv1beta2.CertificateSecret) []CertificateSecret { @@ -497,7 +481,7 @@ func convertSchedulingOptionsFrom(srcOpts *operatorv1beta2.SchedulingConfigurati return dstOpts } -func convertJmxCacheOptionsFrom(srcOpts *operatorv1beta2.JmxCacheOptions) *JmxCacheOptions { +func convertJmxCacheOptionsFrom(srcOpts *operatorv1beta2.TargetConnectionCacheOptions) *JmxCacheOptions { var dstOpts *JmxCacheOptions if srcOpts != nil { dstOpts = &JmxCacheOptions{ @@ -520,18 +504,6 @@ func convertResourceOptionsFrom(srcOpts *operatorv1beta2.ResourceConfigList) *Re return dstOpts } -func convertAuthPropertiesFrom(srcProps *operatorv1beta2.AuthorizationProperties) *AuthorizationProperties { - var dstProps *AuthorizationProperties - if srcProps != nil { - dstProps = &AuthorizationProperties{ - ClusterRoleName: srcProps.ClusterRoleName, - ConfigMapName: srcProps.ConfigMapName, - Filename: srcProps.Filename, - } - } - return dstProps -} - func convertSecurityOptionsFrom(srcOpts *operatorv1beta2.SecurityOptions) *SecurityOptions { var dstOpts *SecurityOptions if srcOpts != nil { @@ -559,11 +531,11 @@ func convertTargetDiscoveryFrom(srcOpts *operatorv1beta2.TargetDiscoveryOptions) return dstOpts } -func convertDatabaseOptionsFrom(srcOpts *operatorv1beta2.JmxCredentialsDatabaseOptions) *JmxCredentialsDatabaseOptions { +func convertDatabaseOptionsFrom(srcOpts *operatorv1beta2.DatabaseOptions) *JmxCredentialsDatabaseOptions { var dstOpts *JmxCredentialsDatabaseOptions if srcOpts != nil { dstOpts = &JmxCredentialsDatabaseOptions{ - DatabaseSecretName: srcOpts.DatabaseSecretName, + DatabaseSecretName: srcOpts.SecretName, } } return dstOpts diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index f66ed2b0d..1655ef883 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -45,11 +45,11 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,order=3,displayName="Enable cert-manager Integration",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} EnableCertManager *bool `json:"enableCertManager"` - // Options to customize the storage for Flight Recordings and Templates. + // Options to customize the storage provisioned for the database and object storage. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec StorageOptions *StorageConfiguration `json:"storageOptions,omitempty"` - // Options to customize the services created for the Cryostat application and Grafana dashboard. + // Options to customize the services created for the Cryostat application. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec ServiceOptions *ServiceConfigList `json:"serviceOptions,omitempty"` @@ -62,10 +62,10 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec ReportOptions *ReportConfiguration `json:"reportOptions,omitempty"` - // Options to customize the JMX target connections cache for the Cryostat application. + // Options to customize the target connections cache for the Cryostat application. // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="JMX Connections Cache Options" - JmxCacheOptions *JmxCacheOptions `json:"jmxCacheOptions,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Target Connection Cache Options" + TargetConnectionCacheOptions *TargetConnectionCacheOptions `json:"targetConnectionCacheOptions,omitempty"` // Resource requirements for the Cryostat deployment. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -74,10 +74,6 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Options",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} AuthorizationOptions *AuthorizationOptions `json:"authorizationOptions,omitempty"` - // Override default authorization properties for Cryostat on OpenShift. - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} - AuthProperties *AuthorizationProperties `json:"authProperties,omitempty"` // Options to configure the Security Contexts for the Cryostat application. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} @@ -90,10 +86,10 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec TargetDiscoveryOptions *TargetDiscoveryOptions `json:"targetDiscoveryOptions,omitempty"` - // Options to configure the Cryostat application's credentials database. + // Options to configure the Cryostat application's database. // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Credentials Database Options" - JmxCredentialsDatabaseOptions *JmxCredentialsDatabaseOptions `json:"jmxCredentialsDatabaseOptions,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Database Options" + DatabaseOptions *DatabaseOptions `json:"databaseOptions,omitempty"` // Options to configure the Cryostat deployments and pods metadata // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Operand metadata" @@ -127,7 +123,7 @@ type ResourceConfigList struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} AuthProxyResources corev1.ResourceRequirements `json:"authProxyResources,omitempty"` - // Resource requirements for the Cryostat application. If specifying a memory limit, at least 768MiB is recommended. + // Resource requirements for the Cryostat application. If specifying a memory limit, at least 384MiB is recommended. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} CoreResources corev1.ResourceRequirements `json:"coreResources,omitempty"` @@ -139,6 +135,14 @@ type ResourceConfigList struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} GrafanaResources corev1.ResourceRequirements `json:"grafanaResources,omitempty"` + // Resource requirements for the database container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + DatabaseResources corev1.ResourceRequirements `json:"databaseResources,omitempty"` + // Resource requirements for the object storage container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + ObjectStorageResources corev1.ResourceRequirements `json:"objectStorageResources,omitempty"` } // CryostatStatus defines the observed state of Cryostat. @@ -152,10 +156,6 @@ type CryostatStatus struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Cryostat Conditions",xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"} Conditions []metav1.Condition `json:"conditions,omitempty"` - // Name of the Secret containing the generated Grafana credentials. - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=status,order=2,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} - GrafanaSecret string `json:"grafanaSecret,omitempty"` // Address of the deployed Cryostat web application. // +operator-sdk:csv:customresourcedefinitions:type=status,order=1,xDescriptors={"urn:alm:descriptor:org.w3:link"} ApplicationURL string `json:"applicationUrl"` @@ -405,15 +405,15 @@ type EmptyDirConfig struct { SizeLimit string `json:"sizeLimit,omitempty"` } -// JmxCacheConfig provides customization for the JMX target connections +// TargetConnectionCacheOptions provides customization for the target connections // cache for the Cryostat application. -type JmxCacheOptions struct { - // The maximum number of JMX connections to cache. Use `-1` for an unlimited cache size (TTL expiration only). Defaults to `-1`. +type TargetConnectionCacheOptions struct { + // The maximum number of target connections to cache. Use `-1` for an unlimited cache size (TTL expiration only). Defaults to `-1`. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} // +kubebuilder:validation:Minimum=-1 TargetCacheSize int32 `json:"targetCacheSize,omitempty"` - // The time to live (in seconds) for cached JMX connections. Defaults to `10`. + // The time to live (in seconds) for cached target connections. Defaults to `10`. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} // +kubebuilder:validation:Minimum=1 @@ -432,7 +432,6 @@ type JmxCacheOptions struct { // to deploy the Cryostat application. // +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} // +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` -// +kubebuilder:printcolumn:name="Grafana Secret",type=string,JSONPath=`.status.grafanaSecret` type Cryostat struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -611,10 +610,12 @@ type TargetDiscoveryOptions struct { DiscoveryPortNumbers []int32 `json:"discoveryPortNumbers,omitempty"` } -// JmxCredentialsDatabaseOptions provides configuration options to the Cryostat application's credentials database. -type JmxCredentialsDatabaseOptions struct { - // Name of the secret containing the password to encrypt credentials database. +// DatabaseOptions provides configuration options to the Cryostat application's database. +type DatabaseOptions struct { + // Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the + // database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data + // stored within the database, such as the target credentials keyring. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} - DatabaseSecretName *string `json:"databaseSecretName,omitempty"` + SecretName *string `json:"secretName,omitempty"` } diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 929146417..0fa1bd72c 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -247,9 +247,9 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { *out = new(ReportConfiguration) (*in).DeepCopyInto(*out) } - if in.JmxCacheOptions != nil { - in, out := &in.JmxCacheOptions, &out.JmxCacheOptions - *out = new(JmxCacheOptions) + if in.TargetConnectionCacheOptions != nil { + in, out := &in.TargetConnectionCacheOptions, &out.TargetConnectionCacheOptions + *out = new(TargetConnectionCacheOptions) **out = **in } if in.Resources != nil { @@ -262,11 +262,6 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { *out = new(AuthorizationOptions) (*in).DeepCopyInto(*out) } - if in.AuthProperties != nil { - in, out := &in.AuthProperties, &out.AuthProperties - *out = new(AuthorizationProperties) - **out = **in - } if in.SecurityOptions != nil { in, out := &in.SecurityOptions, &out.SecurityOptions *out = new(SecurityOptions) @@ -282,9 +277,9 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { *out = new(TargetDiscoveryOptions) (*in).DeepCopyInto(*out) } - if in.JmxCredentialsDatabaseOptions != nil { - in, out := &in.JmxCredentialsDatabaseOptions, &out.JmxCredentialsDatabaseOptions - *out = new(JmxCredentialsDatabaseOptions) + if in.DatabaseOptions != nil { + in, out := &in.DatabaseOptions, &out.DatabaseOptions + *out = new(DatabaseOptions) (*in).DeepCopyInto(*out) } if in.OperandMetadata != nil { @@ -332,72 +327,57 @@ func (in *CryostatStatus) DeepCopy() *CryostatStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EmptyDirConfig) DeepCopyInto(out *EmptyDirConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmptyDirConfig. -func (in *EmptyDirConfig) DeepCopy() *EmptyDirConfig { - if in == nil { - return nil - } - out := new(EmptyDirConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GrafanaServiceConfig) DeepCopyInto(out *GrafanaServiceConfig) { +func (in *DatabaseOptions) DeepCopyInto(out *DatabaseOptions) { *out = *in - if in.HTTPPort != nil { - in, out := &in.HTTPPort, &out.HTTPPort - *out = new(int32) + if in.SecretName != nil { + in, out := &in.SecretName, &out.SecretName + *out = new(string) **out = **in } - in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaServiceConfig. -func (in *GrafanaServiceConfig) DeepCopy() *GrafanaServiceConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseOptions. +func (in *DatabaseOptions) DeepCopy() *DatabaseOptions { if in == nil { return nil } - out := new(GrafanaServiceConfig) + out := new(DatabaseOptions) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JmxCacheOptions) DeepCopyInto(out *JmxCacheOptions) { +func (in *EmptyDirConfig) DeepCopyInto(out *EmptyDirConfig) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JmxCacheOptions. -func (in *JmxCacheOptions) DeepCopy() *JmxCacheOptions { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmptyDirConfig. +func (in *EmptyDirConfig) DeepCopy() *EmptyDirConfig { if in == nil { return nil } - out := new(JmxCacheOptions) + out := new(EmptyDirConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JmxCredentialsDatabaseOptions) DeepCopyInto(out *JmxCredentialsDatabaseOptions) { +func (in *GrafanaServiceConfig) DeepCopyInto(out *GrafanaServiceConfig) { *out = *in - if in.DatabaseSecretName != nil { - in, out := &in.DatabaseSecretName, &out.DatabaseSecretName - *out = new(string) + if in.HTTPPort != nil { + in, out := &in.HTTPPort, &out.HTTPPort + *out = new(int32) **out = **in } + in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JmxCredentialsDatabaseOptions. -func (in *JmxCredentialsDatabaseOptions) DeepCopy() *JmxCredentialsDatabaseOptions { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaServiceConfig. +func (in *GrafanaServiceConfig) DeepCopy() *GrafanaServiceConfig { if in == nil { return nil } - out := new(JmxCredentialsDatabaseOptions) + out := new(GrafanaServiceConfig) in.DeepCopyInto(out) return out } @@ -624,6 +604,8 @@ func (in *ResourceConfigList) DeepCopyInto(out *ResourceConfigList) { in.CoreResources.DeepCopyInto(&out.CoreResources) in.DataSourceResources.DeepCopyInto(&out.DataSourceResources) in.GrafanaResources.DeepCopyInto(&out.GrafanaResources) + in.DatabaseResources.DeepCopyInto(&out.DatabaseResources) + in.ObjectStorageResources.DeepCopyInto(&out.ObjectStorageResources) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceConfigList. @@ -863,6 +845,21 @@ func (in *StorageConfiguration) DeepCopy() *StorageConfiguration { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TargetConnectionCacheOptions) DeepCopyInto(out *TargetConnectionCacheOptions) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetConnectionCacheOptions. +func (in *TargetConnectionCacheOptions) DeepCopy() *TargetConnectionCacheOptions { + if in == nil { + return nil + } + out := new(TargetConnectionCacheOptions) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TargetDiscoveryOptions) DeepCopyInto(out *TargetDiscoveryOptions) { *out = *in diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index a7d07fe70..c05bf7536 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-03T20:13:14Z" + createdAt: "2024-05-06T20:05:20Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -531,28 +531,6 @@ spec: path: enableCertManager x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Override default authorization properties for Cryostat on OpenShift. - displayName: Authorization Properties - path: authProperties - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped - OAuth token. This ClusterRole should contain permissions for all Kubernetes - objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: ClusterRole Name - path: authProperties.clusterRoleName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ClusterRole - - description: Name of config map in the local namespace. - displayName: ConfigMap Name - path: authProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Filename within config map containing the resource mapping. - displayName: Filename - path: authProperties.filename - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - description: Additional configuration options for the authorization proxy. displayName: Authorization Options path: authorizationOptions @@ -595,6 +573,17 @@ spec: path: authorizationOptions.openShiftSSO.disable x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Options to configure the Cryostat application's database. + displayName: Database Options + path: databaseOptions + - description: Name of the secret containing database keys. This secret must + contain a CONNECTION_KEY secret which is the database connection password, + and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive + data stored within the database, such as the target credentials keyring. + displayName: Secret Name + path: databaseOptions.secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. displayName: Event Templates path: eventTemplates @@ -603,31 +592,6 @@ spec: path: eventTemplates[0].configMapName x-descriptors: - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Options to customize the JMX target connections cache for the - Cryostat application. - displayName: JMX Connections Cache Options - path: jmxCacheOptions - - description: The maximum number of JMX connections to cache. Use `-1` for - an unlimited cache size (TTL expiration only). Defaults to `-1`. - displayName: Target Cache Size - path: jmxCacheOptions.targetCacheSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: The time to live (in seconds) for cached JMX connections. Defaults - to `10`. - displayName: Target Cache TTL - path: jmxCacheOptions.targetCacheTTL - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to configure the Cryostat application's credentials database. - displayName: Credentials Database Options - path: jmxCredentialsDatabaseOptions - - description: Name of the secret containing the password to encrypt credentials - database. - displayName: Database Secret Name - path: jmxCredentialsDatabaseOptions.databaseSecretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options @@ -749,7 +713,7 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Cryostat application. If specifying - a memory limit, at least 768MiB is recommended. + a memory limit, at least 384MiB is recommended. displayName: Core Resources path: resources.coreResources x-descriptors: @@ -759,11 +723,21 @@ spec: path: resources.dataSourceResources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the database container. + displayName: Database Resources + path: resources.databaseResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Grafana container. displayName: Grafana Resources path: resources.grafanaResources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the object storage container. + displayName: Object Storage Resources + path: resources.objectStorageResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Options to configure scheduling for the Cryostat deployment displayName: Scheduling Options path: schedulingOptions @@ -822,11 +796,11 @@ spec: - description: Security Context to apply to the storage container. displayName: Storage Security Context path: securityOptions.storageSecurityContext - - description: Options to customize the services created for the Cryostat application - and Grafana dashboard. + - description: Options to customize the services created for the Cryostat application. displayName: Service Options path: serviceOptions - - description: Options to customize the storage for Flight Recordings and Templates. + - description: Options to customize the storage provisioned for the database + and object storage. displayName: Storage Options path: storageOptions - description: Configuration for an EmptyDir to be created by the operator instead @@ -861,6 +835,22 @@ spec: has created the PVC, changes to this field have no effect. displayName: Spec path: storageOptions.pvc.spec + - description: Options to customize the target connections cache for the Cryostat + application. + displayName: Target Connection Cache Options + path: targetConnectionCacheOptions + - description: The maximum number of target connections to cache. Use `-1` for + an unlimited cache size (TTL expiration only). Defaults to `-1`. + displayName: Target Cache Size + path: targetConnectionCacheOptions.targetCacheSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: The time to live (in seconds) for cached target connections. + Defaults to `10`. + displayName: Target Cache TTL + path: targetConnectionCacheOptions.targetCacheTTL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number - description: Options to configure the Cryostat application's target discovery mechanisms. displayName: Target Discovery Options @@ -915,11 +905,6 @@ spec: path: applicationUrl x-descriptors: - urn:alm:descriptor:org.w3:link - - description: Name of the Secret containing the generated Grafana credentials. - displayName: Grafana Secret - path: grafanaSecret - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - description: List of namespaces that Cryostat has been configured and authorized to access and profile. displayName: Target Namespaces diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 460244d0c..2104aa932 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -5101,9 +5101,6 @@ spec: - jsonPath: .status.applicationUrl name: Application URL type: string - - jsonPath: .status.grafanaSecret - name: Grafana Secret - type: string name: v1beta2 schema: openAPIV3Schema: @@ -5128,28 +5125,6 @@ spec: spec: description: CryostatSpec defines the desired state of Cryostat. properties: - authProperties: - description: Override default authorization properties for Cryostat - on OpenShift. - properties: - clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - type: string - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - clusterRoleName - - configMapName - - filename - type: object authorizationOptions: description: Additional configuration options for the authorization proxy. @@ -5224,6 +5199,17 @@ spec: type: boolean type: object type: object + databaseOptions: + description: Options to configure the Cryostat application's database. + properties: + secretName: + description: Name of the secret containing database keys. This + secret must contain a CONNECTION_KEY secret which is the database + connection password, and an ENCRYPTION_KEY secret which is the + key used to encrypt sensitive data stored within the database, + such as the target credentials keyring. + type: string + type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. @@ -5246,33 +5232,6 @@ spec: - filename type: object type: array - jmxCacheOptions: - description: Options to customize the JMX target connections cache - for the Cryostat application. - properties: - targetCacheSize: - description: The maximum number of JMX connections to cache. Use - `-1` for an unlimited cache size (TTL expiration only). Defaults - to `-1`. - format: int32 - minimum: -1 - type: integer - targetCacheTTL: - description: The time to live (in seconds) for cached JMX connections. - Defaults to `10`. - format: int32 - minimum: 1 - type: integer - type: object - jmxCredentialsDatabaseOptions: - description: Options to configure the Cryostat application's credentials - database. - properties: - databaseSecretName: - description: Name of the secret containing the password to encrypt - credentials database. - type: string - type: object networkOptions: description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. @@ -7379,7 +7338,7 @@ spec: type: object coreResources: description: Resource requirements for the Cryostat application. - If specifying a memory limit, at least 768MiB is recommended. + If specifying a memory limit, at least 384MiB is recommended. properties: claims: description: "Claims lists the names of resources, defined @@ -7476,6 +7435,55 @@ spec: Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + databaseResources: + description: Resource requirements for the database container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object grafanaResources: description: Resource requirements for the Grafana container. properties: @@ -7525,6 +7533,55 @@ spec: Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + objectStorageResources: + description: Resource requirements for the object storage container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object type: object schedulingOptions: description: Options to configure scheduling for the Cryostat deployment @@ -9621,7 +9678,7 @@ spec: type: object serviceOptions: description: Options to customize the services created for the Cryostat - application and Grafana dashboard. + application. properties: coreConfig: description: Specification for the service responsible for the @@ -9708,8 +9765,8 @@ spec: type: object type: object storageOptions: - description: Options to customize the storage for Flight Recordings - and Templates. + description: Options to customize the storage provisioned for the + database and object storage. properties: emptyDir: description: Configuration for an EmptyDir to be created by the @@ -9968,6 +10025,24 @@ spec: type: object type: object type: object + targetConnectionCacheOptions: + description: Options to customize the target connections cache for + the Cryostat application. + properties: + targetCacheSize: + description: The maximum number of target connections to cache. + Use `-1` for an unlimited cache size (TTL expiration only). + Defaults to `-1`. + format: int32 + minimum: -1 + type: integer + targetCacheTTL: + description: The time to live (in seconds) for cached target connections. + Defaults to `10`. + format: int32 + minimum: 1 + type: integer + type: object targetDiscoveryOptions: description: Options to configure the Cryostat application's target discovery mechanisms. @@ -10098,9 +10173,6 @@ spec: - type type: object type: array - grafanaSecret: - description: Name of the Secret containing the generated Grafana credentials. - type: string targetNamespaces: description: List of namespaces that Cryostat has been configured and authorized to access and profile. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 4bb2140fc..fd1d66c0c 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -5091,9 +5091,6 @@ spec: - jsonPath: .status.applicationUrl name: Application URL type: string - - jsonPath: .status.grafanaSecret - name: Grafana Secret - type: string name: v1beta2 schema: openAPIV3Schema: @@ -5118,28 +5115,6 @@ spec: spec: description: CryostatSpec defines the desired state of Cryostat. properties: - authProperties: - description: Override default authorization properties for Cryostat - on OpenShift. - properties: - clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - type: string - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - clusterRoleName - - configMapName - - filename - type: object authorizationOptions: description: Additional configuration options for the authorization proxy. @@ -5214,6 +5189,17 @@ spec: type: boolean type: object type: object + databaseOptions: + description: Options to configure the Cryostat application's database. + properties: + secretName: + description: Name of the secret containing database keys. This + secret must contain a CONNECTION_KEY secret which is the database + connection password, and an ENCRYPTION_KEY secret which is the + key used to encrypt sensitive data stored within the database, + such as the target credentials keyring. + type: string + type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. @@ -5236,33 +5222,6 @@ spec: - filename type: object type: array - jmxCacheOptions: - description: Options to customize the JMX target connections cache - for the Cryostat application. - properties: - targetCacheSize: - description: The maximum number of JMX connections to cache. Use - `-1` for an unlimited cache size (TTL expiration only). Defaults - to `-1`. - format: int32 - minimum: -1 - type: integer - targetCacheTTL: - description: The time to live (in seconds) for cached JMX connections. - Defaults to `10`. - format: int32 - minimum: 1 - type: integer - type: object - jmxCredentialsDatabaseOptions: - description: Options to configure the Cryostat application's credentials - database. - properties: - databaseSecretName: - description: Name of the secret containing the password to encrypt - credentials database. - type: string - type: object networkOptions: description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. @@ -7369,7 +7328,7 @@ spec: type: object coreResources: description: Resource requirements for the Cryostat application. - If specifying a memory limit, at least 768MiB is recommended. + If specifying a memory limit, at least 384MiB is recommended. properties: claims: description: "Claims lists the names of resources, defined @@ -7466,6 +7425,55 @@ spec: Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + databaseResources: + description: Resource requirements for the database container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object grafanaResources: description: Resource requirements for the Grafana container. properties: @@ -7515,6 +7523,55 @@ spec: Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + objectStorageResources: + description: Resource requirements for the object storage container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n 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: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object type: object schedulingOptions: description: Options to configure scheduling for the Cryostat deployment @@ -9611,7 +9668,7 @@ spec: type: object serviceOptions: description: Options to customize the services created for the Cryostat - application and Grafana dashboard. + application. properties: coreConfig: description: Specification for the service responsible for the @@ -9698,8 +9755,8 @@ spec: type: object type: object storageOptions: - description: Options to customize the storage for Flight Recordings - and Templates. + description: Options to customize the storage provisioned for the + database and object storage. properties: emptyDir: description: Configuration for an EmptyDir to be created by the @@ -9958,6 +10015,24 @@ spec: type: object type: object type: object + targetConnectionCacheOptions: + description: Options to customize the target connections cache for + the Cryostat application. + properties: + targetCacheSize: + description: The maximum number of target connections to cache. + Use `-1` for an unlimited cache size (TTL expiration only). + Defaults to `-1`. + format: int32 + minimum: -1 + type: integer + targetCacheTTL: + description: The time to live (in seconds) for cached target connections. + Defaults to `10`. + format: int32 + minimum: 1 + type: integer + type: object targetDiscoveryOptions: description: Options to configure the Cryostat application's target discovery mechanisms. @@ -10088,9 +10163,6 @@ spec: - type type: object type: array - grafanaSecret: - description: Name of the Secret containing the generated Grafana credentials. - type: string targetNamespaces: description: List of namespaces that Cryostat has been configured and authorized to access and profile. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index c85c5c395..62e4d6a3c 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -76,28 +76,6 @@ spec: path: enableCertManager x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Override default authorization properties for Cryostat on OpenShift. - displayName: Authorization Properties - path: authProperties - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped - OAuth token. This ClusterRole should contain permissions for all Kubernetes - objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: ClusterRole Name - path: authProperties.clusterRoleName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ClusterRole - - description: Name of config map in the local namespace. - displayName: ConfigMap Name - path: authProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Filename within config map containing the resource mapping. - displayName: Filename - path: authProperties.filename - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - description: Additional configuration options for the authorization proxy. displayName: Authorization Options path: authorizationOptions @@ -140,6 +118,17 @@ spec: path: authorizationOptions.openShiftSSO.disable x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Options to configure the Cryostat application's database. + displayName: Database Options + path: databaseOptions + - description: Name of the secret containing database keys. This secret must + contain a CONNECTION_KEY secret which is the database connection password, + and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive + data stored within the database, such as the target credentials keyring. + displayName: Secret Name + path: databaseOptions.secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. displayName: Event Templates path: eventTemplates @@ -148,31 +137,6 @@ spec: path: eventTemplates[0].configMapName x-descriptors: - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Options to customize the JMX target connections cache for the - Cryostat application. - displayName: JMX Connections Cache Options - path: jmxCacheOptions - - description: The maximum number of JMX connections to cache. Use `-1` for - an unlimited cache size (TTL expiration only). Defaults to `-1`. - displayName: Target Cache Size - path: jmxCacheOptions.targetCacheSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: The time to live (in seconds) for cached JMX connections. Defaults - to `10`. - displayName: Target Cache TTL - path: jmxCacheOptions.targetCacheTTL - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to configure the Cryostat application's credentials database. - displayName: Credentials Database Options - path: jmxCredentialsDatabaseOptions - - description: Name of the secret containing the password to encrypt credentials - database. - displayName: Database Secret Name - path: jmxCredentialsDatabaseOptions.databaseSecretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options @@ -294,7 +258,7 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Cryostat application. If specifying - a memory limit, at least 768MiB is recommended. + a memory limit, at least 384MiB is recommended. displayName: Core Resources path: resources.coreResources x-descriptors: @@ -304,11 +268,21 @@ spec: path: resources.dataSourceResources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the database container. + displayName: Database Resources + path: resources.databaseResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Grafana container. displayName: Grafana Resources path: resources.grafanaResources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the object storage container. + displayName: Object Storage Resources + path: resources.objectStorageResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Options to configure scheduling for the Cryostat deployment displayName: Scheduling Options path: schedulingOptions @@ -367,11 +341,11 @@ spec: - description: Security Context to apply to the storage container. displayName: Storage Security Context path: securityOptions.storageSecurityContext - - description: Options to customize the services created for the Cryostat application - and Grafana dashboard. + - description: Options to customize the services created for the Cryostat application. displayName: Service Options path: serviceOptions - - description: Options to customize the storage for Flight Recordings and Templates. + - description: Options to customize the storage provisioned for the database + and object storage. displayName: Storage Options path: storageOptions - description: Configuration for an EmptyDir to be created by the operator instead @@ -406,6 +380,22 @@ spec: has created the PVC, changes to this field have no effect. displayName: Spec path: storageOptions.pvc.spec + - description: Options to customize the target connections cache for the Cryostat + application. + displayName: Target Connection Cache Options + path: targetConnectionCacheOptions + - description: The maximum number of target connections to cache. Use `-1` for + an unlimited cache size (TTL expiration only). Defaults to `-1`. + displayName: Target Cache Size + path: targetConnectionCacheOptions.targetCacheSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: The time to live (in seconds) for cached target connections. + Defaults to `10`. + displayName: Target Cache TTL + path: targetConnectionCacheOptions.targetCacheTTL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number - description: Options to configure the Cryostat application's target discovery mechanisms. displayName: Target Discovery Options @@ -454,11 +444,6 @@ spec: path: applicationUrl x-descriptors: - urn:alm:descriptor:org.w3:link - - description: Name of the Secret containing the generated Grafana credentials. - displayName: Grafana Secret - path: grafanaSecret - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - description: List of namespaces that Cryostat has been configured and authorized to access and profile. displayName: Target Namespaces diff --git a/docs/config.md b/docs/config.md index 1633b3f95..e57155516 100644 --- a/docs/config.md +++ b/docs/config.md @@ -62,7 +62,7 @@ spec: Multiple TLS secrets may be specified in the `trustedCertSecrets` array. The `secretName` property is mandatory, and must refer to the name of a Secret within the same namespace as the `Cryostat` object. The `certificateKey` must point to the X.509 certificate file to be trusted. If `certificateKey` is omitted, the default key name of `tls.crt` will be used. ### Storage Options -Cryostat uses storage volumes to hold Flight Recording files and user-configured Recording Templates. In the interest of persisting these files across redeployments, Cryostat uses a Persistent Volume Claim by default. Unless overidden, the operator will create a Persistent Volume Claim with the default Storage Class and 500MiB of storage capacity. +Cryostat uses storage volumes to persist data in its database and object storage. In the interest of persisting these files across redeployments, Cryostat uses a Persistent Volume Claim by default. Unless overidden, the operator will create a Persistent Volume Claim with the default Storage Class and 500MiB of storage capacity. Through the `spec.storageOptions` property, users can choose to provide either a custom Persistent Volume Claim `pvc.spec` or an `emptyDir` configuration. Either of these configurations will override any defaults when the operator creates the storage volume. If an `emptyDir` configuration is enabled, Cryostat will use an EmptyDir volume instead of a Persistent Volume Claim. Additional labels and annotations for the Persistent Volume Claim may also be specified. ```yaml @@ -286,9 +286,9 @@ spec: targetCacheTTL: 10 ``` -### JMX Credentials Database +### Application Database -The Cryostat application must be provided with a password to encrypt saved JMX credentials in database. The user can specify a secret containing the password entry with key `CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD`. The Cryostat application will use this password to encrypt saved JMX credentials in database. +Cryostat stores various pieces of information in a database. This can also include target application connection credentials, such as target applications' JMX credentials, which are stored in an encrypted database table. By default, the Operator will generate both a random database connection key and a random table encryption key and configure Cryostat and the database to use these. You may also specify these keys yourself by creating a Secret containing the keys `CONNECTION_KEY` and `ENCRYPTION_KEY`. For example: ```yaml @@ -298,10 +298,11 @@ metadata: name: credentials-database-secret type: Opaque stringData: - CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD: a-very-good-password + CONNECTION_KEY: a-very-good-password + ENCRYPTION_KEY: a-second-good-password ``` -Then, the property `.spec.jmxCredentialsDatabaseOptions.databaseSecretName` must be set to use this secret for password. +Then, the property `.spec.databaseOptions.secretName` must be set to use this Secret for the two keys. ```yaml apiVersion: operator.cryostat.io/v1beta1 @@ -313,48 +314,41 @@ spec: databaseSecretName: credentials-database-secret ``` -**Note**: If the secret is not provided, a default one is generated for this purpose. However, switching between using provided and generated secret is not allowed to avoid password mismatch that causes the Cryostat application's failure to access the credentials database. +**Note**: If the secret is not provided, one is generated for this purpose containing two randomly generated keys. However, switching between using provided and generated secret is not allowed to avoid password mismatch that causes the Cryostat application's failure to access the database or failure to decrypt the credentials keyring. -### Authorization Properties +### Authorization Options -When running on OpenShift, the user is required to have sufficient permissions for certain Kubernetes resources that are mapped into Cryostat-managed resources for authorization. - -The mappings can be specified using a ConfigMap that is compatible with [`OpenShiftAuthManager.properties`](https://github.com/cryostatio/cryostat/blob/6db048682b2b0048c1f6ea9215de626b5a5be284/src/main/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties). For example: -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: auth-properties -data: - auth.properties: | - TARGET=pods,deployments.apps - RECORDING=pods,pods/exec - CERTIFICATE=deployments.apps,pods,cryostats.operator.cryostat.io - CREDENTIALS=cryostats.operator.cryostat.io -``` - -If custom mapping is specified, a ClusterRole must be defined and should contain permissions for all Kubernetes objects listed in custom permission mapping. This ClusterRole will give additional rules on top of [default rules](https://github.com/cryostatio/cryostat-operator/blob/1b5d1ab97fca925e14b6c2baf2585f5e04426440/config/rbac/oauth_client.yaml). +On OpenShift, the authentication/authorization proxy deployed in front of the Cryostat application requires all users to pass a `create pods/exec` access review in the Cryostat installation namespace +by default. This means that access to the Cryostat application is granted to exactly the set of OpenShift cluster user accounts and service accounts which have this Role. This can be configured +using `spec.authorizationOptions.openShiftSSO.accessReview` as depicted below, but note that the `namespace` field should always be included and in most cases should match the Cryostat installation namespace. +The auth proxy may also be configured to allow Basic authentication by creating a Secret containing an `htpasswd` user file. An `htpasswd` file granting access to a user named `user` with the +password `pass` can be generated like this: `htpasswd -cbB htpasswd.conf user pass`. The password should use `bcrypt` hashing, specified by the `-B` flag. +Any user accounts defined in this file will also be granted access to the Cryostat application, and when this configuration is enabled you will see an additional Basic login option when visiting +the Cryostat application UI. If deployed on a non-OpenShift Kubernetes then this is the only supported authentication mechanism. -**Note**: Using [`Secret`](https://kubernetes.io/docs/concepts/configuration/secret/) in mapping can fail with access denied under [security protection](https://kubernetes.io/docs/concepts/configuration/secret/#information-security-for-secrets) against escalations. Find more details about this issue [here](https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth). +If not deployed on OpenShift, or if OpenShift SSO integration is disabled, then no authentication is performed by default - the Cryostat application UI is openly accessible. You should configure +`htpasswd` Basic authentication or install some other access control mechanism. -The property `spec.authProperties` can then be set to configure Cryostat to use this mapping instead of the default ones. ```yaml -apiVersion: operator.cryostat.io/v1beta1 +apiVersion: operator.cryostat.io/v1beta2 kind: Cryostat metadata: name: cryostat-sample spec: - authProperties: - configMapName: auth-properties - filename: auth.properties - clusterRoleName: oauth-cluster-role + authorizationOptions: + openShiftSSO: # only effective when running on OpenShift + disable: false # set this to `true` to disable OpenShift SSO integration + accessReview: # override this to change the required Role for users and service accounts to access the application + verb: create + resource: pods + subresource: exec + namespace: cryostat-install-namespace + basicAuth: + secretName: my-secret # a Secret with this name must exist in the Cryostat installation namespace + filename: htpasswd.conf # the name of the htpasswd user file within the Secret ``` -Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containing resource mappings. The `clusterRoleName` must be a valid name of an existing Cluster Role. - -**Note:** If the mapping is updated, Cryostat must be manually restarted. - ### Security Context @@ -486,6 +480,8 @@ spec: If you wish to use only Cryostat's [Discovery Plugin API](https://github.com/cryostatio/cryostat/blob/801779d5ddf7fa30f7b230f649220a852b06f27d/docs/DISCOVERY_PLUGINS.md), set the property `spec.targetDiscoveryOptions.builtInDiscoveryDisabled` to `true` to disable Cryostat's built-in discovery mechanisms. +You may also change the list of port names and port numbers that Cryostat uses to discover compatible target Endpoints. By default it looks for ports with the name `jfr-jmx` or with the number `9091`. + ```yaml apiVersion: operator.cryostat.io/v1beta1 kind: Cryostat @@ -493,5 +489,9 @@ metadata: name: cryostat-sample spec: targetDiscoveryOptions: - builtInDiscoveryDisabled: true + builtInDiscoveryDisabled: false + discoveryPortNames: + - my-jmx-port # look for ports named my-jmx-port or jdk-observe + - jdk-observe + disableBuiltInPortNumbers: true # ignore default port number 9091 ``` diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index cd3e8036e..a4980bda6 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -71,16 +71,20 @@ type TLSConfig struct { } const ( - defaultAuthProxyCpuRequest string = "50m" - defaultAuthProxyMemoryRequest string = "120Mi" + defaultAuthProxyCpuRequest string = "25m" + defaultAuthProxyMemoryRequest string = "64Mi" defaultCoreCpuRequest string = "500m" - defaultCoreMemoryRequest string = "256Mi" + defaultCoreMemoryRequest string = "384Mi" defaultJfrDatasourceCpuRequest string = "200m" - defaultJfrDatasourceMemoryRequest string = "384Mi" - defaultGrafanaCpuRequest string = "100m" - defaultGrafanaMemoryRequest string = "120Mi" - defaultReportCpuRequest string = "200m" - defaultReportMemoryRequest string = "384Mi" + defaultJfrDatasourceMemoryRequest string = "200Mi" + defaultGrafanaCpuRequest string = "25m" + defaultGrafanaMemoryRequest string = "80Mi" + defaultDatabaseCpuRequest string = "25m" + defaultDatabaseMemoryRequest string = "64Mi" + defaultStorageCpuRequest string = "50m" + defaultStorageMemoryRequest string = "256Mi" + defaultReportCpuRequest string = "500m" + defaultReportMemoryRequest string = "512Mi" OAuth2ConfigFileName string = "alpha_config.json" OAuth2ConfigFilePath string = "/etc/oauth2_proxy/alpha_config" ) @@ -894,10 +898,7 @@ func NewCoreContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequir func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag string, tls *TLSConfig, openshift bool) corev1.Container { configPath := "/opt/cryostat.d/conf.d" - archivePath := "/opt/cryostat.d/recordings.d" templatesPath := "/opt/cryostat.d/templates.d" - clientlibPath := "/opt/cryostat.d/clientlib.d" - probesPath := "/opt/cryostat.d/probes.d" envs := []corev1.EnvVar{ { @@ -968,26 +969,10 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Name: "CRYOSTAT_CONFIG_PATH", Value: configPath, }, - { - Name: "CRYOSTAT_ARCHIVE_PATH", - Value: archivePath, - }, { Name: "CRYOSTAT_TEMPLATE_PATH", Value: templatesPath, }, - { - Name: "CRYOSTAT_CLIENTLIB_PATH", - Value: clientlibPath, - }, - { - Name: "CRYOSTAT_PROBE_TEMPLATE_PATH", - Value: probesPath, - }, - { - Name: "CRYOSTAT_ENABLE_JDP_BROADCAST", - Value: "false", - }, } mounts := []corev1.VolumeMount{ @@ -996,26 +981,11 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag MountPath: configPath, SubPath: "config", }, - { - Name: cr.Name, - MountPath: archivePath, - SubPath: "flightrecordings", - }, { Name: cr.Name, MountPath: templatesPath, SubPath: "templates", }, - { - Name: cr.Name, - MountPath: clientlibPath, - SubPath: "clientlib", - }, - { - Name: cr.Name, - MountPath: probesPath, - SubPath: "probes", - }, { Name: cr.Name, MountPath: "truststore", @@ -1031,8 +1001,8 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag optional := false secretName := cr.Name + "-db" - if cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil { - secretName = *cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName + if cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil { + secretName = *cr.Spec.DatabaseOptions.SecretName } envs = append(envs, corev1.EnvVar{ Name: "QUARKUS_DATASOURCE_PASSWORD", @@ -1041,7 +1011,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag LocalObjectReference: corev1.LocalObjectReference{ Name: secretName, }, - Key: "CONNECTION_KEY", + Key: constants.DatabaseSecretConnectionKey, Optional: &optional, }, }, @@ -1071,19 +1041,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Value: "$(QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY)", }) - if specs.CoreURL != nil { - coreEnvs := []corev1.EnvVar{ - { - Name: "CRYOSTAT_EXT_WEB_PORT", - Value: getPort(specs.CoreURL), - }, - { - Name: "CRYOSTAT_WEB_HOST", - Value: specs.CoreURL.Hostname(), - }, - } - envs = append(envs, coreEnvs...) - } if specs.ReportsURL != nil { reportsEnvs := []corev1.EnvVar{ { @@ -1107,16 +1064,16 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag targetCacheSize := "-1" targetCacheTTL := "10" - if cr.Spec.JmxCacheOptions != nil { - if cr.Spec.JmxCacheOptions.TargetCacheSize != 0 { - targetCacheSize = strconv.Itoa(int(cr.Spec.JmxCacheOptions.TargetCacheSize)) + if cr.Spec.TargetConnectionCacheOptions != nil { + if cr.Spec.TargetConnectionCacheOptions.TargetCacheSize != 0 { + targetCacheSize = strconv.Itoa(int(cr.Spec.TargetConnectionCacheOptions.TargetCacheSize)) } - if cr.Spec.JmxCacheOptions.TargetCacheTTL != 0 { - targetCacheTTL = strconv.Itoa(int(cr.Spec.JmxCacheOptions.TargetCacheTTL)) + if cr.Spec.TargetConnectionCacheOptions.TargetCacheTTL != 0 { + targetCacheTTL = strconv.Itoa(int(cr.Spec.TargetConnectionCacheOptions.TargetCacheTTL)) } } - jmxCacheEnvs := []corev1.EnvVar{ + connectionCacheEnvs := []corev1.EnvVar{ { Name: "CRYOSTAT_CONNECTIONS_MAX_OPEN", Value: targetCacheSize, @@ -1126,7 +1083,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Value: targetCacheTTL, }, } - envs = append(envs, jmxCacheEnvs...) + envs = append(envs, connectionCacheEnvs...) envsFrom := []corev1.EnvFromSource{ { SecretRef: &corev1.SecretEnvSource{ @@ -1181,33 +1138,21 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Value: datasourceURL, }, } - if specs.GrafanaURL != nil { + if specs.AuthProxyURL != nil { grafanaVars = append(grafanaVars, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: specs.GrafanaURL.String(), + Value: fmt.Sprintf("%s/grafana/", specs.AuthProxyURL.String()), }, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_URL", Value: getInternalDashboardURL(tls), - }) + }, + ) } envs = append(envs, grafanaVars...) - if tls == nil { - // If TLS isn't set up, tell Cryostat to not use it - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_DISABLE_SSL", - Value: "true", - }) - // Set CRYOSTAT_SSL_PROXIED if Ingress/Route use HTTPS - if specs.CoreURL != nil && specs.CoreURL.Scheme == "https" { - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_SSL_PROXIED", - Value: "true", - }) - } - } else { + if tls != nil { // Configure keystore location and password in expected environment variables envs = append(envs, corev1.EnvVar{ Name: "KEYSTORE_PATH", @@ -1302,6 +1247,18 @@ func NewGrafanaContainerResource(cr *model.CryostatInstance) *corev1.ResourceReq func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSConfig) corev1.Container { envs := []corev1.EnvVar{ + { + Name: "GF_AUTH_ANONYMOUS_ENABLED", + Value: "true", + }, + { + Name: "GF_SERVER_DOMAIN", + Value: "localhost", + }, + { + Name: "GF_SERVER_SERVE_FROM_SUB_PATH", + Value: "true", + }, { Name: "JFR_DATASOURCE_URL", Value: datasourceURL, @@ -1317,6 +1274,10 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo Name: "GF_SERVER_PROTOCOL", Value: "https", }, + { + Name: "GF_SERVER_ROOT_URL", + Value: fmt.Sprintf("%s://localhost:%d/grafana/", "https", constants.AuthProxyHttpContainerPort), + }, { Name: "GF_SERVER_CERT_KEY", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/%s", tls.GrafanaSecret, corev1.TLSPrivateKeyKey), @@ -1338,6 +1299,11 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo // Use HTTPS for liveness probe livenessProbeScheme = corev1.URISchemeHTTPS + } else { + envs = append(envs, corev1.EnvVar{ + Name: "GF_SERVER_ROOT_URL", + Value: fmt.Sprintf("%s://localhost:%d/grafana/", "http", constants.AuthProxyHttpContainerPort), + }) } var containerSc *corev1.SecurityContext @@ -1364,15 +1330,6 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo }, }, Env: envs, - EnvFrom: []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Name + "-grafana-basic", - }, - }, - }, - }, LivenessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ @@ -1387,19 +1344,21 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo } } -/* - * storage.image.repository - Repository for the database container - * storage.image.pullPolicy - Pull Policy for the database container - * storage.image.tag - Image tag for the database container - * storage.resources - Resource requests/limits for the database container - * storage.securityContext - Security Context for the database container - */ +func NewStorageContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{} + if cr.Spec.Resources != nil { + resources = cr.Spec.Resources.ObjectStorageResources.DeepCopy() + } + populateResourceRequest(resources, defaultStorageCpuRequest, defaultStorageMemoryRequest) + return resources +} + func NewStorageContainer(cr *model.CryostatInstance, imageTag string, tls *TLSConfig) corev1.Container { var containerSc *corev1.SecurityContext envs := []corev1.EnvVar{ { Name: "CRYOSTAT_BUCKETS", - Value: "archivedrecordings,archivedreports,eventtemplates", + Value: "archivedrecordings,archivedreports,eventtemplates,probes", }, { Name: "CRYOSTAT_ACCESS_KEY", @@ -1479,23 +1438,19 @@ func NewStorageContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo ProbeHandler: probeHandler, FailureThreshold: 13, }, + Resources: *NewStorageContainerResource(cr), } } -/* -* { - Name: cr.Name, - MountPath: "/var/lib/pgsql/data", - SubPath: "postgres", - }, -*/ -/* - * db.image.repository - Repository for the database container - * db.image.pullPolicy - Pull Policy for the database container - * db.image.tag - Image tag for the database container - * db.resources - Resource requests/limits for the database container - * db.securityContext - Security Context for the database container - */ +func NewDatabaseContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{} + if cr.Spec.Resources != nil { + resources = cr.Spec.Resources.DatabaseResources.DeepCopy() + } + populateResourceRequest(resources, defaultDatabaseCpuRequest, defaultDatabaseMemoryRequest) + return resources +} + func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSConfig) corev1.Container { var containerSc *corev1.SecurityContext if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.DatabaseSecurityContext != nil { @@ -1530,7 +1485,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC LocalObjectReference: corev1.LocalObjectReference{ Name: secretName, }, - Key: "CONNECTION_KEY", + Key: constants.DatabaseSecretConnectionKey, Optional: &optional, }, }, @@ -1543,7 +1498,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC LocalObjectReference: corev1.LocalObjectReference{ Name: secretName, }, - Key: "ENCRYPTION_KEY", + Key: constants.DatabaseSecretEncryptionKey, Optional: &optional, }, }, @@ -1553,7 +1508,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC { Name: cr.Name, MountPath: "/data", - SubPath: "seaweed", + SubPath: "postgres", }, } @@ -1576,6 +1531,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC }, }, }, + Resources: *NewDatabaseContainerResource(cr), } } diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index d417b62ff..18f1a71f2 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -39,4 +39,9 @@ const ( // ALL capability to drop for restricted pod security. See: // https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted CapabilityAll corev1.Capability = "ALL" + + // DatabaseSecretConnectionKey indexes the database connection password within the Cryostat database Secret + DatabaseSecretConnectionKey = "CONNECTION_KEY" + // DatabaseSecretEncryptionKey indexes the database encryption key within the Cryostat database Secret + DatabaseSecretEncryptionKey = "ENCRYPTION_KEY" ) diff --git a/internal/controllers/ingresses.go b/internal/controllers/ingresses.go index 307307875..d73c2ebeb 100644 --- a/internal/controllers/ingresses.go +++ b/internal/controllers/ingresses.go @@ -48,6 +48,7 @@ func (r *Reconciler) reconcileCoreIngress(ctx context.Context, cr *model.Cryosta if err != nil { return err } + specs.AuthProxyURL = url specs.CoreURL = url return nil } diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 484615959..dea4149b8 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -66,7 +66,7 @@ type cryostatTestInput struct { func (c *controllerTest) commonBeforeEach() *cryostatTestInput { t := &cryostatTestInput{ TestReconcilerConfig: test.TestReconcilerConfig{ - GeneratedPasswords: []string{"auth_cookie_secret", "grafana", "credentials_database", "encryption_key", "object_storage", "jmx", "keystore"}, + GeneratedPasswords: []string{"auth_cookie_secret", "credentials_database", "encryption_key", "object_storage", "jmx", "keystore"}, }, TestResources: &test.TestResources{ Name: "cryostat", @@ -145,7 +145,6 @@ func resourceChecks() []resourceCheck { {func(t *cryostatTestInput) { t.expectPVC(t.NewDefaultPVC()) }, "persistent volume claim"}, - {(*cryostatTestInput).expectGrafanaSecret, "Grafana secret"}, {(*cryostatTestInput).expectCredentialsDatabaseSecret, "credentials database secret"}, {(*cryostatTestInput).expectStorageSecret, "object storage secret"}, {(*cryostatTestInput).expectJMXSecret, "JMX secret"}, @@ -166,9 +165,6 @@ func expectSuccessful(t **cryostatTestInput) { It("should set ApplicationURL in CR Status", func() { (*t).expectStatusApplicationURL() }) - It("should set GrafanaSecret in CR Status", func() { - (*t).expectStatusGrafanaSecretName((*t).NewGrafanaSecret().Name) - }) It("should set TLSSetupComplete condition", func() { (*t).checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "AllCertificatesReady") @@ -477,30 +473,6 @@ func (c *controllerTest) commonTests() { }) }) }) - Context("with an existing Grafana Secret", func() { - var cr *model.CryostatInstance - var oldSecret *corev1.Secret - BeforeEach(func() { - cr = t.NewCryostat() - oldSecret = t.OtherGrafanaSecret() - t.objs = append(t.objs, cr.Object, oldSecret) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - }) - It("should update the username but not password", func() { - secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: oldSecret.Name, Namespace: t.Namespace}, secret) - Expect(err).ToNot(HaveOccurred()) - - Expect(metav1.IsControlledBy(secret, cr.Object)).To(BeTrue()) - - // Username should be replaced, but not password - expected := t.NewGrafanaSecret() - Expect(secret.StringData["GF_SECURITY_ADMIN_USER"]).To(Equal(expected.StringData["GF_SECURITY_ADMIN_USER"])) - Expect(secret.StringData["GF_SECURITY_ADMIN_PASSWORD"]).To(Equal(oldSecret.StringData["GF_SECURITY_ADMIN_PASSWORD"])) - }) - }) Context("with an existing JMX Secret", func() { var cr *model.CryostatInstance var oldSecret *corev1.Secret @@ -2448,17 +2420,6 @@ func (t *cryostatTestInput) expectEmptyDir(expectedEmptyDir *corev1.EmptyDirVolu Expect(emptyDir.SizeLimit).To(Equal(expectedEmptyDir.SizeLimit)) } -func (t *cryostatTestInput) expectGrafanaSecret() { - secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana-basic", Namespace: t.Namespace}, secret) - Expect(err).ToNot(HaveOccurred()) - - // Compare to desired spec - expectedSecret := t.NewGrafanaSecret() - t.checkMetadata(secret, expectedSecret) - Expect(secret.StringData).To(Equal(expectedSecret.StringData)) -} - func (t *cryostatTestInput) expectCredentialsDatabaseSecret() { secret := &corev1.Secret{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-db", Namespace: t.Namespace}, secret) @@ -2501,11 +2462,6 @@ func (t *cryostatTestInput) expectStatusApplicationURL() { Expect(instance.Status.ApplicationURL).To(Equal(fmt.Sprintf("https://%s.example.com", t.Name))) } -func (t *cryostatTestInput) expectStatusGrafanaSecretName(secretName string) { - instance := t.getCryostatInstance() - Expect(instance.Status.GrafanaSecret).To(Equal(secretName)) -} - func (t *cryostatTestInput) expectDeploymentHasCertSecrets() { deployment := &appsv1.Deployment{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, deployment) @@ -2710,10 +2666,9 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, builtInPortConfigDisabled := cr.Spec.TargetDiscoveryOptions != nil && cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNames && cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNumbers - dbSecretProvided := cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil + dbSecretProvided := cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil t.checkCoreContainer(&coreContainer, ingress, reportsUrl, - cr.Spec.AuthProperties != nil, emptyDir, hasPortConfig, builtInDiscoveryDisabled, @@ -2859,7 +2814,7 @@ func (t *cryostatTestInput) checkDeploymentHasTemplates() { } func (t *cryostatTestInput) checkCoreContainer(container *corev1.Container, ingress bool, - reportsUrl string, authProps bool, + reportsUrl string, emptyDir bool, hasPortConfig bool, builtInDiscoveryDisabled bool, builtInPortConfigDisabled bool, dbSecretProvided bool, @@ -2872,7 +2827,7 @@ func (t *cryostatTestInput) checkCoreContainer(container *corev1.Container, ingr Expect(container.Image).To(Equal(*t.EnvCoreImageTag)) } Expect(container.Ports).To(ConsistOf(t.NewCorePorts())) - Expect(container.Env).To(ConsistOf(t.NewCoreEnvironmentVariables(reportsUrl, authProps, ingress, emptyDir, hasPortConfig, builtInDiscoveryDisabled, builtInPortConfigDisabled, dbSecretProvided))) + Expect(container.Env).To(ConsistOf(t.NewCoreEnvironmentVariables(reportsUrl, ingress, emptyDir, hasPortConfig, builtInDiscoveryDisabled, builtInPortConfigDisabled, dbSecretProvided))) Expect(container.EnvFrom).To(ConsistOf(t.NewCoreEnvFromSource())) Expect(container.VolumeMounts).To(ConsistOf(t.NewCoreVolumeMounts())) Expect(container.LivenessProbe).To(Equal(t.NewCoreLivenessProbe())) @@ -2891,7 +2846,6 @@ func (t *cryostatTestInput) checkGrafanaContainer(container *corev1.Container, r } Expect(container.Ports).To(ConsistOf(t.NewGrafanaPorts())) Expect(container.Env).To(ConsistOf(t.NewGrafanaEnvironmentVariables())) - Expect(container.EnvFrom).To(ConsistOf(t.NewGrafanaEnvFromSource())) Expect(container.VolumeMounts).To(ConsistOf(t.NewGrafanaVolumeMounts())) Expect(container.LivenessProbe).To(Equal(t.NewGrafanaLivenessProbe())) Expect(container.SecurityContext).To(Equal(securityContext)) diff --git a/internal/controllers/routes.go b/internal/controllers/routes.go index ef0b3920d..ac0d47a51 100644 --- a/internal/controllers/routes.go +++ b/internal/controllers/routes.go @@ -48,6 +48,7 @@ func (r *Reconciler) reconcileCoreRoute(ctx context.Context, svc *corev1.Service if err != nil { return err } + specs.AuthProxyURL = url specs.CoreURL = url return nil } diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index 6118ce55c..119a02d01 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -18,6 +18,7 @@ import ( "context" "fmt" + "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/controllers/model" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -29,9 +30,6 @@ func (r *Reconciler) reconcileSecrets(ctx context.Context, cr *model.CryostatIns if err := r.reconcileAuthProxyCookieSecret(ctx, cr); err != nil { return err } - if err := r.reconcileGrafanaSecret(ctx, cr); err != nil { - return err - } if err := r.reconcileDatabaseConnectionSecret(ctx, cr); err != nil { return err } @@ -62,35 +60,6 @@ func (r *Reconciler) reconcileAuthProxyCookieSecret(ctx context.Context, cr *mod }) } -func (r *Reconciler) reconcileGrafanaSecret(ctx context.Context, cr *model.CryostatInstance) error { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + "-grafana-basic", - Namespace: cr.InstallNamespace, - }, - } - - err := r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { - if secret.StringData == nil { - secret.StringData = map[string]string{} - } - secret.StringData["GF_SECURITY_ADMIN_USER"] = "admin" - - // Password is generated, so don't regenerate it when updating - if secret.CreationTimestamp.IsZero() { - secret.StringData["GF_SECURITY_ADMIN_PASSWORD"] = r.GenPasswd(20) - } - return nil - }) - if err != nil { - return err - } - - // Set the Grafana secret in the CR status - cr.Status.GrafanaSecret = secret.Name - return r.Client.Status().Update(ctx, cr.Object) -} - // jmxSecretNameSuffix is the suffix to be appended to the name of a // Cryostat CR to name its JMX credentials secret const jmxSecretNameSuffix = "-jmx-auth" @@ -127,12 +96,6 @@ func (r *Reconciler) reconcileJMXSecret(ctx context.Context, cr *model.CryostatI // Cryostat CR to name its credentials database secret const databaseSecretNameSuffix = "-db" -// databaseSecretConnectionPassKey indexes the database connection password within the Cryostat database Secret -const databaseSecretConnectionPassKey = "CONNECTION_KEY" - -// databaseSecretEncryptionKey indexes the database encryption key within the Cryostat database Secret -const databaseSecretEncryptionKey = "ENCRYPTION_KEY" - func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr *model.CryostatInstance) error { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -141,7 +104,7 @@ func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr * }, } - secretProvided := cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil + secretProvided := cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil if secretProvided { return nil // Do not delete default secret to allow reverting to use default if needed } @@ -153,8 +116,8 @@ func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr * // Password is generated, so don't regenerate it when updating if secret.CreationTimestamp.IsZero() { - secret.StringData[databaseSecretConnectionPassKey] = r.GenPasswd(32) - secret.StringData[databaseSecretEncryptionKey] = r.GenPasswd(32) + secret.StringData[constants.DatabaseSecretConnectionKey] = r.GenPasswd(32) + secret.StringData[constants.DatabaseSecretEncryptionKey] = r.GenPasswd(32) } return nil }) diff --git a/internal/test/resources.go b/internal/test/resources.go index 619ca7621..f68af5544 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -541,7 +541,7 @@ func newPVCSpec(storageClass string, storageRequest string, func (r *TestResources) NewCryostatWithJmxCacheOptionsSpec() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.JmxCacheOptions = &operatorv1beta2.JmxCacheOptions{ + cr.Spec.TargetConnectionCacheOptions = &operatorv1beta2.TargetConnectionCacheOptions{ TargetCacheSize: 10, TargetCacheTTL: 20, } @@ -626,8 +626,8 @@ var providedDatabaseSecretName string = "credentials-database-secret" func (r *TestResources) NewCryostatWithDatabaseSecretProvided() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.JmxCredentialsDatabaseOptions = &operatorv1beta2.JmxCredentialsDatabaseOptions{ - DatabaseSecretName: &providedDatabaseSecretName, + cr.Spec.DatabaseOptions = &operatorv1beta2.DatabaseOptions{ + SecretName: &providedDatabaseSecretName, } return cr } @@ -900,32 +900,6 @@ func (r *TestResources) NewCACertSecret(ns string) *corev1.Secret { } } -func (r *TestResources) NewGrafanaSecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-grafana-basic", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "GF_SECURITY_ADMIN_USER": "admin", - "GF_SECURITY_ADMIN_PASSWORD": "grafana", - }, - } -} - -func (r *TestResources) OtherGrafanaSecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-grafana-basic", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "GF_SECURITY_ADMIN_USER": "user", - "GF_SECURITY_ADMIN_PASSWORD": "goodpassword", - }, - } -} - func (r *TestResources) NewDatabaseSecret() *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -1289,7 +1263,7 @@ func (r *TestResources) NewStoragePorts() []corev1.ContainerPort { } } -func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps bool, ingress bool, +func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, ingress bool, emptyDir bool, hasPortConfig bool, builtInDiscoveryDisabled bool, builtInPortConfigDisabled bool, dbSecretProvided bool) []corev1.EnvVar { envs := []corev1.EnvVar{ { @@ -1360,26 +1334,10 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps Name: "CRYOSTAT_CONFIG_PATH", Value: "/opt/cryostat.d/conf.d", }, - { - Name: "CRYOSTAT_ARCHIVE_PATH", - Value: "/opt/cryostat.d/recordings.d", - }, { Name: "CRYOSTAT_TEMPLATE_PATH", Value: "/opt/cryostat.d/templates.d", }, - { - Name: "CRYOSTAT_CLIENTLIB_PATH", - Value: "/opt/cryostat.d/clientlib.d", - }, - { - Name: "CRYOSTAT_PROBE_TEMPLATE_PATH", - Value: "/opt/cryostat.d/probes.d", - }, - { - Name: "CRYOSTAT_ENABLE_JDP_BROADCAST", - Value: "false", - }, { Name: "CRYOSTAT_CONNECTIONS_MAX_OPEN", Value: "-1", @@ -1442,20 +1400,7 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps }, ) - if !r.TLS { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_DISABLE_SSL", - Value: "true", - }) - if r.ExternalTLS { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_SSL_PROXIED", - Value: "true", - }) - } - } else { + if r.TLS { envs = append(envs, corev1.EnvVar{ Name: "KEYSTORE_PATH", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-tls/keystore.p12", r.Name), @@ -1485,36 +1430,18 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps } func (r *TestResources) newNetworkEnvironmentVariables() []corev1.EnvVar { - envs := []corev1.EnvVar{ - { - Name: "CRYOSTAT_WEB_HOST", - Value: r.Name + ".example.com", - }, - } - if r.ExternalTLS { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_EXT_WEB_PORT", - Value: "443", - }) - } else { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_EXT_WEB_PORT", - Value: "80", - }) - } + envs := []corev1.EnvVar{} if r.ExternalTLS { envs = append(envs, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: fmt.Sprintf("https://%s-grafana.example.com", r.Name), + Value: fmt.Sprintf("https://%s.example.com/grafana/", r.Name), }) } else { envs = append(envs, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: fmt.Sprintf("http://%s-grafana.example.com", r.Name), + Value: fmt.Sprintf("http://%s.example.com/grafana/", r.Name), }) } if r.TLS { @@ -1539,6 +1466,21 @@ func (r *TestResources) NewGrafanaEnvironmentVariables() []corev1.EnvVar { Name: "JFR_DATASOURCE_URL", Value: "http://127.0.0.1:8989", }, + { + Name: "GF_AUTH_ANONYMOUS_ENABLED", + Value: "true", + ValueFrom: nil, + }, + { + Name: "GF_SERVER_DOMAIN", + Value: "localhost", + ValueFrom: nil, + }, + { + Name: "GF_SERVER_SERVE_FROM_SUB_PATH", + Value: "true", + ValueFrom: nil, + }, } if r.TLS { envs = append(envs, corev1.EnvVar{ @@ -1550,6 +1492,14 @@ func (r *TestResources) NewGrafanaEnvironmentVariables() []corev1.EnvVar { }, corev1.EnvVar{ Name: "GF_SERVER_CERT_FILE", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-grafana-tls/tls.crt", r.Name), + }, corev1.EnvVar{ + Name: "GF_SERVER_ROOT_URL", + Value: "https://localhost:4180/grafana/", + }) + } else { + envs = append(envs, corev1.EnvVar{ + Name: "GF_SERVER_ROOT_URL", + Value: "http://localhost:4180/grafana/", }) } return envs @@ -1644,18 +1594,6 @@ func (r *TestResources) NewCoreEnvFromSource() []corev1.EnvFromSource { return envsFrom } -func (r *TestResources) NewGrafanaEnvFromSource() []corev1.EnvFromSource { - return []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: r.Name + "-grafana-basic", - }, - }, - }, - } -} - func (r *TestResources) NewJmxCacheOptionsEnv() []corev1.EnvVar { return []corev1.EnvVar{ { @@ -1722,30 +1660,12 @@ func (r *TestResources) NewCoreVolumeMounts() []corev1.VolumeMount { MountPath: "/opt/cryostat.d/conf.d", SubPath: "config", }, - { - Name: r.Name, - ReadOnly: false, - MountPath: "/opt/cryostat.d/recordings.d", - SubPath: "flightrecordings", - }, { Name: r.Name, ReadOnly: false, MountPath: "/opt/cryostat.d/templates.d", SubPath: "templates", }, - { - Name: r.Name, - ReadOnly: false, - MountPath: "/opt/cryostat.d/clientlib.d", - SubPath: "clientlib", - }, - { - Name: r.Name, - ReadOnly: false, - MountPath: "/opt/cryostat.d/probes.d", - SubPath: "probes", - }, { Name: r.Name, ReadOnly: false, @@ -2859,7 +2779,7 @@ func newCoreContainerDefaultResource() *corev1.ResourceRequirements { return &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("256Mi"), + corev1.ResourceMemory: resource.MustParse("384Mi"), }, } } @@ -2887,7 +2807,7 @@ func newDatasourceContainerDefaultResource() *corev1.ResourceRequirements { return &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("200m"), - corev1.ResourceMemory: resource.MustParse("384Mi"), + corev1.ResourceMemory: resource.MustParse("200Mi"), }, } } @@ -2914,8 +2834,8 @@ func (r *TestResources) NewDatasourceContainerResource(cr *model.CryostatInstanc func newGrafanaContainerDefaultResource() *corev1.ResourceRequirements { return &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("100m"), - corev1.ResourceMemory: resource.MustParse("120Mi"), + corev1.ResourceCPU: resource.MustParse("25m"), + corev1.ResourceMemory: resource.MustParse("80Mi"), }, } } @@ -2942,8 +2862,8 @@ func (r *TestResources) NewGrafanaContainerResource(cr *model.CryostatInstance) func newReportContainerDefaultResource() *corev1.ResourceRequirements { return &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("200m"), - corev1.ResourceMemory: resource.MustParse("384Mi"), + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("512Mi"), }, } } From 70351e1edad620865c82657ebe32afc1cb882896 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Wed, 8 May 2024 14:05:17 -0400 Subject: [PATCH 34/53] chore(grafana): remove separate Grafana service/route/ingress (#809) --- api/v1beta1/cryostat_conversion.go | 18 +- api/v1beta1/cryostat_conversion_test.go | 4 - api/v1beta2/cryostat_types.go | 18 - api/v1beta2/zz_generated.deepcopy.go | 31 -- ...yostat-operator.clusterserviceversion.yaml | 18 +- .../operator.cryostat.io_cryostats.yaml | 341 ------------------ .../bases/operator.cryostat.io_cryostats.yaml | 341 ------------------ ...yostat-operator.clusterserviceversion.yaml | 16 - .../resource_definitions.go | 1 - internal/controllers/ingresses.go | 35 -- internal/controllers/reconciler.go | 4 - internal/controllers/reconciler_test.go | 78 +--- internal/controllers/routes.go | 30 -- internal/controllers/services.go | 56 --- internal/test/clients.go | 2 +- internal/test/conversion.go | 8 +- internal/test/resources.go | 137 +------ internal/test/scorecard/common_utils.go | 31 -- 18 files changed, 11 insertions(+), 1158 deletions(-) diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index 301ca0b4f..0d8bc4424 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -124,12 +124,6 @@ func convertServiceOptionsTo(srcOpts *ServiceConfigList) *operatorv1beta2.Servic ServiceConfig: convertServiceConfigTo(srcOpts.CoreConfig.ServiceConfig), } } - if srcOpts.GrafanaConfig != nil { - dstOpts.GrafanaConfig = &operatorv1beta2.GrafanaServiceConfig{ - HTTPPort: srcOpts.GrafanaConfig.HTTPPort, - ServiceConfig: convertServiceConfigTo(srcOpts.GrafanaConfig.ServiceConfig), - } - } if srcOpts.ReportsConfig != nil { dstOpts.ReportsConfig = &operatorv1beta2.ReportsServiceConfig{ HTTPPort: srcOpts.ReportsConfig.HTTPPort, @@ -152,8 +146,7 @@ func convertNetworkOptionsTo(srcOpts *NetworkConfigurationList) *operatorv1beta2 var dstOpts *operatorv1beta2.NetworkConfigurationList if srcOpts != nil { dstOpts = &operatorv1beta2.NetworkConfigurationList{ - CoreConfig: convertNetworkConfigTo(srcOpts.CoreConfig), - GrafanaConfig: convertNetworkConfigTo(srcOpts.GrafanaConfig), + CoreConfig: convertNetworkConfigTo(srcOpts.CoreConfig), } } return dstOpts @@ -393,12 +386,6 @@ func convertServiceOptionsFrom(srcOpts *operatorv1beta2.ServiceConfigList) *Serv ServiceConfig: convertServiceConfigFrom(srcOpts.CoreConfig.ServiceConfig), } } - if srcOpts.GrafanaConfig != nil { - dstOpts.GrafanaConfig = &GrafanaServiceConfig{ - HTTPPort: srcOpts.GrafanaConfig.HTTPPort, - ServiceConfig: convertServiceConfigFrom(srcOpts.GrafanaConfig.ServiceConfig), - } - } if srcOpts.ReportsConfig != nil { dstOpts.ReportsConfig = &ReportsServiceConfig{ HTTPPort: srcOpts.ReportsConfig.HTTPPort, @@ -421,8 +408,7 @@ func convertNetworkOptionsFrom(srcOpts *operatorv1beta2.NetworkConfigurationList var dstOpts *NetworkConfigurationList if srcOpts != nil { dstOpts = &NetworkConfigurationList{ - CoreConfig: convertNetworkConfigFrom(srcOpts.CoreConfig), - GrafanaConfig: convertNetworkConfigFrom(srcOpts.GrafanaConfig), + CoreConfig: convertNetworkConfigFrom(srcOpts.CoreConfig), } } return dstOpts diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go index 443b69cdb..ccc9ad597 100644 --- a/api/v1beta1/cryostat_conversion_test.go +++ b/api/v1beta1/cryostat_conversion_test.go @@ -115,14 +115,10 @@ func tableEntries() []TableEntry { (*test.TestResources).NewCryostatWithEmptyDirSpec), Entry("core service", (*test.TestResources).NewCryostatWithCoreSvcV1Beta1, (*test.TestResources).NewCryostatWithCoreSvc), - Entry("Grafana service", (*test.TestResources).NewCryostatWithGrafanaSvcV1Beta1, - (*test.TestResources).NewCryostatWithGrafanaSvc), Entry("reports service", (*test.TestResources).NewCryostatWithReportsSvcV1Beta1, (*test.TestResources).NewCryostatWithReportsSvc), Entry("core ingress", (*test.TestResources).NewCryostatWithCoreNetworkOptionsV1Beta1, (*test.TestResources).NewCryostatWithCoreNetworkOptions), - Entry("Grafana ingress", (*test.TestResources).NewCryostatWithGrafanaNetworkOptionsV1Beta1, - (*test.TestResources).NewCryostatWithGrafanaNetworkOptions), Entry("reports resources", (*test.TestResources).NewCryostatWithReportsResourcesV1Beta1, (*test.TestResources).NewCryostatWithReportsResources), Entry("reports low resource limit", (*test.TestResources).NewCryostatWithReportLowResourceLimitV1Beta1, diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 1655ef883..81a189a21 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -292,16 +292,6 @@ type CoreServiceConfig struct { ServiceConfig `json:",inline"` } -// GrafanaServiceConfig provides customization for the service handling -// traffic for the Grafana dashboard. -type GrafanaServiceConfig struct { - // HTTP port number for the Grafana dashboard service. - // Defaults to 3000. - // +optional - HTTPPort *int32 `json:"httpPort,omitempty"` - ServiceConfig `json:",inline"` -} - // ReportsServiceConfig provides customization for the service handling // traffic for the cryostat-reports sidecars. type ReportsServiceConfig struct { @@ -318,9 +308,6 @@ type ServiceConfigList struct { // Specification for the service responsible for the Cryostat application. // +optional CoreConfig *CoreServiceConfig `json:"coreConfig,omitempty"` - // Specification for the service responsible for the Cryostat Grafana dashboard. - // +optional - GrafanaConfig *GrafanaServiceConfig `json:"grafanaConfig,omitempty"` // Specification for the service responsible for the cryostat-reports sidecars. // +optional ReportsConfig *ReportsServiceConfig `json:"reportsConfig,omitempty"` @@ -357,11 +344,6 @@ type NetworkConfigurationList struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec CoreConfig *NetworkConfiguration `json:"coreConfig,omitempty"` - // Specifications for how to expose Cryostat's Grafana service, - // which serves the Grafana dashboard. - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec - GrafanaConfig *NetworkConfiguration `json:"grafanaConfig,omitempty"` } // PersistentVolumeClaimConfig holds all customization options to diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 0fa1bd72c..973fbf820 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -361,27 +361,6 @@ func (in *EmptyDirConfig) DeepCopy() *EmptyDirConfig { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GrafanaServiceConfig) DeepCopyInto(out *GrafanaServiceConfig) { - *out = *in - if in.HTTPPort != nil { - in, out := &in.HTTPPort, &out.HTTPPort - *out = new(int32) - **out = **in - } - in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaServiceConfig. -func (in *GrafanaServiceConfig) DeepCopy() *GrafanaServiceConfig { - if in == nil { - return nil - } - out := new(GrafanaServiceConfig) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NetworkConfiguration) DeepCopyInto(out *NetworkConfiguration) { *out = *in @@ -424,11 +403,6 @@ func (in *NetworkConfigurationList) DeepCopyInto(out *NetworkConfigurationList) *out = new(NetworkConfiguration) (*in).DeepCopyInto(*out) } - if in.GrafanaConfig != nil { - in, out := &in.GrafanaConfig, &out.GrafanaConfig - *out = new(NetworkConfiguration) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkConfigurationList. @@ -798,11 +772,6 @@ func (in *ServiceConfigList) DeepCopyInto(out *ServiceConfigList) { *out = new(CoreServiceConfig) (*in).DeepCopyInto(*out) } - if in.GrafanaConfig != nil { - in, out := &in.GrafanaConfig, &out.GrafanaConfig - *out = new(GrafanaServiceConfig) - (*in).DeepCopyInto(*out) - } if in.ReportsConfig != nil { in, out := &in.ReportsConfig, &out.ReportsConfig *out = new(ReportsServiceConfig) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index c05bf7536..7a74e296d 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-06T20:05:20Z" + createdAt: "2024-05-08T15:33:40Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -612,22 +612,6 @@ spec: label with key "app" is reserved for use by the operator. displayName: Labels path: networkOptions.coreConfig.labels - - description: Specifications for how to expose Cryostat's Grafana service, - which serves the Grafana dashboard. - displayName: Grafana Config - path: networkOptions.grafanaConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.grafanaConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.grafanaConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.grafanaConfig.labels - description: Options to configure the Cryostat deployments and pods metadata displayName: Operand metadata path: operandMetadata diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 2104aa932..5b4a334a8 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -5551,321 +5551,6 @@ spec: by the operator. type: object type: object - grafanaConfig: - description: Specifications for how to expose Cryostat's Grafana - service, which serves the Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: service references a service as a backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: paths is a collection of paths - that map requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. - items: - description: IngressTLS describes the transport layer - security associated with an ingress. - properties: - hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the "Host" header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object type: object operandMetadata: description: Options to configure the Cryostat deployments and pods @@ -9711,32 +9396,6 @@ spec: description: Type of service to create. Defaults to "ClusterIP". type: string type: object - grafanaConfig: - description: Specification for the service responsible for the - Cryostat Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Grafana dashboard service. - Defaults to 3000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object reportsConfig: description: Specification for the service responsible for the cryostat-reports sidecars. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index fd1d66c0c..7d6fb2d6b 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -5541,321 +5541,6 @@ spec: by the operator. type: object type: object - grafanaConfig: - description: Specifications for how to expose Cryostat's Grafana - service, which serves the Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the Ingress or Route during - its creation. - type: object - ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. - properties: - defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. - properties: - resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: service references a service as a backend. - This is a mutually exclusive setting with "Resource". - properties: - name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. - type: string - port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. - properties: - name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". - type: string - number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. - type: string - rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. - items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. - properties: - host: - description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." - type: string - http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' - properties: - paths: - description: paths is a collection of paths - that map requests to backends. - items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. - properties: - backend: - description: backend defines the referenced - service endpoint to which the traffic - will be forwarded to. - properties: - resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". - properties: - apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type - of resource being referenced - type: string - name: - description: Name is the name - of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". - properties: - name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. - type: string - port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. - properties: - name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". - type: string - number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". - format: int32 - type: integer - type: object - required: - - name - type: object - type: object - path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". - type: string - pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' - type: string - required: - - backend - - pathType - type: object - type: array - x-kubernetes-list-type: atomic - required: - - paths - type: object - type: object - type: array - x-kubernetes-list-type: atomic - tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. - items: - description: IngressTLS describes the transport layer - security associated with an ingress. - properties: - hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the "Host" header is used for routing. - type: string - type: object - type: array - x-kubernetes-list-type: atomic - type: object - labels: - additionalProperties: - type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. - type: object - type: object type: object operandMetadata: description: Options to configure the Cryostat deployments and pods @@ -9701,32 +9386,6 @@ spec: description: Type of service to create. Defaults to "ClusterIP". type: string type: object - grafanaConfig: - description: Specification for the service responsible for the - Cryostat Grafana dashboard. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the service during its - creation. - type: object - httpPort: - description: HTTP port number for the Grafana dashboard service. - Defaults to 3000. - format: int32 - type: integer - labels: - additionalProperties: - type: string - description: Labels to add to the service during its creation. - The labels with keys "app" and "component" are reserved - for use by the operator. - type: object - serviceType: - description: Type of service to create. Defaults to "ClusterIP". - type: string - type: object reportsConfig: description: Specification for the service responsible for the cryostat-reports sidecars. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 62e4d6a3c..49582ba1e 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -157,22 +157,6 @@ spec: label with key "app" is reserved for use by the operator. displayName: Labels path: networkOptions.coreConfig.labels - - description: Specifications for how to expose Cryostat's Grafana service, - which serves the Grafana dashboard. - displayName: Grafana Config - path: networkOptions.grafanaConfig - - description: Annotations to add to the Ingress or Route during its creation. - displayName: Annotations - path: networkOptions.grafanaConfig.annotations - - description: Configuration for an Ingress object. Currently subpaths are not - supported, so unique hosts must be specified (if a single external IP is - being used) to differentiate between ingresses/services. - displayName: Ingress Spec - path: networkOptions.grafanaConfig.ingressSpec - - description: Labels to add to the Ingress or Route during its creation. The - label with key "app" is reserved for use by the operator. - displayName: Labels - path: networkOptions.grafanaConfig.labels - description: Options to configure the Cryostat deployments and pods metadata displayName: Operand metadata path: operandMetadata diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index a4980bda6..843b0c807 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -49,7 +49,6 @@ type ImageTags struct { type ServiceSpecs struct { AuthProxyURL *url.URL CoreURL *url.URL - GrafanaURL *url.URL ReportsURL *url.URL InsightsURL *url.URL StorageURL *url.URL diff --git a/internal/controllers/ingresses.go b/internal/controllers/ingresses.go index d73c2ebeb..48a53b5fc 100644 --- a/internal/controllers/ingresses.go +++ b/internal/controllers/ingresses.go @@ -53,29 +53,6 @@ func (r *Reconciler) reconcileCoreIngress(ctx context.Context, cr *model.Cryosta return nil } -func (r *Reconciler) reconcileGrafanaIngress(ctx context.Context, cr *model.CryostatInstance, - specs *resource_definitions.ServiceSpecs) error { - ingress := &netv1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + "-grafana", - Namespace: cr.InstallNamespace, - }, - } - - if cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.GrafanaConfig == nil || - cr.Spec.NetworkOptions.GrafanaConfig.IngressSpec == nil { - // User has not requested an Ingress, delete if it exists - return r.deleteIngress(ctx, ingress) - } - grafanaConfig := configureGrafanaIngress(cr) - url, err := r.reconcileIngress(ctx, ingress, cr, grafanaConfig) - if err != nil { - return err - } - specs.GrafanaURL = url - return nil -} - func (r *Reconciler) reconcileIngress(ctx context.Context, ingress *netv1.Ingress, cr *model.CryostatInstance, config *operatorv1beta2.NetworkConfiguration) (*url.URL, error) { ingress, err := r.createOrUpdateIngress(ctx, ingress, cr.Object, config) @@ -131,18 +108,6 @@ func configureCoreIngress(cr *model.CryostatInstance) *operatorv1beta2.NetworkCo return config } -func configureGrafanaIngress(cr *model.CryostatInstance) *operatorv1beta2.NetworkConfiguration { - var config *operatorv1beta2.NetworkConfiguration - if cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.GrafanaConfig == nil { - config = &operatorv1beta2.NetworkConfiguration{} - } else { - config = cr.Spec.NetworkOptions.GrafanaConfig - } - - configureIngress(config, cr.Name, "cryostat") - return config -} - func configureIngress(config *operatorv1beta2.NetworkConfiguration, appLabel string, componentLabel string) { if config.Labels == nil { config.Labels = map[string]string{} diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index 8ed3a3b25..6460bb173 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -253,10 +253,6 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn serviceSpecs := &resources.ServiceSpecs{ InsightsURL: r.InsightsProxy, } - err = r.reconcileGrafanaService(ctx, cr, tlsConfig, serviceSpecs) - if err != nil { - return requeueIfIngressNotReady(reqLogger, err) - } err = r.reconcileCoreService(ctx, cr, tlsConfig, serviceSpecs) if err != nil { return requeueIfIngressNotReady(reqLogger, err) diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index dea4149b8..50ce08206 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -148,7 +148,6 @@ func resourceChecks() []resourceCheck { {(*cryostatTestInput).expectCredentialsDatabaseSecret, "credentials database secret"}, {(*cryostatTestInput).expectStorageSecret, "object storage secret"}, {(*cryostatTestInput).expectJMXSecret, "JMX secret"}, - {(*cryostatTestInput).expectGrafanaService, "Grafana service"}, {(*cryostatTestInput).expectCoreService, "core service"}, {(*cryostatTestInput).expectMainDeployment, "main deployment"}, {(*cryostatTestInput).expectLockConfigMap, "lock config map"}, @@ -520,23 +519,16 @@ func (c *controllerTest) commonTests() { Context("with existing Routes", func() { var cr *model.CryostatInstance var oldCoreRoute *openshiftv1.Route - var oldGrafanaRoute *openshiftv1.Route BeforeEach(func() { cr = t.NewCryostat() oldCoreRoute = t.OtherCoreRoute() - oldGrafanaRoute = t.OtherGrafanaRoute() - t.objs = append(t.objs, cr.Object, oldCoreRoute, oldGrafanaRoute) + t.objs = append(t.objs, cr.Object, oldCoreRoute) }) JustBeforeEach(func() { t.reconcileCryostatFully() }) It("should update the Routes", func() { - expected := t.NewGrafanaRoute() - metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "grafana", "annotation") - metav1.SetMetaDataLabel(&expected.ObjectMeta, "grafana", "label") - t.checkRoute(expected) - - expected = t.NewCoreRoute() + expected := t.NewCoreRoute() metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "custom", "annotation") metav1.SetMetaDataLabel(&expected.ObjectMeta, "custom", "label") t.checkRoute(expected) @@ -1433,14 +1425,6 @@ func (c *controllerTest) commonTests() { t.checkService(t.Name, t.NewCustomizedCoreService()) }) }) - Context("containing grafana config", func() { - BeforeEach(func() { - t.objs = append(t.objs, t.NewCryostatWithGrafanaSvc().Object) - }) - It("should create the service as described", func() { - t.checkService(t.Name+"-grafana", t.NewCustomizedGrafanaService()) - }) - }) Context("containing reports config", func() { BeforeEach(func() { t.ReportReplicas = 1 @@ -1473,14 +1457,6 @@ func (c *controllerTest) commonTests() { t.checkService(t.Name, t.NewCustomizedCoreService()) }) }) - Context("containing grafana config", func() { - BeforeEach(func() { - cr = t.NewCryostatWithGrafanaSvc() - }) - It("should create the service as described", func() { - t.checkService(t.Name+"-grafana", t.NewCustomizedGrafanaService()) - }) - }) Context("containing reports config", func() { BeforeEach(func() { t.ReportReplicas = 1 @@ -1538,14 +1514,6 @@ func (c *controllerTest) commonTests() { t.checkRoute(t.NewCustomCoreRoute()) }) }) - Context("containing grafana config", func() { - BeforeEach(func() { - t.objs = append(t.objs, t.NewCryostatWithGrafanaNetworkOptions().Object) - }) - It("should create the route as described", func() { - t.checkRoute(t.NewCustomGrafanaRoute()) - }) - }) }) Context("with security options", func() { JustBeforeEach(func() { @@ -1917,23 +1885,16 @@ func (c *controllerTest) commonTests() { Context("with existing Ingresses", func() { var cr *model.CryostatInstance var oldCoreIngress *netv1.Ingress - var oldGrafanaIngress *netv1.Ingress BeforeEach(func() { cr = t.NewCryostatWithIngress() oldCoreIngress = t.OtherCoreIngress() - oldGrafanaIngress = t.OtherGrafanaIngress() - t.objs = append(t.objs, cr.Object, oldCoreIngress, oldGrafanaIngress) + t.objs = append(t.objs, cr.Object, oldCoreIngress) }) JustBeforeEach(func() { t.reconcileCryostatFully() }) It("should update the Ingresses", func() { - expected := t.NewGrafanaIngress() - metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "other-grafana", "annotation") - metav1.SetMetaDataLabel(&expected.ObjectMeta, "other-grafana", "label") - t.checkIngress(expected) - - expected = t.NewCoreIngress() + expected := t.NewCoreIngress() metav1.SetMetaDataAnnotation(&expected.ObjectMeta, "other", "annotation") metav1.SetMetaDataLabel(&expected.ObjectMeta, "other", "label") t.checkIngress(expected) @@ -1951,20 +1912,10 @@ func (c *controllerTest) commonTests() { t.updateCryostatInstance(c) t.reconcileCryostatFully() - expectedConfig := cr.Spec.NetworkOptions - expectedConfig.GrafanaConfig.Labels["app"] = cr.Name - expectedConfig.GrafanaConfig.Labels["component"] = "cryostat" ingress := &netv1.Ingress{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, ingress) Expect(kerrors.IsNotFound(err)).To(BeTrue()) - - err = t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana", Namespace: t.Namespace}, ingress) - Expect(err).ToNot(HaveOccurred()) - Expect(ingress.Annotations).To(Equal(expectedConfig.GrafanaConfig.Annotations)) - Expect(ingress.Labels).To(Equal(expectedConfig.GrafanaConfig.Labels)) - Expect(ingress.Spec).To(Equal(*expectedConfig.GrafanaConfig.IngressSpec)) - }) }) Context("ingressSpec for one of the services is nil", func() { @@ -1979,18 +1930,9 @@ func (c *controllerTest) commonTests() { t.updateCryostatInstance(c) t.reconcileCryostatFully() - expectedConfig := cr.Spec.NetworkOptions - expectedConfig.GrafanaConfig.Labels["app"] = cr.Name - expectedConfig.GrafanaConfig.Labels["component"] = "cryostat" ingress := &netv1.Ingress{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana", Namespace: t.Namespace}, ingress) - Expect(err).ToNot(HaveOccurred()) - Expect(ingress.Annotations).To(Equal(expectedConfig.GrafanaConfig.Annotations)) - Expect(ingress.Labels).To(Equal(expectedConfig.GrafanaConfig.Labels)) - Expect(ingress.Spec).To(Equal(*expectedConfig.GrafanaConfig.IngressSpec)) - - err = t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, ingress) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, ingress) Expect(kerrors.IsNotFound(err)).To(BeTrue()) }) }) @@ -2175,7 +2117,6 @@ func (c *controllerTest) commonTests() { } func (t *cryostatTestInput) expectRoutes() { - t.checkRoute(t.NewGrafanaRoute()) t.checkRoute(t.NewCoreRoute()) } @@ -2352,13 +2293,10 @@ func (t *cryostatTestInput) expectNoRoutes() { svc := &openshiftv1.Route{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, svc) Expect(kerrors.IsNotFound(err)).To(BeTrue()) - err = t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana", Namespace: t.Namespace}, svc) - Expect(kerrors.IsNotFound(err)).To(BeTrue()) } func (t *cryostatTestInput) expectIngresses() { t.checkIngress(t.NewCoreIngress()) - t.checkIngress(t.NewGrafanaIngress()) } func (t *cryostatTestInput) checkIngress(expected *netv1.Ingress) { @@ -2374,8 +2312,6 @@ func (t *cryostatTestInput) expectNoIngresses() { ing := &netv1.Ingress{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, ing) Expect(kerrors.IsNotFound(err)).To(BeTrue()) - err = t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana", Namespace: t.Namespace}, ing) - Expect(kerrors.IsNotFound(err)).To(BeTrue()) } func (t *cryostatTestInput) expectLockConfigMap() { @@ -2492,10 +2428,6 @@ func (t *cryostatTestInput) expectCryostatFinalizerPresent() { Expect(cr.Object.GetFinalizers()).To(ContainElement("operator.cryostat.io/cryostat.finalizer")) } -func (t *cryostatTestInput) expectGrafanaService() { - t.checkService(t.Name+"-grafana", t.NewGrafanaService()) -} - func (t *cryostatTestInput) checkService(svcName string, expected *corev1.Service) { service := &corev1.Service{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: svcName, Namespace: t.Namespace}, service) diff --git a/internal/controllers/routes.go b/internal/controllers/routes.go index ac0d47a51..a26640ed4 100644 --- a/internal/controllers/routes.go +++ b/internal/controllers/routes.go @@ -53,24 +53,6 @@ func (r *Reconciler) reconcileCoreRoute(ctx context.Context, svc *corev1.Service return nil } -func (r *Reconciler) reconcileGrafanaRoute(ctx context.Context, svc *corev1.Service, cr *model.CryostatInstance, - tls *resource_definitions.TLSConfig, specs *resource_definitions.ServiceSpecs) error { - route := &routev1.Route{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + "-grafana", - Namespace: cr.InstallNamespace, - }, - } - - grafanaConfig := configureGrafanaRoute(cr) - url, err := r.reconcileRoute(ctx, route, svc, cr, tls, grafanaConfig) - if err != nil { - return err - } - specs.GrafanaURL = url - return nil -} - // ErrIngressNotReady is returned when Kubernetes has not yet exposed our services // so that they may be accessed outside of the cluster var ErrIngressNotReady = goerrors.New("ingress configuration not yet available") @@ -164,18 +146,6 @@ func configureCoreRoute(cr *model.CryostatInstance) *operatorv1beta2.NetworkConf return config } -func configureGrafanaRoute(cr *model.CryostatInstance) *operatorv1beta2.NetworkConfiguration { - var config *operatorv1beta2.NetworkConfiguration - if cr.Spec.NetworkOptions == nil || cr.Spec.NetworkOptions.GrafanaConfig == nil { - config = &operatorv1beta2.NetworkConfiguration{} - } else { - config = cr.Spec.NetworkOptions.GrafanaConfig - } - - configureRoute(config, cr.Name, "cryostat") - return config -} - func configureRoute(config *operatorv1beta2.NetworkConfiguration, appLabel string, componentLabel string) { if config.Labels == nil { config.Labels = map[string]string{} diff --git a/internal/controllers/services.go b/internal/controllers/services.go index 7147a773f..e8ce4c61e 100644 --- a/internal/controllers/services.go +++ b/internal/controllers/services.go @@ -72,41 +72,6 @@ func (r *Reconciler) reconcileCoreService(ctx context.Context, cr *model.Cryosta } } -func (r *Reconciler) reconcileGrafanaService(ctx context.Context, cr *model.CryostatInstance, - tls *resource_definitions.TLSConfig, specs *resource_definitions.ServiceSpecs) error { - svc := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + "-grafana", - Namespace: cr.InstallNamespace, - }, - } - - config := configureGrafanaService(cr) - err := r.createOrUpdateService(ctx, svc, cr.Object, &config.ServiceConfig, func() error { - svc.Spec.Selector = map[string]string{ - "app": cr.Name, - "component": "cryostat", - } - svc.Spec.Ports = []corev1.ServicePort{ - { - Name: "http", - Port: *config.HTTPPort, - TargetPort: intstr.IntOrString{IntVal: 3000}, - }, - } - return nil - }) - if err != nil { - return err - } - - if r.IsOpenShift { - return r.reconcileGrafanaRoute(ctx, svc, cr, tls, specs) - } else { - return r.reconcileGrafanaIngress(ctx, cr, specs) - } -} - func (r *Reconciler) reconcileReportsService(ctx context.Context, cr *model.CryostatInstance, tls *resource_definitions.TLSConfig, specs *resource_definitions.ServiceSpecs) error { config := configureReportsService(cr) @@ -176,27 +141,6 @@ func configureCoreService(cr *model.CryostatInstance) *operatorv1beta2.CoreServi return config } -func configureGrafanaService(cr *model.CryostatInstance) *operatorv1beta2.GrafanaServiceConfig { - // Check CR for config - var config *operatorv1beta2.GrafanaServiceConfig - if cr.Spec.ServiceOptions == nil || cr.Spec.ServiceOptions.GrafanaConfig == nil { - config = &operatorv1beta2.GrafanaServiceConfig{} - } else { - config = cr.Spec.ServiceOptions.GrafanaConfig.DeepCopy() - } - - // Apply common service defaults - configureService(&config.ServiceConfig, cr.Name, "cryostat") - - // Apply default HTTP port if not provided - if config.HTTPPort == nil { - httpPort := constants.GrafanaContainerPort - config.HTTPPort = &httpPort - } - - return config -} - func configureReportsService(cr *model.CryostatInstance) *operatorv1beta2.ReportsServiceConfig { // Check CR for config var config *operatorv1beta2.ReportsServiceConfig diff --git a/internal/test/clients.go b/internal/test/clients.go index 05632c1ae..56152542e 100644 --- a/internal/test/clients.go +++ b/internal/test/clients.go @@ -104,7 +104,7 @@ func (c *testClient) updateRouteStatus(ctx context.Context, obj runtime.Object) // If this object is an operator-managed route, mock the behaviour // of OpenShift's router by setting a dummy hostname in its Status route, ok := obj.(*routev1.Route) - if ok && c.matchesName(route, c.NewGrafanaRoute(), c.NewCoreRoute()) && + if ok && c.matchesName(route, c.NewCoreRoute()) && len(route.Status.Ingress) == 0 { route.Status.Ingress = append(route.Status.Ingress, routev1.RouteIngress{ Host: route.Name + ".example.com", diff --git a/internal/test/conversion.go b/internal/test/conversion.go index 71eb6485e..86f61472d 100644 --- a/internal/test/conversion.go +++ b/internal/test/conversion.go @@ -630,14 +630,8 @@ func (r *TestResources) newNetworkConfigurationListV1Beta1() operatorv1beta1.Net coreIng.Annotations["custom"] = "annotation" coreIng.Labels["custom"] = "label" - grafanaSVC := r.NewGrafanaService() - grafanaIng := r.newNetworkConfigurationV1Beta1(grafanaSVC.Name, grafanaSVC.Spec.Ports[0].Port) - grafanaIng.Annotations["grafana"] = "annotation" - grafanaIng.Labels["grafana"] = "label" - return operatorv1beta1.NetworkConfigurationList{ - CoreConfig: &coreIng, - GrafanaConfig: &grafanaIng, + CoreConfig: &coreIng, } } diff --git a/internal/test/resources.go b/internal/test/resources.go index f68af5544..0eadf690e 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -251,28 +251,6 @@ func (r *TestResources) NewCryostatWithCoreSvc() *model.CryostatInstance { return cr } -func (r *TestResources) NewCryostatWithGrafanaSvc() *model.CryostatInstance { - svcType := corev1.ServiceTypeNodePort - httpPort := int32(8080) - cr := r.NewCryostat() - cr.Spec.ServiceOptions = &operatorv1beta2.ServiceConfigList{ - GrafanaConfig: &operatorv1beta2.GrafanaServiceConfig{ - HTTPPort: &httpPort, - ServiceConfig: operatorv1beta2.ServiceConfig{ - ServiceType: &svcType, - Annotations: map[string]string{ - "my/custom": "annotation", - }, - Labels: map[string]string{ - "my": "label", - "app": "somethingelse", - }, - }, - }, - } - return cr -} - func (r *TestResources) NewCryostatWithReportsSvc() *model.CryostatInstance { svcType := corev1.ServiceTypeNodePort httpPort := int32(13161) @@ -310,21 +288,6 @@ func (r *TestResources) NewCryostatWithCoreNetworkOptions() *model.CryostatInsta return cr } -func (r *TestResources) NewCryostatWithGrafanaNetworkOptions() *model.CryostatInstance { - cr := r.NewCryostat() - cr.Spec.NetworkOptions = &operatorv1beta2.NetworkConfigurationList{ - GrafanaConfig: &operatorv1beta2.NetworkConfiguration{ - Annotations: map[string]string{"grafana": "annotation"}, - Labels: map[string]string{ - "grafana": "label", - "component": "test-comp", - "app": "test-app", - }, - }, - } - return cr -} - func (r *TestResources) NewCryostatWithReportsResources() *model.CryostatInstance { cr := r.NewCryostat() cr.Spec.ReportOptions = &operatorv1beta2.ReportConfiguration{ @@ -839,21 +802,6 @@ func (r *TestResources) NewCustomizedCoreService() *corev1.Service { return svc } -func (r *TestResources) NewCustomizedGrafanaService() *corev1.Service { - svc := r.NewGrafanaService() - svc.Spec.Type = corev1.ServiceTypeNodePort - svc.Spec.Ports[0].Port = 8080 - svc.Annotations = map[string]string{ - "my/custom": "annotation", - } - svc.Labels = map[string]string{ - "app": r.Name, - "component": "cryostat", - "my": "label", - } - return svc -} - func (r *TestResources) NewCustomizedReportsService() *corev1.Service { svc := r.NewReportsService() svc.Spec.Type = corev1.ServiceTypeNodePort @@ -2168,21 +2116,6 @@ func (r *TestResources) NewCustomCoreRoute() *routev1.Route { return route } -func (r *TestResources) NewGrafanaRoute() *routev1.Route { - return r.newRoute(r.Name+"-grafana", 3000) -} - -func (r *TestResources) NewCustomGrafanaRoute() *routev1.Route { - route := r.NewGrafanaRoute() - route.Annotations = map[string]string{"grafana": "annotation"} - route.Labels = map[string]string{ - "grafana": "label", - "app": r.Name, - "component": "cryostat", - } - return route -} - func (r *TestResources) newRoute(name string, port int) *routev1.Route { var routeTLS *routev1.TLSConfig if !r.TLS { @@ -2244,36 +2177,11 @@ func (r *TestResources) OtherCoreRoute() *routev1.Route { } } -func (r *TestResources) OtherGrafanaRoute() *routev1.Route { - return &routev1.Route{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-grafana", - Namespace: r.Namespace, - Annotations: map[string]string{"grafana": "annotation"}, - Labels: map[string]string{"grafana": "label"}, - }, - Spec: routev1.RouteSpec{ - To: routev1.RouteTargetReference{ - Kind: "Service", - Name: "not-grafana", - }, - Port: &routev1.RoutePort{ - TargetPort: intstr.FromInt(5678), - }, - }, - } -} - func (r *TestResources) NewCoreIngress() *netv1.Ingress { return r.newIngress(r.Name, 4180, map[string]string{"custom": "annotation"}, map[string]string{"my": "label", "custom": "label"}) } -func (r *TestResources) NewGrafanaIngress() *netv1.Ingress { - return r.newIngress(r.Name+"-grafana", 3000, map[string]string{"grafana": "annotation"}, - map[string]string{"my": "label", "grafana": "label"}) -} - func (r *TestResources) newIngress(name string, svcPort int32, annotations, labels map[string]string) *netv1.Ingress { pathtype := netv1.PathTypePrefix @@ -2358,57 +2266,14 @@ func (r *TestResources) OtherCoreIngress() *netv1.Ingress { } } -func (r *TestResources) OtherGrafanaIngress() *netv1.Ingress { - pathtype := netv1.PathTypePrefix - return &netv1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-grafana", - Namespace: r.Namespace, - Annotations: map[string]string{"other-grafana": "annotation"}, - Labels: map[string]string{"other-grafana": "label", "app": "not-grafana"}, - }, - Spec: netv1.IngressSpec{ - Rules: []netv1.IngressRule{ - { - Host: "some-other-grafana.example.com", - IngressRuleValue: netv1.IngressRuleValue{ - HTTP: &netv1.HTTPIngressRuleValue{ - Paths: []netv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathtype, - Backend: netv1.IngressBackend{ - Service: &netv1.IngressServiceBackend{ - Name: "some-other-grafana", - Port: netv1.ServiceBackendPort{ - Number: 5000, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } -} - func (r *TestResources) newNetworkConfigurationList() operatorv1beta2.NetworkConfigurationList { coreSVC := r.NewCryostatService() coreIng := r.newNetworkConfiguration(coreSVC.Name, coreSVC.Spec.Ports[0].Port) coreIng.Annotations["custom"] = "annotation" coreIng.Labels["custom"] = "label" - grafanaSVC := r.NewGrafanaService() - grafanaIng := r.newNetworkConfiguration(grafanaSVC.Name, grafanaSVC.Spec.Ports[0].Port) - grafanaIng.Annotations["grafana"] = "annotation" - grafanaIng.Labels["grafana"] = "label" - return operatorv1beta2.NetworkConfigurationList{ - CoreConfig: &coreIng, - GrafanaConfig: &grafanaIng, + CoreConfig: &coreIng, } } diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index 71b7803b0..f8af81f1e 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -325,37 +325,6 @@ func configureIngress(name string, cryostatSpec *operatorv1beta2.CryostatSpec) { }, }, }, - GrafanaConfig: &operatorv1beta2.NetworkConfiguration{ - Annotations: map[string]string{ - "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", - }, - IngressSpec: &netv1.IngressSpec{ - TLS: []netv1.IngressTLS{{}}, - Rules: []netv1.IngressRule{ - { - Host: "testing.cryostat-grafana", - IngressRuleValue: netv1.IngressRuleValue{ - HTTP: &netv1.HTTPIngressRuleValue{ - Paths: []netv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathType, - Backend: netv1.IngressBackend{ - Service: &netv1.IngressServiceBackend{ - Name: fmt.Sprintf("%s-grafana", name), - Port: netv1.ServiceBackendPort{ - Number: 3000, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, } } From dc5df9bf2950c8f2679f54d2b28fa8e3163ccf20 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Wed, 8 May 2024 16:15:02 -0400 Subject: [PATCH 35/53] feat(tls): enable TLS on authproxies (#813) --- ...yostat-operator.clusterserviceversion.yaml | 2 +- internal/controllers/certmanager.go | 8 - .../resource_definitions/certificates.go | 26 -- .../resource_definitions.go | 237 +++++++----------- internal/controllers/configmaps.go | 32 ++- internal/controllers/const_generated.go | 2 +- internal/controllers/constants/constants.go | 2 - internal/controllers/reconciler.go | 10 +- internal/controllers/reconciler_test.go | 2 +- internal/controllers/routes.go | 5 +- internal/test/clients.go | 2 +- internal/test/resources.go | 114 ++------- 12 files changed, 141 insertions(+), 301 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 7a74e296d..ab22fedc9 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-08T15:33:40Z" + createdAt: "2024-05-08T18:54:35Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/internal/controllers/certmanager.go b/internal/controllers/certmanager.go index 294a47eea..a355dcf92 100644 --- a/internal/controllers/certmanager.go +++ b/internal/controllers/certmanager.go @@ -93,14 +93,6 @@ func (r *Reconciler) setupTLS(ctx context.Context, cr *model.CryostatInstance) ( KeystorePassSecret: cryostatCert.Spec.Keystores.PKCS12.PasswordSecretRef.Name, } certificates := []*certv1.Certificate{caCert, cryostatCert, reportsCert} - // Create a certificate for Grafana signed by the Cryostat CA - grafanaCert := resources.NewGrafanaCert(cr) - err = r.createOrUpdateCertificate(ctx, grafanaCert, cr.Object) - if err != nil { - return nil, err - } - certificates = append(certificates, grafanaCert) - tlsConfig.GrafanaSecret = grafanaCert.Spec.SecretName // Update owner references of TLS secrets created by cert-manager to ensure proper cleanup err = r.setCertSecretOwner(ctx, cr.Object, certificates...) diff --git a/internal/controllers/common/resource_definitions/certificates.go b/internal/controllers/common/resource_definitions/certificates.go index 33b8ae183..9ba46b5f6 100644 --- a/internal/controllers/common/resource_definitions/certificates.go +++ b/internal/controllers/common/resource_definitions/certificates.go @@ -20,7 +20,6 @@ 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" @@ -109,31 +108,6 @@ func NewCryostatCert(cr *model.CryostatInstance, keystoreSecretName string) *cer } } -func NewGrafanaCert(cr *model.CryostatInstance) *certv1.Certificate { - return &certv1.Certificate{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + "-grafana", - Namespace: cr.InstallNamespace, - }, - Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf("%s-grafana.%s.svc", cr.Name, cr.InstallNamespace), - DNSNames: []string{ - cr.Name + "-grafana", - fmt.Sprintf("%s-grafana.%s.svc", cr.Name, cr.InstallNamespace), - fmt.Sprintf("%s-grafana.%s.svc.cluster.local", cr.Name, cr.InstallNamespace), - constants.HealthCheckHostname, - }, - SecretName: cr.Name + "-grafana-tls", - IssuerRef: certMeta.ObjectReference{ - Name: cr.Name + "-ca", - }, - Usages: append(certv1.DefaultKeyUsages(), - certv1.UsageServerAuth, - ), - }, - } -} - func NewReportsCert(cr *model.CryostatInstance) *certv1.Certificate { return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 843b0c807..2a01cf753 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -59,8 +59,6 @@ type ServiceSpecs struct { type TLSConfig struct { // Name of the TLS secret for Cryostat CryostatSecret string - // Name of the TLS secret for Grafana - GrafanaSecret string // Name of the TLS secret for Reports Generator ReportsSecret string // Name of the secret containing the password for the keystore in CryostatSecret @@ -317,6 +315,14 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima }) volumes = append(volumes, + corev1.Volume{ + Name: "auth-proxy-tls-secret", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: tls.CryostatSecret, + }, + }, + }, corev1.Volume{ Name: "keystore", VolumeSource: corev1.VolumeSource{ @@ -332,14 +338,6 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima }, }, }, - corev1.Volume{ - Name: "grafana-tls-secret", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: tls.GrafanaSecret, - }, - }, - }, ) } @@ -423,16 +421,6 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima } } - // Use HostAlias for loopback address to allow health checks to - // work over HTTPS with hostname added as a SubjectAltName - hostAliases := []corev1.HostAlias{ - { - IP: constants.LoopbackAddress, - Hostnames: []string{ - constants.HealthCheckHostname, - }, - }, - } var nodeSelector map[string]string var affinity *corev1.Affinity var tolerations []corev1.Toleration @@ -456,7 +444,6 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima Volumes: volumes, Containers: containers, SecurityContext: podSc, - HostAliases: hostAliases, AutomountServiceAccountToken: &automountSAToken, NodeSelector: nodeSelector, Affinity: affinity, @@ -659,21 +646,12 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp } } - probeHandler := corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Port: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, - Path: "/oauth2/healthz", - Scheme: corev1.URISchemeHTTP, - }, - } - args := []string{ fmt.Sprintf("--upstream=http://localhost:%d/", constants.CryostatHTTPContainerPort), fmt.Sprintf("--upstream=http://localhost:%d/grafana/", constants.GrafanaContainerPort), fmt.Sprintf("--upstream=http://localhost:%d/storage/", constants.StoragePort), fmt.Sprintf("--openshift-service-account=%s", cr.Name), "--proxy-websockets=true", - fmt.Sprintf("--http-address=0.0.0.0:%d", constants.AuthProxyHttpContainerPort), "--proxy-prefix=/oauth2", } if isOpenShiftAuthProxyDisabled(cr) { @@ -697,6 +675,7 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp args = append(args, fmt.Sprintf("--openshift-delegate-urls=%s", string(tokenReviewJson))) volumeMounts := []corev1.VolumeMount{} + if isBasicAuthEnabled(cr) { mountPath := "/var/run/secrets/operator.cryostat.io" volumeMounts = append(volumeMounts, corev1.VolumeMount{ @@ -706,31 +685,34 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp }) args = append(args, fmt.Sprintf("--htpasswd-file=%s/%s", mountPath, *cr.Spec.AuthorizationOptions.BasicAuth.Filename)) } - args = append(args, fmt.Sprintf("--skip-provider-button=%t", !isBasicAuthEnabled(cr)), ) - // if tls != nil { - // "--https-address=:8443", - // "--tls-cert=/etc/tls/private/tls.crt", - // "--tls-key=/etc/tls/private/tls.key", - // } else { - args = append(args, "--https-address=") - // } + livenessProbeScheme := corev1.URISchemeHTTP + if tls != nil { + args = append(args, + fmt.Sprintf("--http-address="), + fmt.Sprintf("--https-address=0.0.0.0:%d", constants.AuthProxyHttpContainerPort), + fmt.Sprintf("--tls-cert=/var/run/secrets/operator.cryostat.io/%s/%s", tls.CryostatSecret, corev1.TLSCertKey), + fmt.Sprintf("--tls-key=/var/run/secrets/operator.cryostat.io/%s/%s", tls.CryostatSecret, corev1.TLSPrivateKeyKey), + ) - cookieOptional := false - envsFrom := []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Name + "-oauth2-cookie", - }, - Optional: &cookieOptional, - }, - }, + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: "auth-proxy-tls-secret", + MountPath: "/var/run/secrets/operator.cryostat.io/" + tls.CryostatSecret, + ReadOnly: true, + }) + + livenessProbeScheme = corev1.URISchemeHTTPS + } else { + args = append(args, + fmt.Sprintf("--http-address=0.0.0.0:%d", constants.AuthProxyHttpContainerPort), + "--https-address=", + ) } + cookieOptional := false return &corev1.Container{ Name: cr.Name + "-auth-proxy", Image: imageTag, @@ -741,11 +723,25 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp ContainerPort: constants.AuthProxyHttpContainerPort, }, }, - // Env: envs, - EnvFrom: envsFrom, + EnvFrom: []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Name + "-oauth2-cookie", + }, + Optional: &cookieOptional, + }, + }, + }, Resources: *NewAuthProxyContainerResource(cr), LivenessProbe: &corev1.Probe{ - ProbeHandler: probeHandler, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, + Path: "/oauth2/healthz", + Scheme: livenessProbeScheme, + }, + }, }, SecurityContext: containerSc, Args: args, @@ -793,18 +789,6 @@ func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, im } } - probeHandler := corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Port: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, - Path: "/ping", - Scheme: corev1.URISchemeHTTP, - }, - } - - args := []string{ - fmt.Sprintf("--alpha-config=%s/%s", OAuth2ConfigFilePath, OAuth2ConfigFileName), - } - envs := []corev1.EnvVar{ { Name: "OAUTH2_PROXY_REDIRECT_URL", @@ -816,18 +800,6 @@ func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, im }, } - cookieOptional := false - envsFrom := []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Name + "-oauth2-cookie", - }, - Optional: &cookieOptional, - }, - }, - } - volumeMounts := []corev1.VolumeMount{ { Name: cr.Name + "-oauth2-proxy-cfg", @@ -836,6 +808,17 @@ func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, im }, } + livenessProbeScheme := corev1.URISchemeHTTP + if tls != nil { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: "auth-proxy-tls-secret", + MountPath: "/var/run/secrets/operator.cryostat.io/" + tls.CryostatSecret, + ReadOnly: true, + }) + + livenessProbeScheme = corev1.URISchemeHTTPS + } + if isBasicAuthEnabled(cr) { mountPath := "/var/run/secrets/operator.cryostat.io" volumeMounts = append(volumeMounts, corev1.VolumeMount{ @@ -864,6 +847,7 @@ func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, im }) } + cookieOptional := false return &corev1.Container{ Name: cr.Name + "-auth-proxy", Image: imageTag, @@ -874,14 +858,31 @@ func NewOAuth2ProxyContainer(cr *model.CryostatInstance, specs *ServiceSpecs, im ContainerPort: constants.AuthProxyHttpContainerPort, }, }, - Env: envs, - EnvFrom: envsFrom, + Env: envs, + EnvFrom: []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Name + "-oauth2-cookie", + }, + Optional: &cookieOptional, + }, + }, + }, Resources: *NewAuthProxyContainerResource(cr), LivenessProbe: &corev1.Probe{ - ProbeHandler: probeHandler, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, + Path: "/ping", + Scheme: livenessProbeScheme, + }, + }, }, SecurityContext: containerSc, - Args: args, + Args: []string{ + fmt.Sprintf("--alpha-config=%s/%s", OAuth2ConfigFilePath, OAuth2ConfigFileName), + }, }, nil } @@ -1145,36 +1146,12 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag }, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_URL", - Value: getInternalDashboardURL(tls), + Value: getInternalDashboardURL(), }, ) } envs = append(envs, grafanaVars...) - if tls != nil { - // Configure keystore location and password in expected environment variables - envs = append(envs, corev1.EnvVar{ - Name: "KEYSTORE_PATH", - Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/keystore.p12", tls.CryostatSecret), - }) - envsFrom = append(envsFrom, corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: tls.KeystorePassSecret, - }, - }, - }) - - // Mount the TLS secret's keystore - keystoreMount := corev1.VolumeMount{ - Name: "keystore", - MountPath: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s", tls.CryostatSecret), - ReadOnly: true, - } - - mounts = append(mounts, keystoreMount) - } - // Mount the templates specified in Cryostat CR under /opt/cryostat.d/templates.d for _, template := range cr.Spec.EventTemplates { mount := corev1.VolumeMount{ @@ -1262,47 +1239,10 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo Name: "JFR_DATASOURCE_URL", Value: datasourceURL, }, - } - mounts := []corev1.VolumeMount{} - - // Configure TLS key/cert if enabled - livenessProbeScheme := corev1.URISchemeHTTP - if tls != nil { - tlsEnvs := []corev1.EnvVar{ - { - Name: "GF_SERVER_PROTOCOL", - Value: "https", - }, - { - Name: "GF_SERVER_ROOT_URL", - Value: fmt.Sprintf("%s://localhost:%d/grafana/", "https", constants.AuthProxyHttpContainerPort), - }, - { - Name: "GF_SERVER_CERT_KEY", - Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/%s", tls.GrafanaSecret, corev1.TLSPrivateKeyKey), - }, - { - Name: "GF_SERVER_CERT_FILE", - Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/%s", tls.GrafanaSecret, corev1.TLSCertKey), - }, - } - - tlsSecretMount := corev1.VolumeMount{ - Name: "grafana-tls-secret", - MountPath: "/var/run/secrets/operator.cryostat.io/" + tls.GrafanaSecret, - ReadOnly: true, - } - - envs = append(envs, tlsEnvs...) - mounts = append(mounts, tlsSecretMount) - - // Use HTTPS for liveness probe - livenessProbeScheme = corev1.URISchemeHTTPS - } else { - envs = append(envs, corev1.EnvVar{ + { Name: "GF_SERVER_ROOT_URL", Value: fmt.Sprintf("%s://localhost:%d/grafana/", "http", constants.AuthProxyHttpContainerPort), - }) + }, } var containerSc *corev1.SecurityContext @@ -1322,7 +1262,6 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo Name: cr.Name + "-grafana", Image: imageTag, ImagePullPolicy: getPullPolicy(imageTag), - VolumeMounts: mounts, Ports: []corev1.ContainerPort{ { ContainerPort: constants.GrafanaContainerPort, @@ -1334,7 +1273,7 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo HTTPGet: &corev1.HTTPGetAction{ Port: intstr.IntOrString{IntVal: 3000}, Path: "/api/health", - Scheme: livenessProbeScheme, + Scheme: corev1.URISchemeHTTP, }, }, }, @@ -1605,12 +1544,8 @@ func getPort(url *url.URL) string { return "80" } -func getInternalDashboardURL(tls *TLSConfig) string { - scheme := "https" - if tls == nil { - scheme = "http" - } - return fmt.Sprintf("%s://%s:%d", scheme, constants.HealthCheckHostname, constants.GrafanaContainerPort) +func getInternalDashboardURL() string { + return fmt.Sprintf("http://localhost:%d", constants.GrafanaContainerPort) } // Matches image tags of the form "major.minor.patch" diff --git a/internal/controllers/configmaps.go b/internal/controllers/configmaps.go index 0f3380fba..adff11875 100644 --- a/internal/controllers/configmaps.go +++ b/internal/controllers/configmaps.go @@ -45,7 +45,18 @@ type oauth2ProxyAlphaConfig struct { } type alphaConfigServer struct { - BindAddress string `json:"BindAddress,omitempty"` + BindAddress string `json:"BindAddress,omitempty"` + SecureBindAddress string `json:"SecureBindAddress,omitempty"` + TLS proxyTLS `json:"TLS,omitempty"` +} + +type proxyTLS struct { + Key tlsSecretSource `json:"Key,omitempty"` + Cert tlsSecretSource `json:"Cert,omitempty"` +} + +type tlsSecretSource struct { + FromFile string `json:"fromFile,omitempty"` } type alphaConfigUpstreamConfig struct { @@ -70,10 +81,11 @@ type alphaConfigUpstream struct { ProxyWebSockets bool `json:"proxyWebSockets,omitempty"` } -func (r *Reconciler) reconcileOAuth2ProxyConfig(ctx context.Context, cr *model.CryostatInstance) error { +func (r *Reconciler) reconcileOAuth2ProxyConfig(ctx context.Context, cr *model.CryostatInstance, tls *resources.TLSConfig) error { + bindHost := "0.0.0.0" immutable := true cfg := &oauth2ProxyAlphaConfig{ - Server: alphaConfigServer{BindAddress: fmt.Sprintf("http://0.0.0.0:%d", constants.AuthProxyHttpContainerPort)}, + Server: alphaConfigServer{}, UpstreamConfig: alphaConfigUpstreamConfig{ProxyRawPath: true, Upstreams: []alphaConfigUpstream{ { Id: "cryostat", @@ -97,6 +109,20 @@ func (r *Reconciler) reconcileOAuth2ProxyConfig(ctx context.Context, cr *model.C Providers: []alphaConfigProvider{{Id: "dummy", Name: "Unused - Sign In Below", ClientId: "CLIENT_ID", ClientSecret: "CLIENT_SECRET", Provider: "google"}}, } + if tls != nil { + cfg.Server.SecureBindAddress = fmt.Sprintf("https://%s:%d", bindHost, constants.AuthProxyHttpContainerPort) + cfg.Server.TLS = proxyTLS{ + Key: tlsSecretSource{ + FromFile: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/%s", tls.CryostatSecret, corev1.TLSPrivateKeyKey), + }, + Cert: tlsSecretSource{ + FromFile: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/%s", tls.CryostatSecret, corev1.TLSCertKey), + }, + } + } else { + cfg.Server.BindAddress = fmt.Sprintf("http://%s:%d", bindHost, constants.AuthProxyHttpContainerPort) + } + data := make(map[string]string) json, err := json.Marshal(cfg) if err != nil { diff --git a/internal/controllers/const_generated.go b/internal/controllers/const_generated.go index 41ae4e3e4..4009d3343 100644 --- a/internal/controllers/const_generated.go +++ b/internal/controllers/const_generated.go @@ -11,7 +11,7 @@ const OperatorVersion = "3.0.0-dev" const DefaultOAuth2ProxyImageTag = "quay.io/oauth2-proxy/oauth2-proxy:latest" // Default image tag for the OpenShift OAuth Proxy -const DefaultOpenShiftOAuthProxyImageTag = "quay.io/openshift/origin-oauth-proxy:latest" +const DefaultOpenShiftOAuthProxyImageTag = "quay.io/andrewazores/openshift-oauth-proxy:test-14" // Default image tag for the core application image const DefaultCoreImageTag = "quay.io/cryostat/cryostat:3.0.0-snapshot" diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index 18f1a71f2..f609d40b8 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -34,8 +34,6 @@ const ( HttpPortName string = "http" // CAKey is the key for a CA certificate within a TLS secret CAKey = certMeta.TLSCAKey - // Hostname alias for loopback address, to be used for health checks - HealthCheckHostname = "cryostat-health.local" // ALL capability to drop for restricted pod security. See: // https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted CapabilityAll corev1.Capability = "ALL" diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index 6460bb173..d83eb368d 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -194,11 +194,6 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn return reconcile.Result{}, err } - err = r.reconcileOAuth2ProxyConfig(ctx, cr) - if err != nil { - return reconcile.Result{}, err - } - err = r.reconcilePVC(ctx, cr) if err != nil { return reconcile.Result{}, err @@ -250,6 +245,11 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn } } + err = r.reconcileOAuth2ProxyConfig(ctx, cr, tlsConfig) + if err != nil { + return reconcile.Result{}, err + } + serviceSpecs := &resources.ServiceSpecs{ InsightsURL: r.InsightsProxy, } diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 50ce08206..bd1bbd99b 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -2198,7 +2198,7 @@ func (t *cryostatTestInput) expectWaitingForCertificate() { func (t *cryostatTestInput) expectCertificates() { // Check certificates - certs := []*certv1.Certificate{t.NewCryostatCert(), t.NewCACert(), t.NewReportsCert(), t.NewGrafanaCert()} + certs := []*certv1.Certificate{t.NewCryostatCert(), t.NewCACert(), t.NewReportsCert()} for _, expected := range certs { actual := &certv1.Certificate{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: expected.Name, Namespace: expected.Namespace}, actual) diff --git a/internal/controllers/routes.go b/internal/controllers/routes.go index a26640ed4..5c7e38bb9 100644 --- a/internal/controllers/routes.go +++ b/internal/controllers/routes.go @@ -90,8 +90,9 @@ func (r *Reconciler) createOrUpdateRoute(ctx context.Context, route *routev1.Rou } } else { routeTLS = &routev1.TLSConfig{ - Termination: routev1.TLSTerminationReencrypt, - DestinationCACertificate: string(tlsConfig.CACert), + Termination: routev1.TLSTerminationReencrypt, + DestinationCACertificate: string(tlsConfig.CACert), + InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect, } } diff --git a/internal/test/clients.go b/internal/test/clients.go index 56152542e..4a46133ea 100644 --- a/internal/test/clients.go +++ b/internal/test/clients.go @@ -70,7 +70,7 @@ func (c *testClient) makeCertificatesReady(ctx context.Context, obj runtime.Obje // If this object is one of the operator-managed certificates, mock the behaviour // of cert-manager processing those certificates cert, ok := obj.(*certv1.Certificate) - if ok && c.matchesName(cert, c.NewCryostatCert(), c.NewCACert(), c.NewGrafanaCert(), c.NewReportsCert()) && + if ok && c.matchesName(cert, c.NewCryostatCert(), c.NewCACert(), c.NewReportsCert()) && len(cert.Status.Conditions) == 0 { // Create certificate secret c.createCertSecret(ctx, cert) diff --git a/internal/test/resources.go b/internal/test/resources.go index 0eadf690e..e1bb9d100 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -974,33 +974,6 @@ func (r *TestResources) NewCryostatCert() *certv1.Certificate { } } -func (r *TestResources) NewGrafanaCert() *certv1.Certificate { - return &certv1.Certificate{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-grafana", - Namespace: r.Namespace, - }, - Spec: certv1.CertificateSpec{ - CommonName: fmt.Sprintf(r.Name+"-grafana.%s.svc", r.Namespace), - DNSNames: []string{ - r.Name + "-grafana", - fmt.Sprintf(r.Name+"-grafana.%s.svc", r.Namespace), - fmt.Sprintf(r.Name+"-grafana.%s.svc.cluster.local", r.Namespace), - "cryostat-health.local", - }, - SecretName: r.Name + "-grafana-tls", - IssuerRef: certMeta.ObjectReference{ - Name: r.Name + "-ca", - }, - Usages: []certv1.KeyUsage{ - certv1.UsageDigitalSignature, - certv1.UsageKeyEncipherment, - certv1.UsageServerAuth, - }, - }, - } -} - func (r *TestResources) NewReportsCert() *certv1.Certificate { return &certv1.Certificate{ ObjectMeta: metav1.ObjectMeta{ @@ -1348,13 +1321,6 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, ingress b }, ) - if r.TLS { - envs = append(envs, corev1.EnvVar{ - Name: "KEYSTORE_PATH", - Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-tls/keystore.p12", r.Name), - }) - } - if r.OpenShift || ingress { envs = append(envs, r.newNetworkEnvironmentVariables()...) } @@ -1378,7 +1344,12 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, ingress b } func (r *TestResources) newNetworkEnvironmentVariables() []corev1.EnvVar { - envs := []corev1.EnvVar{} + envs := []corev1.EnvVar{ + { + Name: "GRAFANA_DASHBOARD_URL", + Value: "http://localhost:3000", + }, + } if r.ExternalTLS { envs = append(envs, corev1.EnvVar{ @@ -1392,19 +1363,6 @@ func (r *TestResources) newNetworkEnvironmentVariables() []corev1.EnvVar { Value: fmt.Sprintf("http://%s.example.com/grafana/", r.Name), }) } - if r.TLS { - envs = append(envs, - corev1.EnvVar{ - Name: "GRAFANA_DASHBOARD_URL", - Value: "https://cryostat-health.local:3000", - }) - } else { - envs = append(envs, - corev1.EnvVar{ - Name: "GRAFANA_DASHBOARD_URL", - Value: "http://cryostat-health.local:3000", - }) - } return envs } @@ -1429,26 +1387,10 @@ func (r *TestResources) NewGrafanaEnvironmentVariables() []corev1.EnvVar { Value: "true", ValueFrom: nil, }, - } - if r.TLS { - envs = append(envs, corev1.EnvVar{ - Name: "GF_SERVER_PROTOCOL", - Value: "https", - }, corev1.EnvVar{ - Name: "GF_SERVER_CERT_KEY", - Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-grafana-tls/tls.key", r.Name), - }, corev1.EnvVar{ - Name: "GF_SERVER_CERT_FILE", - Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-grafana-tls/tls.crt", r.Name), - }, corev1.EnvVar{ - Name: "GF_SERVER_ROOT_URL", - Value: "https://localhost:4180/grafana/", - }) - } else { - envs = append(envs, corev1.EnvVar{ + { Name: "GF_SERVER_ROOT_URL", Value: "http://localhost:4180/grafana/", - }) + }, } return envs } @@ -1530,15 +1472,6 @@ func (r *TestResources) NewCoreEnvFromSource() []corev1.EnvFromSource { }, }, } - if r.TLS { - envsFrom = append(envsFrom, corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: r.Name + "-keystore", - }, - }, - }) - } return envsFrom } @@ -1626,27 +1559,11 @@ func (r *TestResources) NewCoreVolumeMounts() []corev1.VolumeMount { MountPath: "/truststore/operator", }, } - if r.TLS { - mounts = append(mounts, - corev1.VolumeMount{ - Name: "keystore", - ReadOnly: true, - MountPath: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-tls", r.Name), - }) - } return mounts } func (r *TestResources) NewGrafanaVolumeMounts() []corev1.VolumeMount { mounts := []corev1.VolumeMount{} - if r.TLS { - mounts = append(mounts, - corev1.VolumeMount{ - Name: "grafana-tls-secret", - MountPath: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-grafana-tls", r.Name), - ReadOnly: true, - }) - } return mounts } @@ -1716,16 +1633,12 @@ func (r *TestResources) newCoreProbeHandler() corev1.ProbeHandler { } func (r *TestResources) NewGrafanaLivenessProbe() *corev1.Probe { - protocol := corev1.URISchemeHTTPS - if !r.TLS { - protocol = corev1.URISchemeHTTP - } return &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Port: intstr.IntOrString{IntVal: 3000}, Path: "/api/health", - Scheme: protocol, + Scheme: corev1.URISchemeHTTP, }, }, } @@ -1971,10 +1884,10 @@ func (r *TestResources) newVolumes(certProjections []corev1.VolumeProjection) [] }, }, corev1.Volume{ - Name: "grafana-tls-secret", + Name: "auth-proxy-tls-secret", VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - SecretName: r.Name + "-grafana-tls", + SecretName: r.Name + "-tls", }, }, }, @@ -2125,8 +2038,9 @@ func (r *TestResources) newRoute(name string, port int) *routev1.Route { } } else { routeTLS = &routev1.TLSConfig{ - Termination: routev1.TLSTerminationReencrypt, - DestinationCACertificate: r.Name + "-ca-bytes", + Termination: routev1.TLSTerminationReencrypt, + DestinationCACertificate: r.Name + "-ca-bytes", + InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect, } } return &routev1.Route{ From efec98e85769187f3b4cbcdfb59dc33631b3711d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 17:34:33 -0400 Subject: [PATCH 36/53] fix(reports): update deprecated quarkus properties (backport #818) (#819) * fix(reports): update deprecated quarkus properties (#818) (cherry picked from commit 0a426ad312bd1a247753e50abfe40cdfcdb7c28d) # Conflicts: # bundle/manifests/cryostat-operator.clusterserviceversion.yaml # config/scorecard/patches/custom.config.yaml * fixup! fix(reports): update deprecated quarkus properties (#818) * regenerate, update scorecard image * correct openshift-oauth-proxy image tag --------- Co-authored-by: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Co-authored-by: Andrew Azores --- .../cryostat-operator.clusterserviceversion.yaml | 2 +- config/scorecard/patches/custom.config.yaml | 12 ++++++------ .../resource_definitions/resource_definitions.go | 4 ++-- internal/controllers/const_generated.go | 2 +- internal/test/resources.go | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index ab22fedc9..abbe21a29 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-08T18:54:35Z" + createdAt: "2024-05-10T19:40:13Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 39c8ea87f..30b927074 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:3.0.0-20240416210645" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" labels: suite: cryostat test: cryostat-multi-namespace @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" labels: suite: cryostat test: cryostat-recording @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" labels: suite: cryostat test: cryostat-config-change @@ -58,7 +58,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" labels: suite: cryostat test: cryostat-report diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 2a01cf753..38f7f8d6e 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -492,11 +492,11 @@ func NewPodForReports(cr *model.CryostatInstance, imageTags *ImageTags, tls *TLS Value: strconv.Itoa(int(constants.ReportsContainerPort)), }, { - Name: "QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILE", + Name: "QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILES", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/%s", tls.ReportsSecret, corev1.TLSPrivateKeyKey), }, { - Name: "QUARKUS_HTTP_SSL_CERTIFICATE_FILE", + Name: "QUARKUS_HTTP_SSL_CERTIFICATE_FILES", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/%s", tls.ReportsSecret, corev1.TLSCertKey), }, { diff --git a/internal/controllers/const_generated.go b/internal/controllers/const_generated.go index 4009d3343..41ae4e3e4 100644 --- a/internal/controllers/const_generated.go +++ b/internal/controllers/const_generated.go @@ -11,7 +11,7 @@ const OperatorVersion = "3.0.0-dev" const DefaultOAuth2ProxyImageTag = "quay.io/oauth2-proxy/oauth2-proxy:latest" // Default image tag for the OpenShift OAuth Proxy -const DefaultOpenShiftOAuthProxyImageTag = "quay.io/andrewazores/openshift-oauth-proxy:test-14" +const DefaultOpenShiftOAuthProxyImageTag = "quay.io/openshift/origin-oauth-proxy:latest" // Default image tag for the core application image const DefaultCoreImageTag = "quay.io/cryostat/cryostat:3.0.0-snapshot" diff --git a/internal/test/resources.go b/internal/test/resources.go index e1bb9d100..497d61de2 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1431,10 +1431,10 @@ func (r *TestResources) NewReportsEnvironmentVariables(resources *corev1.Resourc Name: "QUARKUS_HTTP_SSL_PORT", Value: "10000", }, corev1.EnvVar{ - Name: "QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILE", + Name: "QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILES", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-reports-tls/tls.key", r.Name), }, corev1.EnvVar{ - Name: "QUARKUS_HTTP_SSL_CERTIFICATE_FILE", + Name: "QUARKUS_HTTP_SSL_CERTIFICATE_FILES", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-reports-tls/tls.crt", r.Name), }, corev1.EnvVar{ Name: "QUARKUS_HTTP_INSECURE_REQUESTS", From 95fa911886edf63b1bb758636eee52ad497dc203 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Mon, 13 May 2024 06:47:25 -0700 Subject: [PATCH 37/53] test(scorecard): fix broken scorecard tests for 3.0 (#820) --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 12 +-- config/scorecard/patches/custom.config.yaml | 12 +-- internal/test/scorecard/clients.go | 86 +++++++++++-------- internal/test/scorecard/common_utils.go | 8 +- internal/test/scorecard/openshift.go | 2 +- internal/test/scorecard/tests.go | 21 +++-- internal/test/scorecard/types.go | 30 ++++--- 8 files changed, 95 insertions(+), 78 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index abbe21a29..0d794ced6 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-10T19:40:13Z" + createdAt: "2024-05-11T06:47:54Z" 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 30459721b..e88495e59 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:3.0.0-20240416210645 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240416210645 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726 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:3.0.0-20240416210645 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726 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:3.0.0-20240416210645 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726 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:3.0.0-20240416210645 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726 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:3.0.0-20240416210645 + image: quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726 labels: suite: cryostat test: cryostat-report diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index 30b927074..bada4b26b 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:3.0.0-20240510194331" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726" labels: suite: cryostat test: cryostat-multi-namespace @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726" labels: suite: cryostat test: cryostat-recording @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726" labels: suite: cryostat test: cryostat-config-change @@ -58,7 +58,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240510194331" + image: "quay.io/cryostat/cryostat-operator-scorecard:3.0.0-20240511064726" labels: suite: cryostat test: cryostat-report diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 05965499f..b655b2c72 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -16,7 +16,6 @@ package scorecard import ( "context" - "encoding/base64" "encoding/json" "errors" "fmt" @@ -276,8 +275,8 @@ type RecordingClient struct { *commonCryostatRESTClient } -func (client *RecordingClient) List(ctx context.Context, connectUrl string) ([]Recording, error) { - url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings", url.PathEscape(connectUrl))) +func (client *RecordingClient) List(ctx context.Context, target *Target) ([]Recording, error) { + url := client.Base.JoinPath(fmt.Sprintf("/api/v3/targets/%d/recordings", target.Id)) header := make(http.Header) header.Add("Accept", "*/*") @@ -300,8 +299,8 @@ func (client *RecordingClient) List(ctx context.Context, connectUrl string) ([]R return recordings, nil } -func (client *RecordingClient) Get(ctx context.Context, connectUrl string, recordingName string) (*Recording, error) { - recordings, err := client.List(ctx, connectUrl) +func (client *RecordingClient) Get(ctx context.Context, target *Target, recordingName string) (*Recording, error) { + recordings, err := client.List(ctx, target) if err != nil { return nil, err } @@ -312,11 +311,11 @@ func (client *RecordingClient) Get(ctx context.Context, connectUrl string, recor } } - return nil, fmt.Errorf("recording %s does not exist for target %s", recordingName, connectUrl) + return nil, fmt.Errorf("recording %s does not exist for target %s", recordingName, target.ConnectUrl) } -func (client *RecordingClient) Create(ctx context.Context, connectUrl string, options *RecordingCreateOptions) (*Recording, error) { - url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings", url.PathEscape(connectUrl))) +func (client *RecordingClient) Create(ctx context.Context, target *Target, options *RecordingCreateOptions) (*Recording, error) { + url := client.Base.JoinPath(fmt.Sprintf("/api/v3/targets/%d/recordings", target.Id)) body := options.ToFormData() header := make(http.Header) header.Add("Content-Type", "application/x-www-form-urlencoded") @@ -341,8 +340,8 @@ func (client *RecordingClient) Create(ctx context.Context, connectUrl string, op return recording, err } -func (client *RecordingClient) Archive(ctx context.Context, connectUrl string, recordingName string) (string, error) { - url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings/%s", url.PathEscape(connectUrl), url.PathEscape(recordingName))) +func (client *RecordingClient) Archive(ctx context.Context, target *Target, recordingId uint32) (string, error) { + url := client.Base.JoinPath(fmt.Sprintf("/api/v3/targets/%d/recordings/%d", target.Id, recordingId)) body := "SAVE" header := make(http.Header) header.Add("Content-Type", "text/plain") @@ -366,8 +365,8 @@ func (client *RecordingClient) Archive(ctx context.Context, connectUrl string, r return bodyAsString, nil } -func (client *RecordingClient) Stop(ctx context.Context, connectUrl string, recordingName string) error { - url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings/%s", url.PathEscape(connectUrl), url.PathEscape(recordingName))) +func (client *RecordingClient) Stop(ctx context.Context, target *Target, recordingId uint32) error { + url := client.Base.JoinPath(fmt.Sprintf("/api/v3/targets/%d/recordings/%d", target.Id, recordingId)) body := "STOP" header := make(http.Header) header.Add("Content-Type", "text/plain") @@ -386,8 +385,8 @@ func (client *RecordingClient) Stop(ctx context.Context, connectUrl string, reco return nil } -func (client *RecordingClient) Delete(ctx context.Context, connectUrl string, recordingName string) error { - url := client.Base.JoinPath(fmt.Sprintf("/api/v1/targets/%s/recordings/%s", url.PathEscape(connectUrl), url.PathEscape(recordingName))) +func (client *RecordingClient) Delete(ctx context.Context, target *Target, recordingId uint32) error { + url := client.Base.JoinPath(fmt.Sprintf("/api/v3/targets/%d/recordings/%d", target.Id, recordingId)) header := make(http.Header) resp, err := SendRequest(ctx, client.Client, http.MethodDelete, url.String(), nil, header) @@ -403,17 +402,17 @@ func (client *RecordingClient) Delete(ctx context.Context, connectUrl string, re return nil } -func (client *RecordingClient) GenerateReport(ctx context.Context, connectUrl string, recordingName *Recording) (map[string]interface{}, error) { - reportURL := recordingName.ReportURL - - if len(reportURL) < 1 { +func (client *RecordingClient) GenerateReport(ctx context.Context, target *Target, recording *Recording) (map[string]interface{}, error) { + if len(recording.ReportURL) < 1 { return nil, fmt.Errorf("report URL is not available") } + reportURL := client.Base.JoinPath(recording.ReportURL) + header := make(http.Header) header.Add("Accept", "application/json") - resp, err := SendRequest(ctx, client.Client, http.MethodGet, reportURL, nil, header) + resp, err := SendRequest(ctx, client.Client, http.MethodGet, reportURL.String(), nil, header) if err != nil { return nil, err } @@ -432,27 +431,34 @@ func (client *RecordingClient) GenerateReport(ctx context.Context, connectUrl st return report, nil } -func (client *RecordingClient) ListArchives(ctx context.Context, connectUrl string) ([]Archive, error) { +func (client *RecordingClient) ListArchives(ctx context.Context, target *Target) ([]Archive, error) { url := client.Base.JoinPath("/api/v2.2/graphql") query := &GraphQLQuery{ Query: ` - query ArchivedRecordingsForTarget($connectUrl: String) { - archivedRecordings(filter: { sourceTarget: $connectUrl }) { - data { - name - downloadUrl - reportUrl - metadata { - labels + query ArchivedRecordingsForTarget($id: BigInteger!) { + targetNodes(filter: { targetIds: [$id] }) { + target { + archivedRecordings { + data { + name + downloadUrl + reportUrl + metadata { + labels { + key + value + } + } + size + } } - size } } } `, - Variables: map[string]string{ - connectUrl: connectUrl, + Variables: map[string]any{ + "id": target.Id, }, } queryJSON, err := query.ToJSON() @@ -481,7 +487,7 @@ func (client *RecordingClient) ListArchives(ctx context.Context, connectUrl stri return nil, fmt.Errorf("failed to read response body: %s", err.Error()) } - return graphQLResponse.Data.ArchivedRecordings.Data, nil + return graphQLResponse.Data.TargetNodes[0].Target.ArchivedRecordings.Data, nil } type CredentialClient struct { @@ -515,7 +521,7 @@ func ReadJSON(resp *http.Response, result interface{}) error { err = json.Unmarshal(body, result) if err != nil { - return err + return fmt.Errorf("failed to unmarshal JSON: %s, response body: %s ", err.Error(), body) } return nil } @@ -565,15 +571,19 @@ func NewHttpRequest(ctx context.Context, method string, url string, body *string if err != nil { return nil, err } - if header != nil { - req.Header = header + + req.Header = header + if req.Header == nil { + req.Header = make(http.Header) } - // Authentication is only enabled on OCP. Ignored on k8s. + + // Authentication for OpenShift SSO config, err := rest.InClusterConfig() if err != nil { return nil, fmt.Errorf("failed to get in-cluster configurations: %s", err.Error()) } - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", base64.StdEncoding.EncodeToString([]byte(config.BearerToken)))) + + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", config.BearerToken)) return req, nil } @@ -583,7 +593,7 @@ func StatusOK(statusCode int) bool { func SendRequest(ctx context.Context, httpClient *http.Client, method string, url string, body *string, header http.Header) (*http.Response, error) { var response *http.Response - err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + err := wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (done bool, err error) { // Create a new request req, err := NewHttpRequest(ctx, method, url, body, header) if err != nil { diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index f8af81f1e..ae9c9254d 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -56,7 +56,7 @@ type TestResources struct { } func (r *TestResources) waitForDeploymentAvailability(ctx context.Context, name string, namespace string) error { - err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + err := wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (done bool, err error) { deploy, err := r.Client.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { if kerrors.IsNotFound(err) { @@ -344,7 +344,7 @@ func (r *TestResources) createAndWaitTillCryostatAvailable(cr *operatorv1beta2.C return nil, err } - err = wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + err = wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (done bool, err error) { cr, err = r.Client.OperatorCRDs().Cryostats(cr.Namespace).Get(ctx, cr.Name) if err != nil { return false, fmt.Errorf("failed to get Cryostat CR: %s", err.Error()) @@ -421,7 +421,7 @@ func (r *TestResources) sendHealthRequest(base *url.URL, healthCheck func(resp * ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err := wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + err := wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (done bool, err error) { url := base.JoinPath("/health") req, err := NewHttpRequest(ctx, http.MethodGet, url.String(), nil, make(http.Header)) if err != nil { @@ -483,7 +483,7 @@ func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta2.C // Poll the deployment until it becomes available or we timeout ctx, cancel := context.WithTimeout(context.Background(), testTimeout) defer cancel() - err = wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (done bool, err error) { + err = wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (done bool, err error) { deploy, err := r.Client.AppsV1().Deployments(cr.Namespace).Get(ctx, cr.Name, metav1.GetOptions{}) if err != nil { if kerrors.IsNotFound(err) { diff --git a/internal/test/scorecard/openshift.go b/internal/test/scorecard/openshift.go index 7880221ce..341f9ed6d 100644 --- a/internal/test/scorecard/openshift.go +++ b/internal/test/scorecard/openshift.go @@ -175,7 +175,7 @@ func (r *TestResources) installOpenShiftCertManager() error { // Check CSV status until we know cert-manager installed successfully ctx, cancel := context.WithTimeout(ctx, testTimeout) defer cancel() - return wait.PollImmediateUntilWithContext(ctx, time.Second, func(ctx context.Context) (bool, error) { + return wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (bool, error) { err := olmClient.Get().Resource("subscriptions").Namespace(sub.Namespace).Name(sub.Name).Do(ctx).Into(sub) if err != nil { return false, fmt.Errorf("failed to get Subscription: %s", err.Error()) diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 3ad6257cb..a06b6e7a1 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -185,7 +185,6 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh return r.fail(fmt.Sprintf("failed to create a target: %s", err.Error())) } r.Log += fmt.Sprintf("created a custom target: %+v\n", target) - connectUrl := target.ConnectUrl jmxSecretName := CryostatRecordingTestName + "-jmx-auth" secret, err := r.Client.CoreV1().Secrets(namespace).Get(context.Background(), jmxSecretName, metav1.GetOptions{}) @@ -217,48 +216,48 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh MaxSize: 0, MaxAge: 0, } - rec, err := apiClient.Recordings().Create(context.Background(), connectUrl, options) + rec, err := apiClient.Recordings().Create(context.Background(), target, options) if err != nil { return r.fail(fmt.Sprintf("failed to create a recording: %s", err.Error())) } r.Log += fmt.Sprintf("created a recording: %+v\n", rec) // View the current recording list after creating one - recs, err := apiClient.Recordings().List(context.Background(), connectUrl) + recs, err := apiClient.Recordings().List(context.Background(), target) if err != nil { return r.fail(fmt.Sprintf("failed to list recordings: %s", err.Error())) } r.Log += fmt.Sprintf("current list of recordings: %+v\n", recs) - // Allow the recording to run for 10s + // Allow the recording to run for 30s time.Sleep(30 * time.Second) // Archive the recording - archiveName, err := apiClient.Recordings().Archive(context.Background(), connectUrl, rec.Name) + archiveName, err := apiClient.Recordings().Archive(context.Background(), target, rec.Id) if err != nil { return r.fail(fmt.Sprintf("failed to archive the recording: %s", err.Error())) } r.Log += fmt.Sprintf("archived the recording %s at: %s\n", rec.Name, archiveName) - archives, err := apiClient.Recordings().ListArchives(context.Background(), connectUrl) + archives, err := apiClient.Recordings().ListArchives(context.Background(), target) if err != nil { return r.fail(fmt.Sprintf("failed to list archives: %s", err.Error())) } r.Log += fmt.Sprintf("current list of archives: %+v\n", archives) - report, err := apiClient.Recordings().GenerateReport(context.Background(), connectUrl, rec) + report, err := apiClient.Recordings().GenerateReport(context.Background(), target, rec) if err != nil { return r.fail(fmt.Sprintf("failed to generate report for the recording: %s", err.Error())) } r.Log += fmt.Sprintf("generated report for the recording %s: %+v\n", rec.Name, report) // Stop the recording - err = apiClient.Recordings().Stop(context.Background(), connectUrl, rec.Name) + err = apiClient.Recordings().Stop(context.Background(), target, rec.Id) if err != nil { return r.fail(fmt.Sprintf("failed to stop the recording %s: %s", rec.Name, err.Error())) } // Get the recording to verify its state - rec, err = apiClient.Recordings().Get(context.Background(), connectUrl, rec.Name) + rec, err = apiClient.Recordings().Get(context.Background(), target, rec.Name) if err != nil { return r.fail(fmt.Sprintf("failed to get the recordings: %s", err.Error())) } @@ -268,14 +267,14 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh r.Log += fmt.Sprintf("stopped the recording: %s\n", rec.Name) // Delete the recording - err = apiClient.Recordings().Delete(context.Background(), connectUrl, rec.Name) + err = apiClient.Recordings().Delete(context.Background(), target, rec.Id) if err != nil { return r.fail(fmt.Sprintf("failed to delete the recording %s: %s", rec.Name, err.Error())) } r.Log += fmt.Sprintf("deleted the recording: %s\n", rec.Name) // View the current recording list after deleting one - recs, err = apiClient.Recordings().List(context.Background(), connectUrl) + recs, err = apiClient.Recordings().List(context.Background(), target) if err != nil { return r.fail(fmt.Sprintf("failed to list recordings: %s", err.Error())) } diff --git a/internal/test/scorecard/types.go b/internal/test/scorecard/types.go index 7e34ff4a0..8c26603de 100644 --- a/internal/test/scorecard/types.go +++ b/internal/test/scorecard/types.go @@ -99,13 +99,16 @@ type Recording struct { } type Archive struct { - Name string - DownloadUrl string - ReportUrl string + Name string `json:"name"` + DownloadUrl string `json:"downloadUrl"` + ReportUrl string `json:"reportUrl"` Metadata struct { - Labels map[string]interface{} - } - Size int32 + Labels []struct { + Key string `json:"key"` + Value string `json:"value"` + } + } `json:"metadata"` + Size uint32 `json:"size"` } type CustomTargetResponse struct { @@ -115,6 +118,7 @@ type CustomTargetResponse struct { } type Target struct { + Id uint32 `json:"id,omitempty"` ConnectUrl string `json:"connectUrl"` Alias string `json:"alias,omitempty"` } @@ -129,8 +133,8 @@ func (target *Target) ToFormData() string { } type GraphQLQuery struct { - Query string `json:"query"` - Variables map[string]string `json:"variables,omitempty"` + Query string `json:"query"` + Variables map[string]any `json:"variables,omitempty"` } func (query *GraphQLQuery) ToJSON() ([]byte, error) { @@ -139,8 +143,12 @@ func (query *GraphQLQuery) ToJSON() ([]byte, error) { type ArchiveGraphQLResponse struct { Data struct { - ArchivedRecordings struct { - Data []Archive `json:"data"` - } `json:"archivedRecordings"` + TargetNodes []struct { + Target struct { + ArchivedRecordings struct { + Data []Archive `json:"data"` + } `json:"archivedRecordings"` + } `json:"target"` + } `json:"targetNodes"` } `json:"data"` } From b300689a645e3741ccd5468e09acf20b5b9fb4d2 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 15 May 2024 07:22:51 -0700 Subject: [PATCH 38/53] feat(scorecard): allow running scorecard test locally (#821) * feat(scorecard): allow running scorecard test locally Signed-off-by: Thuan Vo * feat(make): make target to run scorecard locally --------- Signed-off-by: Thuan Vo --- Makefile | 25 +++++++++++++++++++ .../images/custom-scorecard-tests/main.go | 11 ++++++-- internal/test/scorecard/clients.go | 5 ++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 536066819..655faca4a 100644 --- a/Makefile +++ b/Makefile @@ -158,6 +158,9 @@ ifneq ($(SCORECARD_TEST_SUITE),) SCORECARD_TEST_SELECTOR := --selector=suite=$(SCORECARD_TEST_SUITE) endif +# Specify whether to run scorecard tests only (without setup) +SCORECARD_TEST_ONLY ?= false + ##@ General .PHONY: all @@ -187,6 +190,21 @@ ifneq ($(SKIP_TESTS), true) $(OPERATOR_SDK) scorecard -n $(SCORECARD_NAMESPACE) -s cryostat-scorecard -w 20m $(BUNDLE_IMG) --pod-security=restricted $(SCORECARD_TEST_SELECTOR) endif +.PHONY: test-scorecard-local +test-scorecard-local: check_cert_manager kustomize operator-sdk ## Run scorecard test locally without rebuilding bundle. +ifneq ($(SKIP_TESTS), true) +ifeq ($(SCORECARD_TEST_SELECTION),) + @echo "No test selected. Use SCORECARD_TEST_SELECTION to specify tests. For example: SCORECARD_TEST_SELECTION=cryostat-recording make test-scorecard-local" +else ifeq ($(SCORECARD_TEST_ONLY), true) + @$(call scorecard-local) +else + @$(call scorecard-setup) + $(call scorecard-cleanup) ; \ + trap cleanup EXIT ; \ + $(call scorecard-local) +endif +endif + .PHONY: clean-scorecard clean-scorecard: operator-sdk ## Clean up scorecard resources. - $(call scorecard-cleanup); cleanup @@ -222,6 +240,13 @@ function cleanup { \ } endef +define scorecard-local +for test in $${SCORECARD_TEST_SELECTION//,/ }; do \ + echo "Running scorecard test \"$${test}\""; \ + SCORECARD_NAMESPACE=$(SCORECARD_NAMESPACE) BUNDLE_DIR=./bundle go run internal/images/custom-scorecard-tests/main.go $${test}; \ +done +endef + ##@ Build .PHONY: manager diff --git a/internal/images/custom-scorecard-tests/main.go b/internal/images/custom-scorecard-tests/main.go index 5592e766f..3ef4d98e4 100644 --- a/internal/images/custom-scorecard-tests/main.go +++ b/internal/images/custom-scorecard-tests/main.go @@ -51,8 +51,15 @@ func main() { log.Fatal("SCORECARD_NAMESPACE environment variable not set") } - // Read the pod's untar'd bundle from a well-known path. - bundle, err := apimanifests.GetBundleFromDir(podBundleRoot) + // Get the path to the bundle from BUNDLE_DIR environment variable + // If empty, assume running within a pod and use a well-known path to the pod's untar'd bundle + bundleDir := os.Getenv("BUNDLE_DIR") + if len(bundleDir) == 0 { + bundleDir = podBundleRoot + } + + // Read the bundle from the specified path + bundle, err := apimanifests.GetBundleFromDir(bundleDir) if err != nil { log.Fatalf("failed to read bundle manifest: %s", err.Error()) } diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index d1adb198a..781afd8ce 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/util/wait" + "sigs.k8s.io/controller-runtime/pkg/client/config" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes" @@ -51,7 +52,7 @@ func (c *CryostatClientset) OperatorCRDs() *OperatorCRDClient { // NewClientset creates a CryostatClientset func NewClientset() (*CryostatClientset, error) { // Get in-cluster REST config from pod - config, err := rest.InClusterConfig() + config, err := config.GetConfig() if err != nil { return nil, err } @@ -583,7 +584,7 @@ func NewHttpRequest(ctx context.Context, method string, url string, body *string } // Authentication for OpenShift SSO - config, err := rest.InClusterConfig() + config, err := config.GetConfig() if err != nil { return nil, fmt.Errorf("failed to get in-cluster configurations: %s", err.Error()) } From 13e6a20d850e20a97b4f82b07f4f9c6ee5276b54 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 21 May 2024 14:42:38 -0700 Subject: [PATCH 39/53] fix(status): controller should set approriate status in CR (#825) Signed-off-by: Thuan Vo --- api/v1beta1/cryostat_types.go | 8 +-- api/v1beta2/cryostat_types.go | 11 ++++ ...yostat-operator.clusterserviceversion.yaml | 14 +++- .../operator.cryostat.io_cryostats.yaml | 25 ++++++-- .../bases/operator.cryostat.io_cryostats.yaml | 25 ++++++-- ...yostat-operator.clusterserviceversion.yaml | 12 ++++ internal/controllers/reconciler_test.go | 38 ++++++++--- internal/controllers/secrets.go | 64 +++++++++++-------- internal/test/resources.go | 15 ++++- 9 files changed, 158 insertions(+), 54 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 3b7b04000..b9f51a95e 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -141,8 +141,6 @@ type CryostatStatus struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=status,order=2,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} GrafanaSecret string `json:"grafanaSecret,omitempty"` - // Name of the Secret containing the cryostat storage connection key - StorageSecret string `json:"storageSecret,omitempty"` // Address of the deployed Cryostat web application. // +operator-sdk:csv:customresourcedefinitions:type=status,order=1,xDescriptors={"urn:alm:descriptor:org.w3:link"} ApplicationURL string `json:"applicationUrl"` @@ -315,12 +313,12 @@ type ServiceConfigList struct { // Specification for the service responsible for the Cryostat Grafana dashboard. // +optional GrafanaConfig *GrafanaServiceConfig `json:"grafanaConfig,omitempty"` - // Specification for the service responsible for the cryostat-reports sidecars. + // Specification for the service responsible for the Cryostat reports sidecars. // +optional ReportsConfig *ReportsServiceConfig `json:"reportsConfig,omitempty"` - // Specification for the service responsible for the cryostat storage container. + // Specification for the service responsible for the Cryostat storage container. // +optional - StorageConfig *StorageServiceConfig `json:"storageConfig,omitEmpty"` + StorageConfig *StorageServiceConfig `json:"storageConfig,omitempty"` } // NetworkConfiguration provides customization for how to expose a Cryostat diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 81a189a21..c93a30c24 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -159,6 +159,14 @@ type CryostatStatus struct { // Address of the deployed Cryostat web application. // +operator-sdk:csv:customresourcedefinitions:type=status,order=1,xDescriptors={"urn:alm:descriptor:org.w3:link"} ApplicationURL string `json:"applicationUrl"` + // Name of the Secret containing the Cryostat storage connection key. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=status,order=2,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} + StorageSecret string `json:"storageSecret,omitempty"` + // Name of the Secret containing the Cryostat database connection and encryption keys. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=status,order=2,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} + DatabaseSecret string `json:"databaseSecret,omitempty"` } // CryostatConditionType refers to a Condition type that may be used in status.conditions @@ -414,6 +422,9 @@ type TargetConnectionCacheOptions struct { // to deploy the Cryostat application. // +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} // +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` +// +kubebuilder:printcolumn:name="Target Namespaces",type=string,JSONPath=`.status.targetNamespaces` +// +kubebuilder:printcolumn:name="Storage Secret",type=string,JSONPath=`.status.storageSecret` +// +kubebuilder:printcolumn:name="Database Secret",type=string,JSONPath=`.status.databaseSecret` type Cryostat struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 0d794ced6..abeaef42e 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-11T06:47:54Z" + createdAt: "2024-05-20T05:12:58Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -889,6 +889,18 @@ spec: path: applicationUrl x-descriptors: - urn:alm:descriptor:org.w3:link + - description: Name of the Secret containing the Cryostat database connection + and encryption keys. + displayName: Database Secret + path: databaseSecret + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: Name of the Secret containing the Cryostat storage connection + key. + displayName: Storage Secret + path: storageSecret + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret - description: List of namespaces that Cryostat has been configured and authorized to access and profile. displayName: Target Namespaces diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 5b4a334a8..b095d06d1 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -4646,7 +4646,7 @@ spec: type: object reportsConfig: description: Specification for the service responsible for the - cryostat-reports sidecars. + Cryostat reports sidecars. properties: annotations: additionalProperties: @@ -4672,7 +4672,7 @@ spec: type: object storageConfig: description: Specification for the service responsible for the - cryostat storage container. + Cryostat storage container. properties: annotations: additionalProperties: @@ -5085,10 +5085,6 @@ spec: grafanaSecret: description: Name of the Secret containing the generated Grafana credentials. type: string - storageSecret: - description: Name of the Secret containing the cryostat storage connection - key - type: string required: - applicationUrl type: object @@ -5101,6 +5097,15 @@ spec: - jsonPath: .status.applicationUrl name: Application URL type: string + - jsonPath: .status.targetNamespaces + name: Target Namespaces + type: string + - jsonPath: .status.storageSecret + name: Storage Secret + type: string + - jsonPath: .status.databaseSecret + name: Database Secret + type: string name: v1beta2 schema: openAPIV3Schema: @@ -9832,6 +9837,14 @@ spec: - type type: object type: array + databaseSecret: + description: Name of the Secret containing the Cryostat database connection + and encryption keys. + type: string + storageSecret: + description: Name of the Secret containing the Cryostat storage connection + key. + type: string targetNamespaces: description: List of namespaces that Cryostat has been configured and authorized to access and profile. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 7d6fb2d6b..3102d2e92 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -4636,7 +4636,7 @@ spec: type: object reportsConfig: description: Specification for the service responsible for the - cryostat-reports sidecars. + Cryostat reports sidecars. properties: annotations: additionalProperties: @@ -4662,7 +4662,7 @@ spec: type: object storageConfig: description: Specification for the service responsible for the - cryostat storage container. + Cryostat storage container. properties: annotations: additionalProperties: @@ -5075,10 +5075,6 @@ spec: grafanaSecret: description: Name of the Secret containing the generated Grafana credentials. type: string - storageSecret: - description: Name of the Secret containing the cryostat storage connection - key - type: string required: - applicationUrl type: object @@ -5091,6 +5087,15 @@ spec: - jsonPath: .status.applicationUrl name: Application URL type: string + - jsonPath: .status.targetNamespaces + name: Target Namespaces + type: string + - jsonPath: .status.storageSecret + name: Storage Secret + type: string + - jsonPath: .status.databaseSecret + name: Database Secret + type: string name: v1beta2 schema: openAPIV3Schema: @@ -9822,6 +9827,14 @@ spec: - type type: object type: array + databaseSecret: + description: Name of the Secret containing the Cryostat database connection + and encryption keys. + type: string + storageSecret: + description: Name of the Secret containing the Cryostat storage connection + key. + type: string targetNamespaces: description: List of namespaces that Cryostat has been configured and authorized to access and profile. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 49582ba1e..831922035 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -428,6 +428,18 @@ spec: path: applicationUrl x-descriptors: - urn:alm:descriptor:org.w3:link + - description: Name of the Secret containing the Cryostat database connection + and encryption keys. + displayName: Database Secret + path: databaseSecret + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret + - description: Name of the Secret containing the Cryostat storage connection + key. + displayName: Storage Secret + path: storageSecret + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret - description: List of namespaces that Cryostat has been configured and authorized to access and profile. displayName: Target Namespaces diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index bd1bbd99b..6e09e6524 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -66,7 +66,7 @@ type cryostatTestInput struct { func (c *controllerTest) commonBeforeEach() *cryostatTestInput { t := &cryostatTestInput{ TestReconcilerConfig: test.TestReconcilerConfig{ - GeneratedPasswords: []string{"auth_cookie_secret", "credentials_database", "encryption_key", "object_storage", "jmx", "keystore"}, + GeneratedPasswords: []string{"auth_cookie_secret", "connection_key", "encryption_key", "object_storage", "jmx", "keystore"}, }, TestResources: &test.TestResources{ Name: "cryostat", @@ -145,7 +145,7 @@ func resourceChecks() []resourceCheck { {func(t *cryostatTestInput) { t.expectPVC(t.NewDefaultPVC()) }, "persistent volume claim"}, - {(*cryostatTestInput).expectCredentialsDatabaseSecret, "credentials database secret"}, + {(*cryostatTestInput).expectDatabaseSecret, "database secret"}, {(*cryostatTestInput).expectStorageSecret, "object storage secret"}, {(*cryostatTestInput).expectJMXSecret, "JMX secret"}, {(*cryostatTestInput).expectCoreService, "core service"}, @@ -164,6 +164,12 @@ func expectSuccessful(t **cryostatTestInput) { It("should set ApplicationURL in CR Status", func() { (*t).expectStatusApplicationURL() }) + It("should set Database Secret in CR Status", func() { + (*t).expectStatusDatabaseSecret() + }) + It("should set Storage Secret in CR Status", func() { + (*t).expectStatusStorageSecret() + }) It("should set TLSSetupComplete condition", func() { (*t).checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "AllCertificatesReady") @@ -496,7 +502,7 @@ func (c *controllerTest) commonTests() { Expect(secret.StringData["CRYOSTAT_RJMX_PASS"]).To(Equal(oldSecret.StringData["CRYOSTAT_RJMX_PASS"])) }) }) - Context("with an existing Credentials Database Secret", func() { + Context("with an existing Database Secret", func() { var cr *model.CryostatInstance var oldSecret *corev1.Secret BeforeEach(func() { @@ -1592,9 +1598,11 @@ func (c *controllerTest) commonTests() { }) }) }) - Context("with secret provided for database password", func() { + Context("with secret provided for database", func() { + var customSecret *corev1.Secret BeforeEach(func() { - t.objs = append(t.objs, t.NewCryostatWithDatabaseSecretProvided().Object) + customSecret = t.NewCustomDatabaseSecret() + t.objs = append(t.objs, t.NewCryostatWithDatabaseSecretProvided().Object, customSecret) }) JustBeforeEach(func() { t.reconcileCryostatFully() @@ -1602,16 +1610,20 @@ func (c *controllerTest) commonTests() { It("should configure deployment appropriately", func() { t.expectMainDeployment() }) + It("should set Database Secret in CR Status", func() { + instance := t.getCryostatInstance() + Expect(instance.Status.DatabaseSecret).To(Equal(customSecret.Name)) + }) It("should not generate default secret", func() { secret := &corev1.Secret{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-db", Namespace: t.Namespace}, secret) Expect(kerrors.IsNotFound(err)).To(BeTrue()) }) - Context("with an existing Credentials Database Secret", func() { + Context("with an existing Database Secret", func() { BeforeEach(func() { t.objs = append(t.objs, t.NewDatabaseSecret()) }) - It("should not delete the existing Credentials Database Secret", func() { + It("should not delete the existing Database Secret", func() { secret := &corev1.Secret{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-db", Namespace: t.Namespace}, secret) Expect(err).ToNot(HaveOccurred()) @@ -2356,7 +2368,7 @@ func (t *cryostatTestInput) expectEmptyDir(expectedEmptyDir *corev1.EmptyDirVolu Expect(emptyDir.SizeLimit).To(Equal(expectedEmptyDir.SizeLimit)) } -func (t *cryostatTestInput) expectCredentialsDatabaseSecret() { +func (t *cryostatTestInput) expectDatabaseSecret() { secret := &corev1.Secret{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-db", Namespace: t.Namespace}, secret) Expect(err).ToNot(HaveOccurred()) @@ -2398,6 +2410,16 @@ func (t *cryostatTestInput) expectStatusApplicationURL() { Expect(instance.Status.ApplicationURL).To(Equal(fmt.Sprintf("https://%s.example.com", t.Name))) } +func (t *cryostatTestInput) expectStatusDatabaseSecret() { + instance := t.getCryostatInstance() + Expect(instance.Status.DatabaseSecret).To(Equal(fmt.Sprintf("%s-db", t.Name))) +} + +func (t *cryostatTestInput) expectStatusStorageSecret() { + instance := t.getCryostatInstance() + Expect(instance.Status.StorageSecret).To(Equal(fmt.Sprintf("%s-storage-secret-key", t.Name))) +} + func (t *cryostatTestInput) expectDeploymentHasCertSecrets() { deployment := &appsv1.Deployment{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, deployment) diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index 119a02d01..cb1961220 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -93,34 +93,42 @@ func (r *Reconciler) reconcileJMXSecret(ctx context.Context, cr *model.CryostatI } // databaseSecretNameSuffix is the suffix to be appended to the name of a -// Cryostat CR to name its credentials database secret +// Cryostat CR to name its database secret const databaseSecretNameSuffix = "-db" func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr *model.CryostatInstance) error { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + databaseSecretNameSuffix, - Namespace: cr.InstallNamespace, - }, - } - + var secretName string secretProvided := cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil if secretProvided { - return nil // Do not delete default secret to allow reverting to use default if needed - } - - return r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { - if secret.StringData == nil { - secret.StringData = map[string]string{} + // Do not delete default secret to allow reverting to use default if needed + secretName = *cr.Spec.DatabaseOptions.SecretName + } else { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: cr.Name + databaseSecretNameSuffix, + Namespace: cr.InstallNamespace, + }, } - - // Password is generated, so don't regenerate it when updating - if secret.CreationTimestamp.IsZero() { - secret.StringData[constants.DatabaseSecretConnectionKey] = r.GenPasswd(32) - secret.StringData[constants.DatabaseSecretEncryptionKey] = r.GenPasswd(32) + err := r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { + if secret.StringData == nil { + secret.StringData = map[string]string{} + } + + // Password is generated, so don't regenerate it when updating + if secret.CreationTimestamp.IsZero() { + secret.StringData[constants.DatabaseSecretConnectionKey] = r.GenPasswd(32) + secret.StringData[constants.DatabaseSecretEncryptionKey] = r.GenPasswd(32) + } + return nil + }) + + if err != nil { + return err } - return nil - }) + secretName = secret.Name + } + cr.Status.DatabaseSecret = secretName + return r.Client.Status().Update(ctx, cr.Object) } // storageSecretNameSuffix is the suffix to be appended to the name of a @@ -138,12 +146,7 @@ func (r *Reconciler) reconcileStorageSecret(ctx context.Context, cr *model.Cryos }, } - // secretProvided := cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil - // if secretProvided { - // return nil // Do not delete default secret to allow reverting to use default if needed - // } - - return r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { + err := r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { if secret.StringData == nil { secret.StringData = map[string]string{} } @@ -154,6 +157,13 @@ func (r *Reconciler) reconcileStorageSecret(ctx context.Context, cr *model.Cryos } return nil }) + + if err != nil { + return err + } + + cr.Status.StorageSecret = secret.Name + return r.Client.Status().Update(ctx, cr.Object) } func (r *Reconciler) createOrUpdateSecret(ctx context.Context, secret *corev1.Secret, owner metav1.Object, diff --git a/internal/test/resources.go b/internal/test/resources.go index 497d61de2..a736953ef 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -855,12 +855,25 @@ func (r *TestResources) NewDatabaseSecret() *corev1.Secret { Namespace: r.Namespace, }, StringData: map[string]string{ - "CONNECTION_KEY": "credentials_database", + "CONNECTION_KEY": "connection_key", "ENCRYPTION_KEY": "encryption_key", }, } } +func (r *TestResources) NewCustomDatabaseSecret() *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: providedDatabaseSecretName, + Namespace: r.Namespace, + }, + StringData: map[string]string{ + "CONNECTION_KEY": "custom-connection_database", + "ENCRYPTION_KEY": "custom-encryption_key", + }, + } +} + func (r *TestResources) NewStorageSecret() *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ From ad965120f6bfb1359cfcc935babbc957151429a6 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 21 May 2024 14:49:26 -0700 Subject: [PATCH 40/53] fix(secret): database should use user-defined secret if specified (#827) * fix(secret): database should use user-defined secret if specified Signed-off-by: Thuan Vo * chore(def): simplify database secret getter * test(db): check for database container * test(proxy): check for auth proxy container * test(env): fix typo --------- Signed-off-by: Thuan Vo --- .../resource_definitions.go | 14 +- internal/controllers/reconciler_test.go | 102 ++++- internal/test/resources.go | 399 +++++++++++++++--- 3 files changed, 421 insertions(+), 94 deletions(-) diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 38f7f8d6e..2caf52ab6 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -1000,10 +1000,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag } optional := false - secretName := cr.Name + "-db" - if cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil { - secretName = *cr.Spec.DatabaseOptions.SecretName - } + secretName := getDatabaseSecret(cr) envs = append(envs, corev1.EnvVar{ Name: "QUARKUS_DATASOURCE_PASSWORD", ValueFrom: &corev1.EnvVarSource{ @@ -1415,7 +1412,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC } optional := false - secretName := cr.Name + "-db" + secretName := getDatabaseSecret(cr) envs = append(envs, corev1.EnvVar{ Name: "POSTGRESQL_PASSWORD", ValueFrom: &corev1.EnvVarSource{ @@ -1624,3 +1621,10 @@ func populateResourceRequest(resources *corev1.ResourceRequirements, defaultCpu, } checkResourceRequestWithLimit(requests, resources.Limits) } + +func getDatabaseSecret(cr *model.CryostatInstance) string { + if cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil { + return *cr.Spec.DatabaseOptions.SecretName + } + return cr.Name + "-db" +} diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 6e09e6524..65f5e27db 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -2638,6 +2638,25 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, datasourceContainer := template.Spec.Containers[2] t.checkDatasourceContainer(&datasourceContainer, t.NewDatasourceContainerResource(cr), t.NewDatasourceSecurityContext(cr)) + // Check that Storage is configured properly + storageContainer := template.Spec.Containers[3] + t.checkStorageContainer(&storageContainer, t.NewStorageContainerResource(cr), t.NewStorageSecurityContext(cr)) + + // Check that Database is configured properly + databaseContainer := template.Spec.Containers[4] + t.checkDatabaseContainer(&databaseContainer, t.NewDatabaseContainerResource(cr), t.NewDatabaseSecurityContext(cr), dbSecretProvided) + + // Check that Auth Proxy is configured properly + authProxyContainer := template.Spec.Containers[5] + basicAuthConfigured := cr.Spec.AuthorizationOptions != nil && + cr.Spec.AuthorizationOptions.BasicAuth != nil && + cr.Spec.AuthorizationOptions.BasicAuth.Filename != nil && cr.Spec.AuthorizationOptions.BasicAuth.SecretName != nil + var basicAuthFilename string + if basicAuthConfigured { + basicAuthFilename = *cr.Spec.AuthorizationOptions.BasicAuth.Filename + } + t.checkAuthProxyContainer(&authProxyContainer, t.NewAuthProxyContainerResource(cr), t.NewAuthProxySecurityContext(cr), basicAuthConfigured, basicAuthFilename) + // Check that the proper Service Account is set Expect(template.Spec.ServiceAccountName).To(Equal(t.Name)) @@ -2800,7 +2819,7 @@ func (t *cryostatTestInput) checkGrafanaContainer(container *corev1.Container, r } Expect(container.Ports).To(ConsistOf(t.NewGrafanaPorts())) Expect(container.Env).To(ConsistOf(t.NewGrafanaEnvironmentVariables())) - Expect(container.VolumeMounts).To(ConsistOf(t.NewGrafanaVolumeMounts())) + Expect(container.VolumeMounts).To(BeEmpty()) Expect(container.LivenessProbe).To(Equal(t.NewGrafanaLivenessProbe())) Expect(container.SecurityContext).To(Equal(securityContext)) @@ -2824,6 +2843,65 @@ func (t *cryostatTestInput) checkDatasourceContainer(container *corev1.Container test.ExpectResourceRequirements(&container.Resources, resources) } +func (t *cryostatTestInput) checkStorageContainer(container *corev1.Container, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext) { + Expect(container.Name).To(Equal(t.Name + "-storage")) + if t.EnvStorageImageTag == nil { + Expect(container.Image).To(HavePrefix("quay.io/cryostat/cryostat-storage:")) + } else { + Expect(container.Image).To(Equal(*t.EnvStorageImageTag)) + } + Expect(container.Ports).To(ConsistOf(t.NewStoragePorts())) + Expect(container.Env).To(ConsistOf(t.NewStorageEnvironmentVariables())) + Expect(container.EnvFrom).To(BeEmpty()) + Expect(container.VolumeMounts).To(ConsistOf(t.NewStorageVolumeMounts())) + Expect(container.LivenessProbe).To(Equal(t.NewStorageLivenessProbe())) + Expect(container.SecurityContext).To(Equal(securityContext)) + + test.ExpectResourceRequirements(&container.Resources, resources) +} + +func (t *cryostatTestInput) checkDatabaseContainer(container *corev1.Container, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext, dbSecretProvided bool) { + Expect(container.Name).To(Equal(t.Name + "-db")) + if t.EnvDatabaseImageTag == nil { + Expect(container.Image).To(HavePrefix("quay.io/cryostat/cryostat-db:")) + } else { + Expect(container.Image).To(Equal(*t.EnvDatabaseImageTag)) + } + Expect(container.Ports).To(ConsistOf(t.NewDatabasePorts())) + Expect(container.Env).To(ConsistOf(t.NewDatabaseEnvironmentVariables(dbSecretProvided))) + Expect(container.EnvFrom).To(BeEmpty()) + Expect(container.VolumeMounts).To(ConsistOf(t.NewDatabaseVolumeMounts())) + Expect(container.ReadinessProbe).To(Equal(t.NewDatabaseReadinessProbe())) + Expect(container.SecurityContext).To(Equal(securityContext)) + + test.ExpectResourceRequirements(&container.Resources, resources) +} + +func (t *cryostatTestInput) checkAuthProxyContainer(container *corev1.Container, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext, basicAuthConfigured bool, basicAuthFilename string) { + Expect(container.Name).To(Equal(t.Name + "-auth-proxy")) + + imageTag := t.EnvOAuth2ProxyImageTag + defaultPrefix := "quay.io/oauth2-proxy/oauth2-proxy:" + if t.OpenShift { + imageTag = t.EnvOpenShiftOAuthProxyImageTag + defaultPrefix = "quay.io/openshift/origin-oauth-proxy:" + } + if imageTag != nil { + Expect(container.Image).To(Equal(*imageTag)) + } else { + Expect(container.Image).To(HavePrefix(defaultPrefix)) + } + + Expect(container.Ports).To(ConsistOf(t.NewAuthProxyPorts())) + Expect(container.Env).To(ConsistOf(t.NewAuthProxyEnvironmentVariables(basicAuthConfigured, basicAuthFilename))) + Expect(container.EnvFrom).To(ConsistOf(t.NewAuthProxyEnvFromSource())) + Expect(container.VolumeMounts).To(ConsistOf(t.NewAuthProxyVolumeMounts(basicAuthConfigured))) + Expect(container.LivenessProbe).To(Equal(t.NewAuthProxyLivenessProbe())) + Expect(container.SecurityContext).To(Equal(securityContext)) + + test.ExpectResourceRequirements(&container.Resources, resources) +} + func (t *cryostatTestInput) checkReportsContainer(container *corev1.Container, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext) { Expect(container.Name).To(Equal(t.Name + "-reports")) if t.EnvReportsImageTag == nil { @@ -2840,22 +2918,6 @@ func (t *cryostatTestInput) checkReportsContainer(container *corev1.Container, r test.ExpectResourceRequirements(&container.Resources, resources) } -// func (t *cryostatTestInput) checkStorageContainer(container *corev1.Container, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext) { -// Expect(container.Name).To(Equal(t.Name + "-storage")) -// if t.EnvReportsImageTag == nil { -// Expect(container.Image).To(HavePrefix("quay.io/cryostat/cryostat-storage:")) -// } else { -// Expect(container.Image).To(Equal(*t.EnvReportsImageTag)) -// } -// Expect(container.Ports).To(ConsistOf(t.NewStoragePorts())) -// Expect(container.Env).To(ConsistOf(t.NewStorageEnvironmentVariables(resources))) -// Expect(container.VolumeMounts).To(ConsistOf(t.NewReportsVolumeMounts())) -// Expect(container.LivenessProbe).To(Equal(t.NewReportsLivenessProbe())) -// Expect(container.SecurityContext).To(Equal(securityContext)) - -// test.ExpectResourceRequirements(&container.Resources, resources) -// } - func (t *cryostatTestInput) checkCoreHasEnvironmentVariables(expectedEnvVars []corev1.EnvVar) { deployment := &appsv1.Deployment{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, deployment) @@ -2905,12 +2967,6 @@ func (t *cryostatTestInput) expectConsoleLink() { Expect(link.Spec).To(Equal(expectedLink.Spec)) } -func (t *cryostatTestInput) expectResourcesUnaffected() { - for _, check := range resourceChecks() { - check.expectFunc(t) - } -} - func (t *cryostatTestInput) expectTargetNamespaces() { cr := t.getCryostatInstance() Expect(*cr.TargetNamespaceStatus).To(ConsistOf(t.TargetNamespaces)) diff --git a/internal/test/resources.go b/internal/test/resources.go index a736953ef..9fb75bc41 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1186,13 +1186,23 @@ func (r *TestResources) NewReportsPorts() []corev1.ContainerPort { func (r *TestResources) NewStoragePorts() []corev1.ContainerPort { return []corev1.ContainerPort{ { - ContainerPort: 8080, + ContainerPort: 8333, }, + } +} + +func (r *TestResources) NewDatabasePorts() []corev1.ContainerPort { + return []corev1.ContainerPort{ { - ContainerPort: 8333, + ContainerPort: 5432, }, + } +} + +func (r *TestResources) NewAuthProxyPorts() []corev1.ContainerPort { + return []corev1.ContainerPort{ { - ContainerPort: 8888, + ContainerPort: 4180, }, } } @@ -1465,12 +1475,129 @@ func (r *TestResources) NewReportsEnvironmentVariables(resources *corev1.Resourc func (r *TestResources) NewStorageEnvironmentVariables() []corev1.EnvVar { return []corev1.EnvVar{ { - Name: "QUARKUS_HTTP_HOST", - Value: "127.0.0.1", + Name: "CRYOSTAT_BUCKETS", + Value: "archivedrecordings,archivedreports,eventtemplates,probes", }, { - Name: "QUARKUS_HTTP_PORT", - Value: "8989", + Name: "CRYOSTAT_ACCESS_KEY", + Value: "cryostat", + }, + { + Name: "DATA_DIR", + Value: "/data", + }, + { + Name: "IP_BIND", + Value: "0.0.0.0", + }, + { + Name: "CRYOSTAT_SECRET_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: r.Name + "-storage-secret-key", + }, + Key: "SECRET_KEY", + Optional: &[]bool{false}[0], + }, + }, + }, + } +} + +func (r *TestResources) NewDatabaseEnvironmentVariables(dbSecretProvided bool) []corev1.EnvVar { + optional := false + secretName := r.Name + "-db" + if dbSecretProvided { + secretName = providedDatabaseSecretName + } + return []corev1.EnvVar{ + { + Name: "POSTGRESQL_USER", + Value: "cryostat3", + }, + { + Name: "POSTGRESQL_DATABASE", + Value: "cryostat3", + }, + { + Name: "POSTGRESQL_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + Key: "CONNECTION_KEY", + Optional: &optional, + }, + }, + }, + { + Name: "PG_ENCRYPT_KEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + Key: "ENCRYPTION_KEY", + Optional: &optional, + }, + }, + }, + } +} + +func (r *TestResources) NewAuthProxyEnvironmentVariables(basicAuthConfigured bool, basicAuthFilename string) []corev1.EnvVar { + envs := []corev1.EnvVar{} + + if !r.OpenShift { + envs = append(envs, + corev1.EnvVar{ + Name: "OAUTH2_PROXY_REDIRECT_URL", + Value: "http://localhost:4180/oauth2/callback", + }, + corev1.EnvVar{ + Name: "OAUTH2_PROXY_EMAIL_DOMAINS", + Value: "*", + }, + ) + + if basicAuthConfigured { + envs = append(envs, + corev1.EnvVar{ + Name: "OAUTH2_PROXY_HTPASSWD_FILE", + Value: "/var/run/secrets/operator.cryostat.io/" + basicAuthFilename, + }, + corev1.EnvVar{ + Name: "OAUTH2_PROXY_HTPASSWD_USER_GROUP", + Value: "write", + }, + corev1.EnvVar{ + Name: "OAUTH2_PROXY_SKIP_AUTH_ROUTES", + Value: "^/health(/liveness)?$", + }, + ) + } else { + envs = append(envs, + corev1.EnvVar{ + Name: "OAUTH2_PROXY_SKIP_AUTH_ROUTES", + Value: ".*", + }) + } + } + + return envs +} + +func (r *TestResources) NewAuthProxyEnvFromSource() []corev1.EnvFromSource { + return []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: r.Name + "-oauth2-cookie", + }, + Optional: &[]bool{false}[0], + }, }, } } @@ -1575,8 +1702,54 @@ func (r *TestResources) NewCoreVolumeMounts() []corev1.VolumeMount { return mounts } -func (r *TestResources) NewGrafanaVolumeMounts() []corev1.VolumeMount { +func (r *TestResources) NewStorageVolumeMounts() []corev1.VolumeMount { + return []corev1.VolumeMount{ + { + Name: r.Name, + MountPath: "/data", + SubPath: "seaweed", + }, + } +} + +func (r *TestResources) NewDatabaseVolumeMounts() []corev1.VolumeMount { + return []corev1.VolumeMount{ + { + Name: r.Name, + MountPath: "/data", + SubPath: "postgres", + }, + } +} + +func (r *TestResources) NewAuthProxyVolumeMounts(basicAuthConfigured bool) []corev1.VolumeMount { mounts := []corev1.VolumeMount{} + if r.TLS { + mounts = append(mounts, corev1.VolumeMount{ + Name: "auth-proxy-tls-secret", + MountPath: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-tls", r.Name), + ReadOnly: true, + }) + } + + if basicAuthConfigured { + mounts = append(mounts, corev1.VolumeMount{ + Name: r.Name + "-auth-proxy-htpasswd", + MountPath: "/var/run/secrets/operator.cryostat.io", + ReadOnly: true, + }) + } + + if !r.OpenShift { + mounts = append(mounts, + corev1.VolumeMount{ + Name: r.Name + "-oauth2-proxy-cfg", + MountPath: "/etc/oauth2_proxy/alpha_config", + ReadOnly: true, + }) + + } + return mounts } @@ -1667,6 +1840,49 @@ func (r *TestResources) NewDatasourceLivenessProbe() *corev1.Probe { } } +func (r *TestResources) NewStorageLivenessProbe() *corev1.Probe { + return &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.IntOrString{IntVal: 8333}, + Path: "/status", + Scheme: corev1.URISchemeHTTP, + }, + }, + FailureThreshold: 2, + } +} + +func (r *TestResources) NewDatabaseReadinessProbe() *corev1.Probe { + return &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + Exec: &corev1.ExecAction{ + Command: []string{"pg_isready", "-U", "cryostat3", "-d", "cryostat3"}, + }, + }, + } +} + +func (r *TestResources) NewAuthProxyLivenessProbe() *corev1.Probe { + protocol := corev1.URISchemeHTTP + if r.TLS { + protocol = corev1.URISchemeHTTPS + } + path := "/ping" + if r.OpenShift { + path = "/oauth2/healthz" + } + return &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Port: intstr.IntOrString{IntVal: 4180}, + Path: path, + Scheme: protocol, + }, + }, + } +} + func (r *TestResources) NewReportsLivenessProbe() *corev1.Probe { protocol := corev1.URISchemeHTTPS if !r.TLS { @@ -2020,6 +2236,27 @@ func (r *TestResources) NewDatasourceSecurityContext(cr *model.CryostatInstance) return r.commonDefaultSecurityContext() } +func (r *TestResources) NewStorageSecurityContext(cr *model.CryostatInstance) *corev1.SecurityContext { + if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.StorageSecurityContext != nil { + return cr.Spec.SecurityOptions.StorageSecurityContext + } + return r.commonDefaultSecurityContext() +} + +func (r *TestResources) NewDatabaseSecurityContext(cr *model.CryostatInstance) *corev1.SecurityContext { + if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.DatabaseSecurityContext != nil { + return cr.Spec.SecurityOptions.DatabaseSecurityContext + } + return r.commonDefaultSecurityContext() +} + +func (r *TestResources) NewAuthProxySecurityContext(cr *model.CryostatInstance) *corev1.SecurityContext { + if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.AuthProxySecurityContext != nil { + return cr.Spec.SecurityOptions.AuthProxySecurityContext + } + return r.commonDefaultSecurityContext() +} + func (r *TestResources) NewReportSecurityContext(cr *model.CryostatInstance) *corev1.SecurityContext { if cr.Spec.ReportOptions != nil && cr.Spec.ReportOptions.SecurityOptions != nil && cr.Spec.ReportOptions.SecurityOptions.ReportsSecurityContext != nil { return cr.Spec.ReportOptions.SecurityOptions.ReportsSecurityContext @@ -2567,117 +2804,147 @@ func (r *TestResources) NewApiServerWithApplicationURL() *configv1.APIServer { } } -func newCoreContainerDefaultResource() *corev1.ResourceRequirements { - return &corev1.ResourceRequirements{ +func (r *TestResources) NewCoreContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("500m"), corev1.ResourceMemory: resource.MustParse("384Mi"), }, } -} -func (r *TestResources) NewCoreContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { - requests := newCoreContainerDefaultResource().Requests - var limits corev1.ResourceList if cr.Spec.Resources != nil && cr.Spec.Resources.CoreResources.Requests != nil { - requests = cr.Spec.Resources.CoreResources.Requests - } else if cr.Spec.Resources != nil && cr.Spec.Resources.CoreResources.Limits != nil { - checkWithLimit(requests, cr.Spec.Resources.CoreResources.Limits) + resources.Requests = cr.Spec.Resources.CoreResources.Requests } - if cr.Spec.Resources != nil { - limits = cr.Spec.Resources.CoreResources.Limits + if cr.Spec.Resources != nil && cr.Spec.Resources.CoreResources.Limits != nil { + resources.Limits = cr.Spec.Resources.CoreResources.Limits + checkWithLimit(resources.Requests, resources.Limits) } - return &corev1.ResourceRequirements{ - Requests: requests, - Limits: limits, - } + return resources } -func newDatasourceContainerDefaultResource() *corev1.ResourceRequirements { - return &corev1.ResourceRequirements{ +func (r *TestResources) NewDatasourceContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("200m"), corev1.ResourceMemory: resource.MustParse("200Mi"), }, } -} -func (r *TestResources) NewDatasourceContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { - requests := newDatasourceContainerDefaultResource().Requests - var limits corev1.ResourceList if cr.Spec.Resources != nil && cr.Spec.Resources.DataSourceResources.Requests != nil { - requests = cr.Spec.Resources.DataSourceResources.Requests - } else if cr.Spec.Resources != nil && cr.Spec.Resources.DataSourceResources.Limits != nil { - checkWithLimit(requests, cr.Spec.Resources.DataSourceResources.Limits) + resources.Requests = cr.Spec.Resources.DataSourceResources.Requests } - if cr.Spec.Resources != nil { - limits = cr.Spec.Resources.DataSourceResources.Limits + if cr.Spec.Resources != nil && cr.Spec.Resources.DataSourceResources.Limits != nil { + resources.Limits = cr.Spec.Resources.DataSourceResources.Limits + checkWithLimit(resources.Requests, resources.Limits) } - return &corev1.ResourceRequirements{ - Requests: requests, - Limits: limits, - } + return resources } -func newGrafanaContainerDefaultResource() *corev1.ResourceRequirements { - return &corev1.ResourceRequirements{ +func (r *TestResources) NewGrafanaContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("25m"), corev1.ResourceMemory: resource.MustParse("80Mi"), }, } -} -func (r *TestResources) NewGrafanaContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { - requests := newGrafanaContainerDefaultResource().Requests - var limits corev1.ResourceList if cr.Spec.Resources != nil && cr.Spec.Resources.GrafanaResources.Requests != nil { - requests = cr.Spec.Resources.GrafanaResources.Requests - } else if cr.Spec.Resources != nil && cr.Spec.Resources.GrafanaResources.Limits != nil { - checkWithLimit(requests, cr.Spec.Resources.GrafanaResources.Limits) + resources.Requests = cr.Spec.Resources.GrafanaResources.Requests } - if cr.Spec.Resources != nil { - limits = cr.Spec.Resources.GrafanaResources.Limits + if cr.Spec.Resources != nil && cr.Spec.Resources.GrafanaResources.Limits != nil { + resources.Limits = cr.Spec.Resources.GrafanaResources.Limits + checkWithLimit(resources.Requests, resources.Limits) } - return &corev1.ResourceRequirements{ - Requests: requests, - Limits: limits, + return resources +} + +func (r *TestResources) NewStorageContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("50m"), + corev1.ResourceMemory: resource.MustParse("256Mi"), + }, + } + + if cr.Spec.Resources != nil && cr.Spec.Resources.ObjectStorageResources.Requests != nil { + resources.Requests = cr.Spec.Resources.ObjectStorageResources.Requests } + + if cr.Spec.Resources != nil && cr.Spec.Resources.ObjectStorageResources.Limits != nil { + resources.Limits = cr.Spec.Resources.ObjectStorageResources.Limits + checkWithLimit(resources.Requests, resources.Limits) + } + + return resources } -func newReportContainerDefaultResource() *corev1.ResourceRequirements { - return &corev1.ResourceRequirements{ +func (r *TestResources) NewDatabaseContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("512Mi"), + corev1.ResourceCPU: resource.MustParse("25m"), + corev1.ResourceMemory: resource.MustParse("64Mi"), }, } + + if cr.Spec.Resources != nil && cr.Spec.Resources.DatabaseResources.Requests != nil { + resources.Requests = cr.Spec.Resources.DatabaseResources.Requests + } + + if cr.Spec.Resources != nil && cr.Spec.Resources.DatabaseResources.Limits != nil { + resources.Limits = cr.Spec.Resources.DatabaseResources.Limits + checkWithLimit(resources.Requests, resources.Limits) + } + + return resources +} + +func (r *TestResources) NewAuthProxyContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("25m"), + corev1.ResourceMemory: resource.MustParse("64Mi"), + }, + } + + if cr.Spec.Resources != nil && cr.Spec.Resources.AuthProxyResources.Requests != nil { + resources.Requests = cr.Spec.Resources.AuthProxyResources.Requests + } + + if cr.Spec.Resources != nil && cr.Spec.Resources.AuthProxyResources.Limits != nil { + resources.Limits = cr.Spec.Resources.AuthProxyResources.Limits + checkWithLimit(resources.Requests, resources.Limits) + } + + return resources } func (r *TestResources) NewReportContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { - requests := newReportContainerDefaultResource().Requests - var limits corev1.ResourceList + resources := &corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("512Mi"), + }, + } if cr.Spec.ReportOptions != nil { reportOptions := cr.Spec.ReportOptions if reportOptions.Resources.Requests != nil { - requests = reportOptions.Resources.Requests - } else if reportOptions.Resources.Limits != nil { - checkWithLimit(requests, reportOptions.Resources.Limits) + resources.Requests = reportOptions.Resources.Requests } - limits = reportOptions.Resources.Limits - } - return &corev1.ResourceRequirements{ - Requests: requests, - Limits: limits, + if reportOptions.Resources.Limits != nil { + resources.Limits = reportOptions.Resources.Limits + checkWithLimit(resources.Requests, resources.Limits) + } } + + return resources } func checkWithLimit(requests, limits corev1.ResourceList) { From f692e475ad62c556132bc22675fd8e06559a0770 Mon Sep 17 00:00:00 2001 From: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Date: Mon, 27 May 2024 17:17:17 -0400 Subject: [PATCH 41/53] chore(storage): rename storage secret (#833) --- bundle/manifests/cryostat-operator.clusterserviceversion.yaml | 2 +- .../common/resource_definitions/resource_definitions.go | 4 ++-- internal/controllers/reconciler_test.go | 4 ++-- internal/controllers/secrets.go | 2 +- internal/test/resources.go | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index abeaef42e..0b8851753 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-20T05:12:58Z" + createdAt: "2024-05-27T20:00:30Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 2caf52ab6..e80cfb00e 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -1019,7 +1019,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Value: "cryostat", }) - secretName = cr.Name + "-storage-secret-key" + secretName = cr.Name + "-storage" envs = append(envs, corev1.EnvVar{ Name: "QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY", ValueFrom: &corev1.EnvVarSource{ @@ -1317,7 +1317,7 @@ func NewStorageContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo }, } - secretName := cr.Name + "-storage-secret-key" + secretName := cr.Name + "-storage" optional := false envs = append(envs, corev1.EnvVar{ Name: "CRYOSTAT_SECRET_KEY", diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 65f5e27db..526f327ce 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -2381,7 +2381,7 @@ func (t *cryostatTestInput) expectDatabaseSecret() { func (t *cryostatTestInput) expectStorageSecret() { secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-storage-secret-key", Namespace: t.Namespace}, secret) + err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-storage", Namespace: t.Namespace}, secret) Expect(err).ToNot(HaveOccurred()) // Compare to desired spec @@ -2417,7 +2417,7 @@ func (t *cryostatTestInput) expectStatusDatabaseSecret() { func (t *cryostatTestInput) expectStatusStorageSecret() { instance := t.getCryostatInstance() - Expect(instance.Status.StorageSecret).To(Equal(fmt.Sprintf("%s-storage-secret-key", t.Name))) + Expect(instance.Status.StorageSecret).To(Equal(fmt.Sprintf("%s-storage", t.Name))) } func (t *cryostatTestInput) expectDeploymentHasCertSecrets() { diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index cb1961220..9ded00104 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -133,7 +133,7 @@ func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr * // storageSecretNameSuffix is the suffix to be appended to the name of a // Cryostat CR to name its object storage secret -const storageSecretNameSuffix = "-storage-secret-key" +const storageSecretNameSuffix = "-storage" // storageSecretUserKey indexes the password within the Cryostat storage Secret const storageSecretPassKey = "SECRET_KEY" diff --git a/internal/test/resources.go b/internal/test/resources.go index 9fb75bc41..9c4b86c73 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -877,7 +877,7 @@ func (r *TestResources) NewCustomDatabaseSecret() *corev1.Secret { func (r *TestResources) NewStorageSecret() *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-storage-secret-key", + Name: r.Name + "-storage", Namespace: r.Namespace, }, StringData: map[string]string{ @@ -1495,7 +1495,7 @@ func (r *TestResources) NewStorageEnvironmentVariables() []corev1.EnvVar { ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: r.Name + "-storage-secret-key", + Name: r.Name + "-storage", }, Key: "SECRET_KEY", Optional: &[]bool{false}[0], From ec50b8858f0456b661bca01380a57d856065d7c0 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Tue, 28 May 2024 17:03:21 -0400 Subject: [PATCH 42/53] chore(jmx): remove configuration for JMX server, service, and auth secret (#823) * chore(jmx): remove configuration for JMX server, service, and auth secret * regen * remove jmx credential * readme * correct agent sample cryostat service port * increase memory limit * default agent to enable API writes * re-add JMX port in v1beta1 conversion test * fixup conversion test * fixup envtest --- README.md | 13 ++--- api/v1beta1/cryostat_conversion.go | 2 - api/v1beta1/cryostat_conversion_test.go | 2 + api/v1beta2/cryostat_types.go | 6 +-- api/v1beta2/zz_generated.deepcopy.go | 5 -- .../operator.cryostat.io_cryostats.yaml | 5 -- .../bases/operator.cryostat.io_cryostats.yaml | 5 -- config/samples/sample-app-agent.yaml | 6 ++- docs/config.md | 3 +- .../resource_definitions.go | 13 ----- internal/controllers/constants/constants.go | 1 - internal/controllers/reconciler_test.go | 38 +-------------- internal/controllers/secrets.go | 37 +-------------- internal/controllers/services.go | 9 ---- internal/test/conversion.go | 9 +++- internal/test/resources.go | 47 +------------------ internal/test/scorecard/tests.go | 19 -------- 17 files changed, 23 insertions(+), 197 deletions(-) diff --git a/README.md b/README.md index e2f29b6d8..936e5fc5d 100644 --- a/README.md +++ b/README.md @@ -31,14 +31,11 @@ at the URL provided by: ``` kubectl get cryostat -o jsonpath='{$.items[0].status.applicationUrl}' ``` -The JMX authentication credentials for Cryostat itself can be obtained with: -```shell -CRYOSTAT_NAME=$(kubectl get cryostat -o jsonpath='{$.items[0].metadata.name}') -# Username -kubectl get secret ${CRYOSTAT_NAME}-jmx-auth -o jsonpath='{$.data.CRYOSTAT_RJMX_USER}' | base64 -d -# Password -kubectl get secret ${CRYOSTAT_NAME}-jmx-auth -o jsonpath='{$.data.CRYOSTAT_RJMX_PASS}' | base64 -d -``` + +To use Cryostat to monitor or profile Cryostat itself - since it is also an available JVM target - +you may use the Cryostat web UI to define a Custom Target with the connection URL `localhost:0`. +This is a special value which tells Cryostat's JVM that it should connect to itself directly, without +the need to expose a JMX port over the network. # Building ## Requirements diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index 0d8bc4424..4a6b898d2 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -120,7 +120,6 @@ func convertServiceOptionsTo(srcOpts *ServiceConfigList) *operatorv1beta2.Servic if srcOpts.CoreConfig != nil { dstOpts.CoreConfig = &operatorv1beta2.CoreServiceConfig{ HTTPPort: srcOpts.CoreConfig.HTTPPort, - JMXPort: srcOpts.CoreConfig.JMXPort, ServiceConfig: convertServiceConfigTo(srcOpts.CoreConfig.ServiceConfig), } } @@ -382,7 +381,6 @@ func convertServiceOptionsFrom(srcOpts *operatorv1beta2.ServiceConfigList) *Serv if srcOpts.CoreConfig != nil { dstOpts.CoreConfig = &CoreServiceConfig{ HTTPPort: srcOpts.CoreConfig.HTTPPort, - JMXPort: srcOpts.CoreConfig.JMXPort, ServiceConfig: convertServiceConfigFrom(srcOpts.CoreConfig.ServiceConfig), } } diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go index ccc9ad597..a0058defd 100644 --- a/api/v1beta1/cryostat_conversion_test.go +++ b/api/v1beta1/cryostat_conversion_test.go @@ -84,6 +84,8 @@ func tableEntriesTo() []TableEntry { (*test.TestResources).NewCryostatWithIngress), Entry("minimal mode", (*test.TestResources).NewCryostatWithMinimalModeV1Beta1, (*test.TestResources).NewCryostat), + Entry("core JMX port", (*test.TestResources).NewCryostatWithCoreSvcJMXPortV1Beta1, + (*test.TestResources).NewCryostatWithCoreSvc), ) } diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index c93a30c24..89df67d0c 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -292,11 +292,7 @@ type CoreServiceConfig struct { // HTTP port number for the Cryostat application service. // Defaults to 8181. // +optional - HTTPPort *int32 `json:"httpPort,omitempty"` - // Remote JMX port number for the Cryostat application service. - // Defaults to 9091. - // +optional - JMXPort *int32 `json:"jmxPort,omitempty"` + HTTPPort *int32 `json:"httpPort,omitempty"` ServiceConfig `json:",inline"` } diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 973fbf820..57b4fc8a7 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -125,11 +125,6 @@ func (in *CoreServiceConfig) DeepCopyInto(out *CoreServiceConfig) { *out = new(int32) **out = **in } - if in.JMXPort != nil { - in, out := &in.JMXPort, &out.JMXPort - *out = new(int32) - **out = **in - } in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) } diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index b095d06d1..e20a74c99 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -9385,11 +9385,6 @@ spec: service. Defaults to 8181. format: int32 type: integer - jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. - format: int32 - type: integer labels: additionalProperties: type: string diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 3102d2e92..17a51300b 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -9375,11 +9375,6 @@ spec: service. Defaults to 8181. format: int32 type: integer - jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. - format: int32 - type: integer labels: additionalProperties: type: string diff --git a/config/samples/sample-app-agent.yaml b/config/samples/sample-app-agent.yaml index d3cf7ca7c..4ca177ae7 100644 --- a/config/samples/sample-app-agent.yaml +++ b/config/samples/sample-app-agent.yaml @@ -24,8 +24,10 @@ spec: fieldRef: apiVersion: v1 fieldPath: metadata.namespace + - name: CRYOSTAT_AGENT_API_WRITES_ENABLED + value: "true" - name: CRYOSTAT_AGENT_BASEURI - value: https://cryostat-sample.$(NAMESPACE).svc:8181 + value: https://cryostat-sample.$(NAMESPACE).svc:4180 - name: POD_IP valueFrom: fieldRef: @@ -64,7 +66,7 @@ spec: memory: 96Mi limits: cpu: 500m - memory: 128Mi + memory: 192Mi securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/docs/config.md b/docs/config.md index e57155516..1d694774e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -99,7 +99,7 @@ spec: ``` ### Service Options -The Cryostat operator creates three services: one for the core Cryostat application, one for Grafana, and one for the cryostat-reports sidecars. These services are created by default as Cluster IP services. The core service exposes two ports: `8181` for HTTP and `9091` for JMX. The Grafana service exposes port `3000` for HTTP traffic. The Reports service exposts port `10000` for HTTP traffic. The service type, port numbers, labels and annotations can all be customized using the `spec.serviceOptions` property. +The Cryostat operator creates two services: one for the core Cryostat application and (optionally) one for the cryostat-reports sidecars. These services are created by default as Cluster IP services. The core service exposes one ports `4180` for HTTP(S). The Reports service exposts port `10000` for HTTP(S) traffic. The service type, port numbers, labels and annotations can all be customized using the `spec.serviceOptions` property. ```yaml apiVersion: operator.cryostat.io/v1beta1 kind: Cryostat @@ -114,7 +114,6 @@ spec: my-custom-annotation: some-value serviceType: NodePort httpPort: 8080 - jmxPort: 9095 grafanaConfig: labels: my-custom-label: some-value diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index e80cfb00e..43fdb346d 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -1081,15 +1081,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag }, } envs = append(envs, connectionCacheEnvs...) - envsFrom := []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Name + "-jmx-auth", - }, - }, - }, - } k8sDiscoveryEnabled := true k8sDiscoveryPortNames := "jfr-jmx" @@ -1190,12 +1181,8 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag { ContainerPort: constants.CryostatHTTPContainerPort, }, - { - ContainerPort: constants.CryostatJMXContainerPort, - }, }, Env: envs, - EnvFrom: envsFrom, Resources: *NewCoreContainerResource(cr), LivenessProbe: &corev1.Probe{ ProbeHandler: probeHandler, diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index f609d40b8..86351dfc1 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -22,7 +22,6 @@ import ( const ( AuthProxyHttpContainerPort int32 = 4180 CryostatHTTPContainerPort int32 = 8181 - CryostatJMXContainerPort int32 = 9091 GrafanaContainerPort int32 = 3000 DatasourceContainerPort int32 = 8989 ReportsContainerPort int32 = 10000 diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 526f327ce..9b2415d08 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -66,7 +66,7 @@ type cryostatTestInput struct { func (c *controllerTest) commonBeforeEach() *cryostatTestInput { t := &cryostatTestInput{ TestReconcilerConfig: test.TestReconcilerConfig{ - GeneratedPasswords: []string{"auth_cookie_secret", "connection_key", "encryption_key", "object_storage", "jmx", "keystore"}, + GeneratedPasswords: []string{"auth_cookie_secret", "connection_key", "encryption_key", "object_storage", "keystore"}, }, TestResources: &test.TestResources{ Name: "cryostat", @@ -147,7 +147,6 @@ func resourceChecks() []resourceCheck { }, "persistent volume claim"}, {(*cryostatTestInput).expectDatabaseSecret, "database secret"}, {(*cryostatTestInput).expectStorageSecret, "object storage secret"}, - {(*cryostatTestInput).expectJMXSecret, "JMX secret"}, {(*cryostatTestInput).expectCoreService, "core service"}, {(*cryostatTestInput).expectMainDeployment, "main deployment"}, {(*cryostatTestInput).expectLockConfigMap, "lock config map"}, @@ -478,30 +477,6 @@ func (c *controllerTest) commonTests() { }) }) }) - Context("with an existing JMX Secret", func() { - var cr *model.CryostatInstance - var oldSecret *corev1.Secret - BeforeEach(func() { - cr = t.NewCryostat() - oldSecret = t.OtherJMXSecret() - t.objs = append(t.objs, cr.Object, oldSecret) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - }) - It("should update the username but not password", func() { - secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: oldSecret.Name, Namespace: t.Namespace}, secret) - Expect(err).ToNot(HaveOccurred()) - - Expect(metav1.IsControlledBy(secret, cr.Object)).To(BeTrue()) - - // Username should be replaced, but not password - expected := t.NewJMXSecret() - Expect(secret.StringData["CRYOSTAT_RJMX_USER"]).To(Equal(expected.StringData["CRYOSTAT_RJMX_USER"])) - Expect(secret.StringData["CRYOSTAT_RJMX_PASS"]).To(Equal(oldSecret.StringData["CRYOSTAT_RJMX_PASS"])) - }) - }) Context("with an existing Database Secret", func() { var cr *model.CryostatInstance var oldSecret *corev1.Secret @@ -2390,17 +2365,6 @@ func (t *cryostatTestInput) expectStorageSecret() { Expect(secret.StringData).To(Equal(expectedSecret.StringData)) } -func (t *cryostatTestInput) expectJMXSecret() { - secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-jmx-auth", Namespace: t.Namespace}, secret) - Expect(err).ToNot(HaveOccurred()) - - // Compare to desired spec - expectedSecret := t.NewJMXSecret() - t.checkMetadata(secret, expectedSecret) - Expect(secret.StringData).To(Equal(expectedSecret.StringData)) -} - func (t *cryostatTestInput) expectCoreService() { t.checkService(t.Name, t.NewCryostatService()) } diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index 9ded00104..b2519c0b0 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -33,10 +33,7 @@ func (r *Reconciler) reconcileSecrets(ctx context.Context, cr *model.CryostatIns if err := r.reconcileDatabaseConnectionSecret(ctx, cr); err != nil { return err } - if err := r.reconcileStorageSecret(ctx, cr); err != nil { - return err - } - return r.reconcileJMXSecret(ctx, cr) + return r.reconcileStorageSecret(ctx, cr) } func (r *Reconciler) reconcileAuthProxyCookieSecret(ctx context.Context, cr *model.CryostatInstance) error { @@ -60,38 +57,6 @@ func (r *Reconciler) reconcileAuthProxyCookieSecret(ctx context.Context, cr *mod }) } -// jmxSecretNameSuffix is the suffix to be appended to the name of a -// Cryostat CR to name its JMX credentials secret -const jmxSecretNameSuffix = "-jmx-auth" - -// jmxSecretUserKey indexes the username within the Cryostat JMX auth secret -const jmxSecretUserKey = "CRYOSTAT_RJMX_USER" - -// jmxSecretPassKey indexes the password within the Cryostat JMX auth secret -const jmxSecretPassKey = "CRYOSTAT_RJMX_PASS" - -func (r *Reconciler) reconcileJMXSecret(ctx context.Context, cr *model.CryostatInstance) error { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + jmxSecretNameSuffix, - Namespace: cr.InstallNamespace, - }, - } - - return r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { - if secret.StringData == nil { - secret.StringData = map[string]string{} - } - secret.StringData[jmxSecretUserKey] = "cryostat" - - // Password is generated, so don't regenerate it when updating - if secret.CreationTimestamp.IsZero() { - secret.StringData[jmxSecretPassKey] = r.GenPasswd(20) - } - return nil - }) -} - // databaseSecretNameSuffix is the suffix to be appended to the name of a // Cryostat CR to name its database secret const databaseSecretNameSuffix = "-db" diff --git a/internal/controllers/services.go b/internal/controllers/services.go index e8ce4c61e..db099e1fd 100644 --- a/internal/controllers/services.go +++ b/internal/controllers/services.go @@ -53,11 +53,6 @@ func (r *Reconciler) reconcileCoreService(ctx context.Context, cr *model.Cryosta Port: *config.HTTPPort, TargetPort: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, }, - { - Name: "jfr-jmx", - Port: *config.JMXPort, - TargetPort: intstr.IntOrString{IntVal: constants.CryostatJMXContainerPort}, - }, } return nil }) @@ -133,10 +128,6 @@ func configureCoreService(cr *model.CryostatInstance) *operatorv1beta2.CoreServi httpPort := constants.AuthProxyHttpContainerPort config.HTTPPort = &httpPort } - if config.JMXPort == nil { - jmxPort := constants.CryostatJMXContainerPort - config.JMXPort = &jmxPort - } return config } diff --git a/internal/test/conversion.go b/internal/test/conversion.go index 86f61472d..ee42357e7 100644 --- a/internal/test/conversion.go +++ b/internal/test/conversion.go @@ -168,12 +168,10 @@ func (r *TestResources) NewCryostatWithEmptyDirSpecV1Beta1() *operatorv1beta1.Cr func (r *TestResources) NewCryostatWithCoreSvcV1Beta1() *operatorv1beta1.Cryostat { svcType := corev1.ServiceTypeNodePort httpPort := int32(8080) - jmxPort := int32(9095) cr := r.NewCryostatV1Beta1() cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ CoreConfig: &operatorv1beta1.CoreServiceConfig{ HTTPPort: &httpPort, - JMXPort: &jmxPort, ServiceConfig: operatorv1beta1.ServiceConfig{ ServiceType: &svcType, Annotations: map[string]string{ @@ -189,6 +187,13 @@ func (r *TestResources) NewCryostatWithCoreSvcV1Beta1() *operatorv1beta1.Cryosta return cr } +func (r *TestResources) NewCryostatWithCoreSvcJMXPortV1Beta1() *operatorv1beta1.Cryostat { + jmxPort := int32(9095) + cr := r.NewCryostatWithCoreSvcV1Beta1() + cr.Spec.ServiceOptions.CoreConfig.JMXPort = &jmxPort + return cr +} + func (r *TestResources) NewCryostatWithGrafanaSvcV1Beta1() *operatorv1beta1.Cryostat { svcType := corev1.ServiceTypeNodePort httpPort := int32(8080) diff --git a/internal/test/resources.go b/internal/test/resources.go index 9c4b86c73..91722ddd5 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -230,12 +230,10 @@ func (r *TestResources) NewCryostatWithEmptyDirSpec() *model.CryostatInstance { func (r *TestResources) NewCryostatWithCoreSvc() *model.CryostatInstance { svcType := corev1.ServiceTypeNodePort httpPort := int32(8080) - jmxPort := int32(9095) cr := r.NewCryostat() cr.Spec.ServiceOptions = &operatorv1beta2.ServiceConfigList{ CoreConfig: &operatorv1beta2.CoreServiceConfig{ HTTPPort: &httpPort, - JMXPort: &jmxPort, ServiceConfig: operatorv1beta2.ServiceConfig{ ServiceType: &svcType, Annotations: map[string]string{ @@ -665,11 +663,6 @@ func (r *TestResources) NewCryostatService() *corev1.Service { Port: 4180, TargetPort: intstr.FromInt(4180), }, - { - Name: "jfr-jmx", - Port: 9091, - TargetPort: intstr.FromInt(9091), - }, }, }, } @@ -790,7 +783,6 @@ func (r *TestResources) NewCustomizedCoreService() *corev1.Service { svc := r.NewCryostatService() svc.Spec.Type = corev1.ServiceTypeNodePort svc.Spec.Ports[0].Port = 8080 - svc.Spec.Ports[1].Port = 9095 svc.Annotations = map[string]string{ "my/custom": "annotation", } @@ -899,19 +891,6 @@ func (r *TestResources) OtherDatabaseSecret() *corev1.Secret { } } -func (r *TestResources) NewJMXSecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-jmx-auth", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "CRYOSTAT_RJMX_USER": "cryostat", - "CRYOSTAT_RJMX_PASS": "jmx", - }, - } -} - func (r *TestResources) NewKeystoreSecret() *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -924,19 +903,6 @@ func (r *TestResources) NewKeystoreSecret() *corev1.Secret { } } -func (r *TestResources) OtherJMXSecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-jmx-auth", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "CRYOSTAT_RJMX_USER": "not-cryostat", - "CRYOSTAT_RJMX_PASS": "other-pass", - }, - } -} - func (r *TestResources) NewTestCertSecret(name string) *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -1153,9 +1119,6 @@ func (r *TestResources) NewCorePorts() []corev1.ContainerPort { { ContainerPort: 8181, }, - { - ContainerPort: 9091, - }, } } @@ -1603,15 +1566,7 @@ func (r *TestResources) NewAuthProxyEnvFromSource() []corev1.EnvFromSource { } func (r *TestResources) NewCoreEnvFromSource() []corev1.EnvFromSource { - envsFrom := []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: r.Name + "-jmx-auth", - }, - }, - }, - } + envsFrom := []corev1.EnvFromSource{} return envsFrom } diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index a06b6e7a1..16d74d763 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -23,7 +23,6 @@ import ( operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -186,24 +185,6 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh } r.Log += fmt.Sprintf("created a custom target: %+v\n", target) - jmxSecretName := CryostatRecordingTestName + "-jmx-auth" - secret, err := r.Client.CoreV1().Secrets(namespace).Get(context.Background(), jmxSecretName, metav1.GetOptions{}) - if err != nil { - return r.fail(fmt.Sprintf("failed to get jmx credentials: %s", err.Error())) - } - - credential := &Credential{ - UserName: string(secret.Data["CRYOSTAT_RJMX_USER"]), - Password: string(secret.Data["CRYOSTAT_RJMX_PASS"]), - MatchExpression: fmt.Sprintf("target.alias==\"%s\"", target.Alias), - } - - err = apiClient.CredentialClient.Create(context.Background(), credential) - if err != nil { - return r.fail(fmt.Sprintf("failed to create stored credential: %s", err.Error())) - } - r.Log += fmt.Sprintf("created stored credential with match expression: %s\n", credential.MatchExpression) - // Wait for Cryostat to update the discovery tree time.Sleep(2 * time.Second) From 7918cf90a0caa4e9bca2cd286de07d5de5bd33c5 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 28 May 2024 14:15:18 -0700 Subject: [PATCH 43/53] chore(discovery): ensure consistent names for discovery options in CRD (#828) Signed-off-by: Thuan Vo --- api/v1beta1/cryostat_conversion.go | 4 ++-- api/v1beta2/cryostat_types.go | 6 +++--- .../cryostat-operator.clusterserviceversion.yaml | 14 ++++++++------ .../manifests/operator.cryostat.io_cryostats.yaml | 12 +++++++----- .../crd/bases/operator.cryostat.io_cryostats.yaml | 12 +++++++----- .../cryostat-operator.clusterserviceversion.yaml | 12 +++++++----- .../resource_definitions/resource_definitions.go | 2 +- internal/controllers/reconciler_test.go | 2 +- internal/test/resources.go | 2 +- 9 files changed, 37 insertions(+), 29 deletions(-) diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index 4a6b898d2..7de305950 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -244,7 +244,7 @@ func convertTargetDiscoveryTo(srcOpts *TargetDiscoveryOptions) *operatorv1beta2. var dstOpts *operatorv1beta2.TargetDiscoveryOptions if srcOpts != nil { dstOpts = &operatorv1beta2.TargetDiscoveryOptions{ - BuiltInDiscoveryDisabled: srcOpts.BuiltInDiscoveryDisabled, + DisableBuiltInDiscovery: srcOpts.BuiltInDiscoveryDisabled, DisableBuiltInPortNames: srcOpts.DisableBuiltInPortNames, DiscoveryPortNames: srcOpts.DiscoveryPortNames, DisableBuiltInPortNumbers: srcOpts.DisableBuiltInPortNumbers, @@ -505,7 +505,7 @@ func convertTargetDiscoveryFrom(srcOpts *operatorv1beta2.TargetDiscoveryOptions) var dstOpts *TargetDiscoveryOptions if srcOpts != nil { dstOpts = &TargetDiscoveryOptions{ - BuiltInDiscoveryDisabled: srcOpts.BuiltInDiscoveryDisabled, + BuiltInDiscoveryDisabled: srcOpts.DisableBuiltInDiscovery, DisableBuiltInPortNames: srcOpts.DisableBuiltInPortNames, DiscoveryPortNames: srcOpts.DiscoveryPortNames, DisableBuiltInPortNumbers: srcOpts.DisableBuiltInPortNumbers, diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index 89df67d0c..e87fa0798 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -580,8 +580,8 @@ type TargetDiscoveryOptions struct { // When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable Built-in Discovery",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} - BuiltInDiscoveryDisabled bool `json:"builtInDiscoveryDisabled,omitempty"` - // When true, the Cryostat application will use the default port name jfr-jmx to look for JMX connectable targets. + DisableBuiltInDiscovery bool `json:"disableBuiltInDiscovery,omitempty"` + // When false and discoveryPortNames is empty, the Cryostat application will use the default port name jfr-jmx to look for JMX connectable targets. Defaults to false. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable Built-in Port Names",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} DisableBuiltInPortNames bool `json:"disableBuiltInPortNames,omitempty"` @@ -589,7 +589,7 @@ type TargetDiscoveryOptions struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldDependency:targetDiscoveryOptions.disableBuiltInPortNames:true"} DiscoveryPortNames []string `json:"discoveryPortNames,omitempty"` - // When true, the Cryostat application will use the default port number 9091 to look for JMX connectable targets. + // When false and discoveryPortNumbers is empty, the Cryostat application will use the default port number 9091 to look for JMX connectable targets. Defaults to false. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Disable Built-in Port Numbers",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} DisableBuiltInPortNumbers bool `json:"disableBuiltInPortNumbers,omitempty"` diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 0b8851753..12aee9bfb 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-27T20:00:30Z" + createdAt: "2024-05-28T20:14:14Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -842,17 +842,19 @@ spec: - description: When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false displayName: Disable Built-in Discovery - path: targetDiscoveryOptions.builtInDiscoveryDisabled + path: targetDiscoveryOptions.disableBuiltInDiscovery x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - name jfr-jmx to look for JMX connectable targets. + - description: When false and discoveryPortNames is empty, the Cryostat application + will use the default port name jfr-jmx to look for JMX connectable targets. + Defaults to false. displayName: Disable Built-in Port Names path: targetDiscoveryOptions.disableBuiltInPortNames x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - number 9091 to look for JMX connectable targets. + - description: When false and discoveryPortNumbers is empty, the Cryostat application + will use the default port number 9091 to look for JMX connectable targets. + Defaults to false. displayName: Disable Built-in Port Numbers path: targetDiscoveryOptions.disableBuiltInPortNumbers x-descriptors: diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index e20a74c99..abe2529f6 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -9706,17 +9706,19 @@ spec: description: Options to configure the Cryostat application's target discovery mechanisms. properties: - builtInDiscoveryDisabled: + disableBuiltInDiscovery: description: When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false type: boolean disableBuiltInPortNames: - description: When true, the Cryostat application will use the - default port name jfr-jmx to look for JMX connectable targets. + description: When false and discoveryPortNames is empty, the Cryostat + application will use the default port name jfr-jmx to look for + JMX connectable targets. Defaults to false. type: boolean disableBuiltInPortNumbers: - description: When true, the Cryostat application will use the - default port number 9091 to look for JMX connectable targets. + description: When false and discoveryPortNumbers is empty, the + Cryostat application will use the default port number 9091 to + look for JMX connectable targets. Defaults to false. type: boolean discoveryPortNames: description: List of port names that the Cryostat application diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 17a51300b..c8bb0ddd1 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -9696,17 +9696,19 @@ spec: description: Options to configure the Cryostat application's target discovery mechanisms. properties: - builtInDiscoveryDisabled: + disableBuiltInDiscovery: description: When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false type: boolean disableBuiltInPortNames: - description: When true, the Cryostat application will use the - default port name jfr-jmx to look for JMX connectable targets. + description: When false and discoveryPortNames is empty, the Cryostat + application will use the default port name jfr-jmx to look for + JMX connectable targets. Defaults to false. type: boolean disableBuiltInPortNumbers: - description: When true, the Cryostat application will use the - default port number 9091 to look for JMX connectable targets. + description: When false and discoveryPortNumbers is empty, the + Cryostat application will use the default port number 9091 to + look for JMX connectable targets. Defaults to false. type: boolean discoveryPortNames: description: List of port names that the Cryostat application diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 831922035..2ac7fd2c3 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -387,17 +387,19 @@ spec: - description: When true, the Cryostat application will disable the built-in discovery mechanisms. Defaults to false displayName: Disable Built-in Discovery - path: targetDiscoveryOptions.builtInDiscoveryDisabled + path: targetDiscoveryOptions.disableBuiltInDiscovery x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - name jfr-jmx to look for JMX connectable targets. + - description: When false and discoveryPortNames is empty, the Cryostat application + will use the default port name jfr-jmx to look for JMX connectable targets. + Defaults to false. displayName: Disable Built-in Port Names path: targetDiscoveryOptions.disableBuiltInPortNames x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: When true, the Cryostat application will use the default port - number 9091 to look for JMX connectable targets. + - description: When false and discoveryPortNumbers is empty, the Cryostat application + will use the default port number 9091 to look for JMX connectable targets. + Defaults to false. displayName: Disable Built-in Port Numbers path: targetDiscoveryOptions.disableBuiltInPortNumbers x-descriptors: diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 43fdb346d..a23758052 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -1086,7 +1086,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag k8sDiscoveryPortNames := "jfr-jmx" k8sDiscoveryPortNumbers := "9091" if cr.Spec.TargetDiscoveryOptions != nil { - k8sDiscoveryEnabled = !cr.Spec.TargetDiscoveryOptions.BuiltInDiscoveryDisabled + k8sDiscoveryEnabled = !cr.Spec.TargetDiscoveryOptions.DisableBuiltInDiscovery if len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames) > 0 { k8sDiscoveryPortNames = strings.Join(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames[:], ",") diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 9b2415d08..b9857fe7d 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -2580,7 +2580,7 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, hasPortConfig := cr.Spec.TargetDiscoveryOptions != nil && len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNames) > 0 && len(cr.Spec.TargetDiscoveryOptions.DiscoveryPortNumbers) > 0 - builtInDiscoveryDisabled := cr.Spec.TargetDiscoveryOptions != nil && cr.Spec.TargetDiscoveryOptions.BuiltInDiscoveryDisabled + builtInDiscoveryDisabled := cr.Spec.TargetDiscoveryOptions != nil && cr.Spec.TargetDiscoveryOptions.DisableBuiltInDiscovery builtInPortConfigDisabled := cr.Spec.TargetDiscoveryOptions != nil && cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNames && cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNumbers diff --git a/internal/test/resources.go b/internal/test/resources.go index 91722ddd5..e0da06ded 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -464,7 +464,7 @@ func (r *TestResources) NewCryostatWithLowResourceLimit() *model.CryostatInstanc func (r *TestResources) NewCryostatWithBuiltInDiscoveryDisabled() *model.CryostatInstance { cr := r.NewCryostat() cr.Spec.TargetDiscoveryOptions = &operatorv1beta2.TargetDiscoveryOptions{ - BuiltInDiscoveryDisabled: true, + DisableBuiltInDiscovery: true, } return cr } From 04e0331cdce9db97c14945387a00291bc90c588e Mon Sep 17 00:00:00 2001 From: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Date: Wed, 29 May 2024 11:24:24 -0400 Subject: [PATCH 44/53] fix(scorecard): print newline instead of \n in local scorecard test output (#834) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 655faca4a..34f491345 100644 --- a/Makefile +++ b/Makefile @@ -243,7 +243,7 @@ endef define scorecard-local for test in $${SCORECARD_TEST_SELECTION//,/ }; do \ echo "Running scorecard test \"$${test}\""; \ - SCORECARD_NAMESPACE=$(SCORECARD_NAMESPACE) BUNDLE_DIR=./bundle go run internal/images/custom-scorecard-tests/main.go $${test}; \ + SCORECARD_NAMESPACE=$(SCORECARD_NAMESPACE) BUNDLE_DIR=./bundle go run internal/images/custom-scorecard-tests/main.go $${test} | sed 's/\\n/\n/g'; \ done endef From 374c5767406a25f7c54072fb21b9405a091c5487 Mon Sep 17 00:00:00 2001 From: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Date: Thu, 30 May 2024 16:38:12 -0400 Subject: [PATCH 45/53] chore(CI): update OLM to 0.28.0 (#837) * update OLM to 0.28.0 * fix typo --- .github/workflows/test-ci-reusable.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-ci-reusable.yml b/.github/workflows/test-ci-reusable.yml index 0eefabd1b..bd24a7dbe 100644 --- a/.github/workflows/test-ci-reusable.yml +++ b/.github/workflows/test-ci-reusable.yml @@ -142,7 +142,7 @@ jobs: ip_address=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ci-${{ github.run_id }}-control-plane) echo "$ip_address testing.cryostat" | sudo tee -a /etc/hosts - name: Install Operator Lifecycle Manager - run: curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.24.0/install.sh | bash -s v0.24.0 + run: curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.28.0/install.sh | bash -s v0.28.0 - name: Install Cert Manager run: make cert_manager - uses: redhat-actions/podman-login@v1 From 0832d987bb5c614aeff83277de6ef061e17e84d1 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Tue, 4 Jun 2024 14:20:21 -0400 Subject: [PATCH 46/53] fix(proxy): do not pass unused credentials upstream (#839) --- .../common/resource_definitions/resource_definitions.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index a23758052..ef1cb1dcf 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -647,6 +647,9 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp } args := []string{ + "--pass-access-token=false", + "--pass-user-bearer-token=false", + "--pass-basic-auth=false", fmt.Sprintf("--upstream=http://localhost:%d/", constants.CryostatHTTPContainerPort), fmt.Sprintf("--upstream=http://localhost:%d/grafana/", constants.GrafanaContainerPort), fmt.Sprintf("--upstream=http://localhost:%d/storage/", constants.StoragePort), From 28f69769e9ae3d767ee1ee9874073607d76196b3 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 5 Jun 2024 06:13:00 -0700 Subject: [PATCH 47/53] test(envtest): add validations for auth proxy arguments (#844) * test(env): ensure crd dir path is valid * test(env): add validations for auth proxy arguments --- internal/controllers/reconciler_test.go | 19 +++--- internal/controllers/suite_test.go | 7 +- internal/test/resources.go | 88 ++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 17 deletions(-) diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index b9857fe7d..ecdef0fd4 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -2612,14 +2612,7 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, // Check that Auth Proxy is configured properly authProxyContainer := template.Spec.Containers[5] - basicAuthConfigured := cr.Spec.AuthorizationOptions != nil && - cr.Spec.AuthorizationOptions.BasicAuth != nil && - cr.Spec.AuthorizationOptions.BasicAuth.Filename != nil && cr.Spec.AuthorizationOptions.BasicAuth.SecretName != nil - var basicAuthFilename string - if basicAuthConfigured { - basicAuthFilename = *cr.Spec.AuthorizationOptions.BasicAuth.Filename - } - t.checkAuthProxyContainer(&authProxyContainer, t.NewAuthProxyContainerResource(cr), t.NewAuthProxySecurityContext(cr), basicAuthConfigured, basicAuthFilename) + t.checkAuthProxyContainer(&authProxyContainer, t.NewAuthProxyContainerResource(cr), t.NewAuthProxySecurityContext(cr), cr.Spec.AuthorizationOptions) // Check that the proper Service Account is set Expect(template.Spec.ServiceAccountName).To(Equal(t.Name)) @@ -2841,7 +2834,7 @@ func (t *cryostatTestInput) checkDatabaseContainer(container *corev1.Container, test.ExpectResourceRequirements(&container.Resources, resources) } -func (t *cryostatTestInput) checkAuthProxyContainer(container *corev1.Container, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext, basicAuthConfigured bool, basicAuthFilename string) { +func (t *cryostatTestInput) checkAuthProxyContainer(container *corev1.Container, resources *corev1.ResourceRequirements, securityContext *corev1.SecurityContext, authOptions *operatorv1beta2.AuthorizationOptions) { Expect(container.Name).To(Equal(t.Name + "-auth-proxy")) imageTag := t.EnvOAuth2ProxyImageTag @@ -2857,12 +2850,16 @@ func (t *cryostatTestInput) checkAuthProxyContainer(container *corev1.Container, } Expect(container.Ports).To(ConsistOf(t.NewAuthProxyPorts())) - Expect(container.Env).To(ConsistOf(t.NewAuthProxyEnvironmentVariables(basicAuthConfigured, basicAuthFilename))) + Expect(container.Env).To(ConsistOf(t.NewAuthProxyEnvironmentVariables(authOptions))) Expect(container.EnvFrom).To(ConsistOf(t.NewAuthProxyEnvFromSource())) - Expect(container.VolumeMounts).To(ConsistOf(t.NewAuthProxyVolumeMounts(basicAuthConfigured))) + Expect(container.VolumeMounts).To(ConsistOf(t.NewAuthProxyVolumeMounts(authOptions))) Expect(container.LivenessProbe).To(Equal(t.NewAuthProxyLivenessProbe())) Expect(container.SecurityContext).To(Equal(securityContext)) + args, err := t.NewAuthProxyArguments(authOptions) + Expect(err).ToNot(HaveOccurred()) + Expect(container.Args).To(ConsistOf(args)) + test.ExpectResourceRequirements(&container.Resources, resources) } diff --git a/internal/controllers/suite_test.go b/internal/controllers/suite_test.go index 36391d97c..a86cbcb64 100644 --- a/internal/controllers/suite_test.go +++ b/internal/controllers/suite_test.go @@ -27,7 +27,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta1" certv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" configv1 "github.com/openshift/api/config/v1" @@ -54,7 +54,8 @@ var _ = BeforeSuite(func() { By("bootstrapping test environment") testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, } var err error @@ -63,7 +64,7 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = operatorv1beta1.AddToScheme(scheme.Scheme) + err = operatorv1beta2.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = certv1.AddToScheme(scheme.Scheme) diff --git a/internal/test/resources.go b/internal/test/resources.go index e0da06ded..76d691b55 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -16,6 +16,7 @@ package test import ( "crypto/sha256" + "encoding/json" "fmt" "strings" @@ -29,6 +30,7 @@ import ( routev1 "github.com/openshift/api/route/v1" securityv1 "github.com/openshift/api/security/v1" appsv1 "k8s.io/api/apps/v1" + authzv1 "k8s.io/api/authorization/v1" corev1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -1510,7 +1512,7 @@ func (r *TestResources) NewDatabaseEnvironmentVariables(dbSecretProvided bool) [ } } -func (r *TestResources) NewAuthProxyEnvironmentVariables(basicAuthConfigured bool, basicAuthFilename string) []corev1.EnvVar { +func (r *TestResources) NewAuthProxyEnvironmentVariables(authOptions *operatorv1beta2.AuthorizationOptions) []corev1.EnvVar { envs := []corev1.EnvVar{} if !r.OpenShift { @@ -1525,11 +1527,13 @@ func (r *TestResources) NewAuthProxyEnvironmentVariables(basicAuthConfigured boo }, ) + basicAuthConfigured := authOptions != nil && authOptions.BasicAuth != nil && + authOptions.BasicAuth.Filename != nil && authOptions.BasicAuth.SecretName != nil if basicAuthConfigured { envs = append(envs, corev1.EnvVar{ Name: "OAUTH2_PROXY_HTPASSWD_FILE", - Value: "/var/run/secrets/operator.cryostat.io/" + basicAuthFilename, + Value: "/var/run/secrets/operator.cryostat.io/" + *authOptions.BasicAuth.Filename, }, corev1.EnvVar{ Name: "OAUTH2_PROXY_HTPASSWD_USER_GROUP", @@ -1628,6 +1632,82 @@ func (r *TestResources) NewTargetDiscoveryEnvVars(hasPortConfig bool, builtInDis return envs } +func (r *TestResources) NewAuthProxyArguments(authOptions *operatorv1beta2.AuthorizationOptions) ([]string, error) { + if !r.OpenShift { + return []string{ + "--alpha-config=/etc/oauth2_proxy/alpha_config/alpha_config.json", + }, nil + } + + basicAuthConfigured := authOptions != nil && authOptions.BasicAuth != nil && + authOptions.BasicAuth.Filename != nil && authOptions.BasicAuth.SecretName != nil + + openShiftSSOConfigured := authOptions != nil && authOptions.OpenShiftSSO != nil + openShiftSSODisabled := openShiftSSOConfigured && authOptions.OpenShiftSSO.Disable != nil && *authOptions.OpenShiftSSO.Disable + + accessReview := authzv1.ResourceAttributes{ + Namespace: r.Namespace, + Verb: "create", + Group: "", + Version: "", + Resource: "pods", + Subresource: "exec", + Name: "", + } + if openShiftSSOConfigured && authOptions.OpenShiftSSO.AccessReview != nil { + accessReview = *authOptions.OpenShiftSSO.AccessReview + } + + subjectAccessReviewJson, err := json.Marshal([]authzv1.ResourceAttributes{accessReview}) + if err != nil { + return nil, err + } + + delegateUrls := make(map[string]authzv1.ResourceAttributes) + delegateUrls["/"] = accessReview + tokenReviewJson, err := json.Marshal(delegateUrls) + if err != nil { + return nil, err + } + + args := []string{ + "--upstream=http://localhost:8181/", + "--upstream=http://localhost:3000/grafana/", + "--upstream=http://localhost:8333/storage/", + fmt.Sprintf("--openshift-service-account=%s", r.Name), + "--proxy-websockets=true", + "--proxy-prefix=/oauth2", + fmt.Sprintf("--skip-provider-button=%t", !basicAuthConfigured), + fmt.Sprintf("--openshift-sar=%s", subjectAccessReviewJson), + fmt.Sprintf("--openshift-delegate-urls=%s", string(tokenReviewJson)), + } + + if openShiftSSODisabled { + args = append(args, "--bypass-auth-for=.*") + } else { + args = append(args, "--bypass-auth-for=^/health(/liveness)?$") + } + + if basicAuthConfigured { + args = append(args, fmt.Sprintf("--htpasswd-file=%s/%s", "/var/run/secrets/operator.cryostat.io", *authOptions.BasicAuth.Filename)) + } + + if r.TLS { + args = append(args, + "--http-address=", + "--https-address=0.0.0.0:4180", + fmt.Sprintf("--tls-cert=/var/run/secrets/operator.cryostat.io/%s/%s", r.Name+"-tls", corev1.TLSCertKey), + fmt.Sprintf("--tls-key=/var/run/secrets/operator.cryostat.io/%s/%s", r.Name+"-tls", corev1.TLSPrivateKeyKey), + ) + } else { + args = append(args, + "--http-address=0.0.0.0:4180", + "--https-address=", + ) + } + return args, nil +} + func (r *TestResources) NewCoreVolumeMounts() []corev1.VolumeMount { mounts := []corev1.VolumeMount{ { @@ -1677,7 +1757,7 @@ func (r *TestResources) NewDatabaseVolumeMounts() []corev1.VolumeMount { } } -func (r *TestResources) NewAuthProxyVolumeMounts(basicAuthConfigured bool) []corev1.VolumeMount { +func (r *TestResources) NewAuthProxyVolumeMounts(authOptions *operatorv1beta2.AuthorizationOptions) []corev1.VolumeMount { mounts := []corev1.VolumeMount{} if r.TLS { mounts = append(mounts, corev1.VolumeMount{ @@ -1687,6 +1767,8 @@ func (r *TestResources) NewAuthProxyVolumeMounts(basicAuthConfigured bool) []cor }) } + basicAuthConfigured := authOptions != nil && authOptions.BasicAuth != nil && + authOptions.BasicAuth.Filename != nil && authOptions.BasicAuth.SecretName != nil if basicAuthConfigured { mounts = append(mounts, corev1.VolumeMount{ Name: r.Name + "-auth-proxy-htpasswd", From 5a7c4c33480070a3a7d3be8aa3336acc7afbc657 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Wed, 5 Jun 2024 15:08:23 -0400 Subject: [PATCH 48/53] test(proxy): add missing args to proxy expectations (#845) --- internal/test/resources.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/test/resources.go b/internal/test/resources.go index 76d691b55..1f0e45b65 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1671,6 +1671,9 @@ func (r *TestResources) NewAuthProxyArguments(authOptions *operatorv1beta2.Autho } args := []string{ + "--pass-access-token=false", + "--pass-user-bearer-token=false", + "--pass-basic-auth=false", "--upstream=http://localhost:8181/", "--upstream=http://localhost:3000/grafana/", "--upstream=http://localhost:8333/storage/", From 7025c66888670d6ad7120ed8b6bf4bd73a7fa9b4 Mon Sep 17 00:00:00 2001 From: Ming Yu Wang <90855268+mwangggg@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:41:13 -0400 Subject: [PATCH 49/53] replace v1beta1 resources (#847) --- .../resource_definitions.go | 4 +-- internal/controllers/reconciler.go | 34 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index ef1cb1dcf..c544d0ea0 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -22,7 +22,7 @@ import ( "strconv" "strings" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" common "github.com/cryostatio/cryostat-operator/internal/controllers/common" "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/controllers/model" @@ -278,7 +278,7 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima if secret.CertificateKey != nil { key = *secret.CertificateKey } else { - key = operatorv1beta1.DefaultCertificateKey + key = operatorv1beta2.DefaultCertificateKey } source := corev1.VolumeProjection{ Secret: &corev1.SecretProjection{ diff --git a/internal/controllers/reconciler.go b/internal/controllers/reconciler.go index d83eb368d..8f4fd66a6 100644 --- a/internal/controllers/reconciler.go +++ b/internal/controllers/reconciler.go @@ -24,7 +24,7 @@ import ( "time" certv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - operatorv1beta1 "github.com/cryostatio/cryostat-operator/api/v1beta1" + operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" common "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" @@ -121,17 +121,17 @@ const ( ) // Map Cryostat conditions to deployment conditions -type deploymentConditionTypeMap map[operatorv1beta1.CryostatConditionType]appsv1.DeploymentConditionType +type deploymentConditionTypeMap map[operatorv1beta2.CryostatConditionType]appsv1.DeploymentConditionType var mainDeploymentConditions = deploymentConditionTypeMap{ - operatorv1beta1.ConditionTypeMainDeploymentAvailable: appsv1.DeploymentAvailable, - operatorv1beta1.ConditionTypeMainDeploymentProgressing: appsv1.DeploymentProgressing, - operatorv1beta1.ConditionTypeMainDeploymentReplicaFailure: appsv1.DeploymentReplicaFailure, + operatorv1beta2.ConditionTypeMainDeploymentAvailable: appsv1.DeploymentAvailable, + operatorv1beta2.ConditionTypeMainDeploymentProgressing: appsv1.DeploymentProgressing, + operatorv1beta2.ConditionTypeMainDeploymentReplicaFailure: appsv1.DeploymentReplicaFailure, } var reportsDeploymentConditions = deploymentConditionTypeMap{ - operatorv1beta1.ConditionTypeReportsDeploymentAvailable: appsv1.DeploymentAvailable, - operatorv1beta1.ConditionTypeReportsDeploymentProgressing: appsv1.DeploymentProgressing, - operatorv1beta1.ConditionTypeReportsDeploymentReplicaFailure: appsv1.DeploymentReplicaFailure, + operatorv1beta2.ConditionTypeReportsDeploymentAvailable: appsv1.DeploymentAvailable, + operatorv1beta2.ConditionTypeReportsDeploymentProgressing: appsv1.DeploymentProgressing, + operatorv1beta2.ConditionTypeReportsDeploymentReplicaFailure: appsv1.DeploymentReplicaFailure, } func newReconciler(config *ReconcilerConfig, objType client.Object, isNamespaced bool) (*Reconciler, error) { @@ -217,7 +217,7 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn tlsConfig, err = r.setupTLS(ctx, cr) if err != nil { if err == common.ErrCertNotReady { - condErr := r.updateCondition(ctx, cr, operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionFalse, + condErr := r.updateCondition(ctx, cr, operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionFalse, reasonWaitingForCert, "Waiting for certificates to become ready.") if condErr != nil { return reconcile.Result{}, err @@ -225,20 +225,20 @@ func (r *Reconciler) reconcileCryostat(ctx context.Context, cr *model.CryostatIn return reconcile.Result{RequeueAfter: 5 * time.Second}, nil } if err == errCertManagerMissing { - r.updateCondition(ctx, cr, operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionFalse, + r.updateCondition(ctx, cr, operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionFalse, reasonCertManagerUnavailable, eventCertManagerUnavailableMsg) } reqLogger.Error(err, "Failed to set up TLS for Cryostat") return reconcile.Result{}, err } - err = r.updateCondition(ctx, cr, operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, + err = r.updateCondition(ctx, cr, operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, reasonAllCertsReady, "All certificates for Cryostat components are ready.") if err != nil { return reconcile.Result{}, err } } else { - err = r.updateCondition(ctx, cr, operatorv1beta1.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, + err = r.updateCondition(ctx, cr, operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, reasonCertManagerDisabled, "TLS setup has been disabled.") if err != nil { return reconcile.Result{}, err @@ -346,9 +346,9 @@ func (r *Reconciler) reconcileReports(ctx context.Context, reqLogger logr.Logger return reconcile.Result{}, err } - removeConditionIfPresent(cr, operatorv1beta1.ConditionTypeReportsDeploymentAvailable, - operatorv1beta1.ConditionTypeReportsDeploymentProgressing, - operatorv1beta1.ConditionTypeReportsDeploymentReplicaFailure) + removeConditionIfPresent(cr, operatorv1beta2.ConditionTypeReportsDeploymentAvailable, + operatorv1beta2.ConditionTypeReportsDeploymentProgressing, + operatorv1beta2.ConditionTypeReportsDeploymentReplicaFailure) err := r.Client.Status().Update(ctx, cr.Object) if err != nil { return reconcile.Result{}, err @@ -429,7 +429,7 @@ func parseSupGroups(supGroups string) (*int64, error) { } func (r *Reconciler) updateCondition(ctx context.Context, cr *model.CryostatInstance, - condType operatorv1beta1.CryostatConditionType, status metav1.ConditionStatus, reason string, message string) error { + condType operatorv1beta2.CryostatConditionType, status metav1.ConditionStatus, reason string, message string) error { reqLogger := r.Log.WithValues("Request.Namespace", cr.InstallNamespace, "Request.Name", cr.Name) meta.SetStatusCondition(&cr.Status.Conditions, metav1.Condition{ Type: string(condType), @@ -541,7 +541,7 @@ func requeueIfIngressNotReady(log logr.Logger, err error) (reconcile.Result, err return reconcile.Result{}, err } -func removeConditionIfPresent(cr *model.CryostatInstance, condType ...operatorv1beta1.CryostatConditionType) { +func removeConditionIfPresent(cr *model.CryostatInstance, condType ...operatorv1beta2.CryostatConditionType) { for _, ct := range condType { found := meta.FindStatusCondition(cr.Status.Conditions, string(ct)) if found != nil { From e7b7afc7012454c97aca87013ec9869f246ee49d Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 5 Jun 2024 13:44:24 -0700 Subject: [PATCH 50/53] fix(scorecard): error when constructing request should be checked (#843) * fix(scorecard): error when constructing request should be checked Signed-off-by: Thuan Vo * chore(scorecard): better error message and avoid nil pointer --------- Signed-off-by: Thuan Vo --- internal/test/scorecard/clients.go | 20 +++++++++++++++++--- internal/test/scorecard/common_utils.go | 8 ++++---- internal/test/scorecard/tests.go | 4 ++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 781afd8ce..734a4e42f 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -149,6 +149,9 @@ func get[r runtime.Object](ctx context.Context, c rest.Interface, res string, ns if len(ns) > 0 { rq = rq.Namespace(ns) } + if err := rq.Error(); err != nil { + return result, err + } err := rq.Do(ctx).Into(result) return result, err } @@ -158,14 +161,22 @@ func create[r runtime.Object](ctx context.Context, c rest.Interface, res string, if len(ns) > 0 { rq = rq.Namespace(ns) } + if err := rq.Error(); err != nil { + return result, err + } err := rq.Do(ctx).Into(result) return result, err } func update[r runtime.Object](ctx context.Context, c rest.Interface, res string, ns string, obj r, result r, name string) (r, error) { - err := c.Put(). - Namespace(ns).Resource(res).Name(name). - Body(obj).Do(ctx).Into(result) + rq := c.Put().Resource(res).Name(name).Body(obj) + if len(ns) > 0 { + rq = rq.Namespace(ns) + } + if err := rq.Error(); err != nil { + return result, err + } + err := rq.Do(ctx).Into(result) return result, err } @@ -174,6 +185,9 @@ func delete(ctx context.Context, c rest.Interface, res string, ns string, name s if len(ns) > 0 { rq = rq.Namespace(ns) } + if err := rq.Error(); err != nil { + return err + } return rq.Do(ctx).Error() } diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index ae9c9254d..b3c45d4cb 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -331,7 +331,7 @@ func configureIngress(name string, cryostatSpec *operatorv1beta2.CryostatSpec) { func (r *TestResources) createAndWaitTillCryostatAvailable(cr *operatorv1beta2.Cryostat) (*operatorv1beta2.Cryostat, error) { cr, err := r.Client.OperatorCRDs().Cryostats(cr.Namespace).Create(context.Background(), cr) if err != nil { - r.logError(fmt.Sprintf("failed to create Cryostat CR: %s", err.Error())) + r.logError(fmt.Sprintf("failed to create Cryostat CR \"%s\": %s", cr.Name, err.Error())) return nil, err } @@ -347,7 +347,7 @@ func (r *TestResources) createAndWaitTillCryostatAvailable(cr *operatorv1beta2.C err = wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (done bool, err error) { cr, err = r.Client.OperatorCRDs().Cryostats(cr.Namespace).Get(ctx, cr.Name) if err != nil { - return false, fmt.Errorf("failed to get Cryostat CR: %s", err.Error()) + return false, fmt.Errorf("failed to get Cryostat CR \"%s\": %s", cr.Name, err.Error()) } if len(cr.Spec.TargetNamespaces) > 0 { if len(cr.Status.TargetNamespaces) == 0 { @@ -457,7 +457,7 @@ func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta2.C var err error cr, err = r.Client.OperatorCRDs().Cryostats(cr.Namespace).Get(ctx, cr.Name) if err != nil { - return fmt.Errorf("failed to get Cryostat CR: %s", err.Error()) + return fmt.Errorf("failed to get Cryostat CR \"%s\": %s", cr.Name, err.Error()) } cr.Spec.StorageOptions = &operatorv1beta2.StorageConfiguration{ @@ -477,7 +477,7 @@ func (r *TestResources) updateAndWaitTillCryostatAvailable(cr *operatorv1beta2.C return err }) if err != nil { - return nil, fmt.Errorf("failed to update Cryostat CR: %s", err.Error()) + return nil, fmt.Errorf("failed to update Cryostat CR \"%s\": %s", cr.Name, err.Error()) } // Poll the deployment until it becomes available or we timeout diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 16d74d763..55b90f899 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -116,7 +116,7 @@ func CryostatConfigChangeTest(bundle *apimanifests.Bundle, namespace string, ope }, } - _, err = r.createAndWaitTillCryostatAvailable(cr) + cr, err = r.createAndWaitTillCryostatAvailable(cr) if err != nil { return r.fail(fmt.Sprintf("failed to determine application URL: %s", err.Error())) } @@ -243,7 +243,7 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh return r.fail(fmt.Sprintf("failed to get the recordings: %s", err.Error())) } if rec.State != "STOPPED" { - return r.fail(fmt.Sprintf("recording %s failed to stop: %s", rec.Name, err.Error())) + return r.fail(fmt.Sprintf("expect recording %s to have state STOPPED but found %s", rec.Name, rec.State)) } r.Log += fmt.Sprintf("stopped the recording: %s\n", rec.Name) From 48128d13040afcc00ccdd19de2d704e1cd4531c7 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Wed, 5 Jun 2024 17:10:32 -0400 Subject: [PATCH 51/53] build(golang): build images with Go 1.22 (#850) * build(golang): build images with Go 1.22 * Add comment for go directive --- .github/workflows/test-ci-reusable.yml | 2 +- Dockerfile | 2 +- README.md | 2 +- go.mod | 1 + go.sum | 8 -------- internal/images/custom-scorecard-tests/Dockerfile | 2 +- 6 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test-ci-reusable.yml b/.github/workflows/test-ci-reusable.yml index bd24a7dbe..1566a5276 100644 --- a/.github/workflows/test-ci-reusable.yml +++ b/.github/workflows/test-ci-reusable.yml @@ -48,7 +48,7 @@ jobs: ref: ${{ inputs.ref }} - uses: actions/setup-go@v4 with: - go-version: '1.21.*' + go-version: '1.22.*' - name: Run controller tests run: make test-envtest - name: Set latest commit status as ${{ job.status }} diff --git a/Dockerfile b/Dockerfile index daee119a6..e54f0c79b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the manager binary -FROM docker.io/library/golang:1.21 as builder +FROM docker.io/library/golang:1.22 as builder ARG TARGETOS ARG TARGETARCH diff --git a/README.md b/README.md index 936e5fc5d..92e33ad13 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ the need to expose a JMX port over the network. # Building ## Requirements -- `go` v1.21 +- `go` v1.21+ - [`operator-sdk`](https://github.com/operator-framework/operator-sdk) v1.31.0 - [`cert-manager`](https://github.com/cert-manager/cert-manager) v1.11.5+ (Recommended) - `podman` or `docker` diff --git a/go.mod b/go.mod index 315b827e3..29d6101b6 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,6 @@ module github.com/cryostatio/cryostat-operator +// Increment to go 1.22 once downstream is compatible go 1.21 require ( diff --git a/go.sum b/go.sum index d45e6d30d..385cde0b4 100644 --- a/go.sum +++ b/go.sum @@ -126,24 +126,16 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ 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 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.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/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.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 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= diff --git a/internal/images/custom-scorecard-tests/Dockerfile b/internal/images/custom-scorecard-tests/Dockerfile index 2dc8ec4dd..0f9110bc5 100644 --- a/internal/images/custom-scorecard-tests/Dockerfile +++ b/internal/images/custom-scorecard-tests/Dockerfile @@ -13,7 +13,7 @@ # limitations under the License. # Build the manager binary -FROM docker.io/library/golang:1.21 as builder +FROM docker.io/library/golang:1.22 as builder ARG TARGETOS ARG TARGETARCH From eba4fb21218da1be7126f2f089a1c65564d4d2e7 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 5 Jun 2024 14:28:16 -0700 Subject: [PATCH 52/53] fix(crd): restrict database secret name to be immutable (#831) * fix(database): emit an Event when database secret is mismatched Signed-off-by: Thuan Vo * fix(secret): mark generated db secret as immutable * docs(crd): more details on immutable secrets * docs(crd): fix typo in crd markers * docs(readme): mention min k8s version in README * docs(readme): re-organize readme * fix(secret): ensure secret is immutable in createOrUpdate --------- Signed-off-by: Thuan Vo --- README.md | 9 +++- api/v1beta2/cryostat_types.go | 4 +- ...yostat-operator.clusterserviceversion.yaml | 7 ++- .../operator.cryostat.io_cryostats.yaml | 7 ++- .../bases/operator.cryostat.io_cryostats.yaml | 7 ++- ...yostat-operator.clusterserviceversion.yaml | 5 ++- internal/controllers/reconciler_test.go | 1 + internal/controllers/secrets.go | 45 ++++++++++++------- internal/test/resources.go | 1 + 9 files changed, 62 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 92e33ad13..af4ed12b5 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,14 @@ the JFR datasource for Grafana. for the Grafana dashboard. # Using + +## Requirements + +- `kubernetes` v1.21+ with [`Operator Lifecycle Manager`](https://olm.operatorframework.io/) +- [`cert-manager`](https://github.com/cert-manager/cert-manager) v1.11.5+ (Recommended) + +## Instructions + Once deployed, the `cryostat` instance can be accessed via web browser at the URL provided by: ``` @@ -41,7 +49,6 @@ the need to expose a JMX port over the network. ## Requirements - `go` v1.21+ - [`operator-sdk`](https://github.com/operator-framework/operator-sdk) v1.31.0 -- [`cert-manager`](https://github.com/cert-manager/cert-manager) v1.11.5+ (Recommended) - `podman` or `docker` - [`jq`](https://stedolan.github.io/jq/) v1.6+ - `ginkgo` (Optional) diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index e87fa0798..ff826ce15 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -603,7 +603,9 @@ type TargetDiscoveryOptions struct { type DatabaseOptions struct { // Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the // database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data - // stored within the database, such as the target credentials keyring. + // stored within the database, such as the target credentials keyring. This field cannot be updated. + // It is recommended that the secret should be marked as immutable to avoid accidental changes to secret's data. + // More details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} SecretName *string `json:"secretName,omitempty"` diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 12aee9bfb..ce14a503f 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-28T20:14:14Z" + createdAt: "2024-05-31T05:27:37Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -576,10 +576,13 @@ spec: - description: Options to configure the Cryostat application's database. displayName: Database Options path: databaseOptions - - description: Name of the secret containing database keys. This secret must + - description: 'Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data stored within the database, such as the target credentials keyring. + This field cannot be updated. It is recommended that the secret should be + marked as immutable to avoid accidental changes to secret''s data. More + details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable' displayName: Secret Name path: databaseOptions.secretName x-descriptors: diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index abe2529f6..baa6f92a9 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -5208,11 +5208,14 @@ spec: description: Options to configure the Cryostat application's database. properties: secretName: - description: Name of the secret containing database keys. This + description: 'Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data stored within the database, - such as the target credentials keyring. + such as the target credentials keyring. This field cannot be + updated. It is recommended that the secret should be marked + as immutable to avoid accidental changes to secret''s data. + More details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable' type: string type: object enableCertManager: diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index c8bb0ddd1..63a11693b 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -5198,11 +5198,14 @@ spec: description: Options to configure the Cryostat application's database. properties: secretName: - description: Name of the secret containing database keys. This + description: 'Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data stored within the database, - such as the target credentials keyring. + such as the target credentials keyring. This field cannot be + updated. It is recommended that the secret should be marked + as immutable to avoid accidental changes to secret''s data. + More details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable' type: string type: object enableCertManager: diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 2ac7fd2c3..72316d39d 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -121,10 +121,13 @@ spec: - description: Options to configure the Cryostat application's database. displayName: Database Options path: databaseOptions - - description: Name of the secret containing database keys. This secret must + - description: 'Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data stored within the database, such as the target credentials keyring. + This field cannot be updated. It is recommended that the secret should be + marked as immutable to avoid accidental changes to secret''s data. More + details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable' displayName: Secret Name path: databaseOptions.secretName x-descriptors: diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index ecdef0fd4..c622fd481 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -2352,6 +2352,7 @@ func (t *cryostatTestInput) expectDatabaseSecret() { expectedSecret := t.NewDatabaseSecret() t.checkMetadata(secret, expectedSecret) Expect(secret.StringData).To(Equal(expectedSecret.StringData)) + Expect(secret.Immutable).To(Equal(expectedSecret.Immutable)) } func (t *cryostatTestInput) expectStorageSecret() { diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index b2519c0b0..d0074754b 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -16,12 +16,13 @@ package controllers import ( "context" + "errors" "fmt" "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/controllers/model" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" + kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) @@ -57,23 +58,35 @@ func (r *Reconciler) reconcileAuthProxyCookieSecret(ctx context.Context, cr *mod }) } -// databaseSecretNameSuffix is the suffix to be appended to the name of a -// Cryostat CR to name its database secret -const databaseSecretNameSuffix = "-db" +const ( + // The suffix to be appended to the name of a Cryostat CR to name its database secret + databaseSecretNameSuffix = "-db" + eventDatabaseSecretMismatchedType = "DatabaseSecretMismatched" + eventDatabaseMismatchMsg = "\"databaseOptions.secretName\" field cannot be updated, please revert its value or re-create this Cryostat custom resource" +) + +var errDatabaseSecretUpdated = errors.New("database secret cannot be updated, but another secret is specified") func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr *model.CryostatInstance) error { - var secretName string + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: cr.Name + databaseSecretNameSuffix, + Namespace: cr.InstallNamespace, + }, + } + secretName := secret.Name secretProvided := cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil if secretProvided { - // Do not delete default secret to allow reverting to use default if needed secretName = *cr.Spec.DatabaseOptions.SecretName - } else { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + databaseSecretNameSuffix, - Namespace: cr.InstallNamespace, - }, - } + } + + // If the CR status contains the secret name, emit an Event in case the configured secret's name does not match. + if len(cr.Status.DatabaseSecret) > 0 && cr.Status.DatabaseSecret != secretName { + r.EventRecorder.Event(cr.Object, corev1.EventTypeWarning, eventDatabaseSecretMismatchedType, eventDatabaseMismatchMsg) + return errDatabaseSecretUpdated + } + + if !secretProvided { err := r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { if secret.StringData == nil { secret.StringData = map[string]string{} @@ -84,14 +97,16 @@ func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr * secret.StringData[constants.DatabaseSecretConnectionKey] = r.GenPasswd(32) secret.StringData[constants.DatabaseSecretEncryptionKey] = r.GenPasswd(32) } + + secret.Immutable = &[]bool{true}[0] return nil }) if err != nil { return err } - secretName = secret.Name } + cr.Status.DatabaseSecret = secretName return r.Client.Status().Update(ctx, cr.Object) } @@ -150,7 +165,7 @@ func (r *Reconciler) createOrUpdateSecret(ctx context.Context, secret *corev1.Se func (r *Reconciler) deleteSecret(ctx context.Context, secret *corev1.Secret) error { err := r.Client.Delete(ctx, secret) - if err != nil && !errors.IsNotFound(err) { + if err != nil && !kerrors.IsNotFound(err) { r.Log.Error(err, "Could not delete secret", "name", secret.Name, "namespace", secret.Namespace) return err } diff --git a/internal/test/resources.go b/internal/test/resources.go index 1f0e45b65..1164a0445 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -852,6 +852,7 @@ func (r *TestResources) NewDatabaseSecret() *corev1.Secret { "CONNECTION_KEY": "connection_key", "ENCRYPTION_KEY": "encryption_key", }, + Immutable: &[]bool{true}[0], } } From 1be75e984b69cf99020124d22376ca9995d524fc Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 6 Jun 2024 11:47:50 -0700 Subject: [PATCH 53/53] build(deps): bump controller-tools version to 0.14.0 (#851) Signed-off-by: Thuan Vo --- Makefile | 2 +- api/v1beta1/zz_generated.deepcopy.go | 1 - api/v1beta2/zz_generated.deepcopy.go | 1 - ...yostat-operator.clusterserviceversion.yaml | 2 +- .../operator.cryostat.io_cryostats.yaml | 8792 ++++++++-------- .../bases/operator.cryostat.io_cryostats.yaml | 8793 ++++++++--------- config/rbac/role.yaml | 2 - config/webhook/manifests.yaml | 2 - 8 files changed, 8322 insertions(+), 9273 deletions(-) diff --git a/Makefile b/Makefile index 34f491345..bca35eca8 100644 --- a/Makefile +++ b/Makefile @@ -98,7 +98,7 @@ CERT_MANAGER_MANIFEST ?= \ https://github.com/cert-manager/cert-manager/releases/download/v$(CERT_MANAGER_VERSION)/cert-manager.yaml KUSTOMIZE_VERSION ?= 3.8.7 -CONTROLLER_TOOLS_VERSION ?= 0.11.1 +CONTROLLER_TOOLS_VERSION ?= 0.14.0 GOLICENSE_VERSION ?= 1.29.0 OPM_VERSION ?= 1.23.0 # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 7863ae29e..172b48e9e 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Copyright The Cryostat Authors. // diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 57b4fc8a7..426d2639d 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Copyright The Cryostat Authors. // diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index ce14a503f..59f9000af 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-31T05:27:37Z" + createdAt: "2024-06-05T22:02:01Z" 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 baa6f92a9..431ee6834 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -3,7 +3,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: cryostat-operator-system/cryostat-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.11.1 + controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null name: cryostats.operator.cryostat.io spec: @@ -35,20 +35,27 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: Cryostat allows you to install Cryostat for a single namespace. - It contains configuration options for controlling the Deployment of the - Cryostat application and its related components. A Cryostat instance must - be created to instruct the operator to deploy the Cryostat application. + description: |- + Cryostat allows you to install Cryostat for a single namespace. + It contains configuration options for controlling the Deployment of the Cryostat + application and its related components. + A Cryostat instance must be created to instruct the operator + to deploy the Cryostat application. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -60,10 +67,10 @@ spec: on OpenShift. properties: clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + description: |- + Name of the ClusterRole to use when Cryostat requests a role-scoped OAuth token. + This ClusterRole should contain permissions for all Kubernetes objects listed in custom permission mapping. + More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth type: string configMapName: description: Name of config map in the local namespace. @@ -78,8 +85,9 @@ spec: - filename type: object enableCertManager: - description: Use cert-manager to secure in-cluster communication between - Cryostat components. Requires cert-manager to be installed. + description: |- + Use cert-manager to secure in-cluster communication between Cryostat components. + Requires cert-manager to be installed. type: boolean eventTemplates: description: List of Flight Recorder Event Templates to preconfigure @@ -137,13 +145,17 @@ spec: Dashboard or JFR Data Source. type: boolean networkOptions: - description: Options to control how the operator exposes the application - outside of the cluster, such as using an Ingress or Route. + description: |- + Options to control how the operator exposes the application outside of the cluster, + such as using an Ingress or Route. properties: commandConfig: - description: "Specifications for how to expose the Cryostat command - service, which serves the WebSocket command channel. \n Deprecated: - CommandConfig is no longer used." + description: |- + Specifications for how to expose the Cryostat command service, + which serves the WebSocket command channel. + + + Deprecated: CommandConfig is no longer used. properties: annotations: additionalProperties: @@ -152,32 +164,30 @@ spec: its creation. type: object ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. + description: |- + Configuration for an Ingress object. + Currently subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate between ingresses/services. properties: defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. + description: |- + defaultBackend is the backend that should handle requests that don't + match any rule. If Rules are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests that do not match any + of the rules will be up to the Ingress controller. properties: resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type of resource being @@ -193,27 +203,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a service as a backend. + description: |- + service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -222,100 +234,92 @@ spec: type: object type: object ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. + description: |- + ingressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource, by a transitive connection + (controller -> IngressClass -> Ingress resource). Although the + `kubernetes.io/ingress.class` annotation (simple constant name) was never + formally defined, it was widely supported by Ingress controllers to create + a direct binding between Ingress controller and Ingress resources. Newly + created Ingress resources should prefer using the field. However, even + though the annotation is officially deprecated, for backwards compatibility + reasons, ingress controllers should still honor that annotation if present. type: string rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. + description: |- + rules is a list of host rules used to configure the Ingress. If unspecified, + or no rule matches, all traffic is sent to the default backend. items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. + description: |- + IngressRule represents the rules mapping the paths under a specified host to + the related backend services. Incoming requests are first evaluated for a host + match, then routed to the backend associated with the matching IngressRuleValue. properties: host: description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." + name of a network host, as defined by RFC 3986.\nNote + the following deviations from the \"host\" part + of the\nURI as defined in RFC 3986:\n1. IPs are + not allowed. Currently an IngressRuleValue can + only apply to\n the IP in the Spec of the parent + Ingress.\n2. The `:` delimiter is not respected + because ports are not allowed.\n\t Currently + the port of an Ingress is implicitly :80 for http + and\n\t :443 for https.\nBoth these may change + in the future.\nIncoming requests are matched + against the host before the\nIngressRuleValue. + If the host is unspecified, the Ingress routes + all\ntraffic based on the specified IngressRuleValue.\n\n\nhost + can be \"precise\" which is a domain name without + the terminating dot of\na network host (e.g. \"foo.bar.com\") + or \"wildcard\", which is a domain name\nprefixed + with a single wildcard label (e.g. \"*.foo.com\").\nThe + wildcard character '*' must appear by itself as + the first DNS label and\nmatches only a single + label. You cannot have a wildcard label by itself + (e.g. Host == \"*\").\nRequests will be matched + against the Host field in the following way:\n1. + If host is precise, the request matches this rule + if the http host header is equal to Host.\n2. + If host is a wildcard, then the request matches + this rule if the http host header\nis to equal + to the suffix (removing the first label) of the + wildcard rule." type: string http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' + description: |- + HTTPIngressRuleValue is a list of http selectors pointing to backends. + In the example: http:///? -> backend where + where parts of the url correspond to RFC 3986, this resource will be used + to match against everything after the last '/' and before the first '?' + or '#'. properties: paths: description: paths is a collection of paths that map requests to backends. items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. + description: |- + HTTPIngressPath associates a path with a backend. Incoming urls matching the + path are forwarded to the backend. properties: backend: - description: backend defines the referenced - service endpoint to which the traffic + description: |- + backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type @@ -331,34 +335,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". + description: |- + service references a service as a backend. + This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -367,39 +366,28 @@ spec: type: object type: object path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". + description: |- + path is matched against the path of an incoming request. Currently it can + contain characters disallowed from the conventional "path" part of a URL + as defined by RFC 3986. Paths must begin with a '/' and must be present + when using PathType with value "Exact" or "Prefix". type: string pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' + description: |- + pathType determines the interpretation of the path matching. PathType can + be one of the following values: + * Exact: Matches the URL path exactly. + * Prefix: Matches based on a URL path prefix split by '/'. Matching is + done on a path element by element basis. A path element refers is the + list of labels in the path split by the '/' separator. A request is a + match for path p if every p is an element-wise prefix of p of the + request path. Note that if the last element of the path is a substring + of the last element in request path, it is not a match (e.g. /foo/bar + matches /foo/bar/baz, but does not match /foo/barbaz). + * ImplementationSpecific: Interpretation of the Path matching is up to + the IngressClass. Implementations can treat this as a separate PathType + or treat it identically to Prefix or Exact path types. + Implementations are required to support all path types. type: string required: - backend @@ -414,34 +402,32 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. + description: |- + tls represents the TLS configuration. Currently the Ingress only supports a + single TLS port, 443. If multiple members of this list specify different hosts, + they will be multiplexed on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller fulfilling the + ingress supports SNI. items: description: IngressTLS describes the transport layer security associated with an ingress. properties: hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. items: type: string type: array x-kubernetes-list-type: atomic secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination and value of the "Host" header is used for routing. type: string type: object @@ -451,13 +437,14 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. + description: |- + Labels to add to the Ingress or Route during its creation. + The label with key "app" is reserved for use by the operator. type: object type: object coreConfig: - description: Specifications for how to expose the Cryostat service, + description: |- + Specifications for how to expose the Cryostat service, which serves the Cryostat application. properties: annotations: @@ -467,32 +454,30 @@ spec: its creation. type: object ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. + description: |- + Configuration for an Ingress object. + Currently subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate between ingresses/services. properties: defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. + description: |- + defaultBackend is the backend that should handle requests that don't + match any rule. If Rules are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests that do not match any + of the rules will be up to the Ingress controller. properties: resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type of resource being @@ -508,27 +493,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a service as a backend. + description: |- + service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -537,100 +524,92 @@ spec: type: object type: object ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. + description: |- + ingressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource, by a transitive connection + (controller -> IngressClass -> Ingress resource). Although the + `kubernetes.io/ingress.class` annotation (simple constant name) was never + formally defined, it was widely supported by Ingress controllers to create + a direct binding between Ingress controller and Ingress resources. Newly + created Ingress resources should prefer using the field. However, even + though the annotation is officially deprecated, for backwards compatibility + reasons, ingress controllers should still honor that annotation if present. type: string rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. + description: |- + rules is a list of host rules used to configure the Ingress. If unspecified, + or no rule matches, all traffic is sent to the default backend. items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. + description: |- + IngressRule represents the rules mapping the paths under a specified host to + the related backend services. Incoming requests are first evaluated for a host + match, then routed to the backend associated with the matching IngressRuleValue. properties: host: description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." + name of a network host, as defined by RFC 3986.\nNote + the following deviations from the \"host\" part + of the\nURI as defined in RFC 3986:\n1. IPs are + not allowed. Currently an IngressRuleValue can + only apply to\n the IP in the Spec of the parent + Ingress.\n2. The `:` delimiter is not respected + because ports are not allowed.\n\t Currently + the port of an Ingress is implicitly :80 for http + and\n\t :443 for https.\nBoth these may change + in the future.\nIncoming requests are matched + against the host before the\nIngressRuleValue. + If the host is unspecified, the Ingress routes + all\ntraffic based on the specified IngressRuleValue.\n\n\nhost + can be \"precise\" which is a domain name without + the terminating dot of\na network host (e.g. \"foo.bar.com\") + or \"wildcard\", which is a domain name\nprefixed + with a single wildcard label (e.g. \"*.foo.com\").\nThe + wildcard character '*' must appear by itself as + the first DNS label and\nmatches only a single + label. You cannot have a wildcard label by itself + (e.g. Host == \"*\").\nRequests will be matched + against the Host field in the following way:\n1. + If host is precise, the request matches this rule + if the http host header is equal to Host.\n2. + If host is a wildcard, then the request matches + this rule if the http host header\nis to equal + to the suffix (removing the first label) of the + wildcard rule." type: string http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' + description: |- + HTTPIngressRuleValue is a list of http selectors pointing to backends. + In the example: http:///? -> backend where + where parts of the url correspond to RFC 3986, this resource will be used + to match against everything after the last '/' and before the first '?' + or '#'. properties: paths: description: paths is a collection of paths that map requests to backends. items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. + description: |- + HTTPIngressPath associates a path with a backend. Incoming urls matching the + path are forwarded to the backend. properties: backend: - description: backend defines the referenced - service endpoint to which the traffic + description: |- + backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type @@ -646,34 +625,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". + description: |- + service references a service as a backend. + This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -682,39 +656,28 @@ spec: type: object type: object path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". + description: |- + path is matched against the path of an incoming request. Currently it can + contain characters disallowed from the conventional "path" part of a URL + as defined by RFC 3986. Paths must begin with a '/' and must be present + when using PathType with value "Exact" or "Prefix". type: string pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' + description: |- + pathType determines the interpretation of the path matching. PathType can + be one of the following values: + * Exact: Matches the URL path exactly. + * Prefix: Matches based on a URL path prefix split by '/'. Matching is + done on a path element by element basis. A path element refers is the + list of labels in the path split by the '/' separator. A request is a + match for path p if every p is an element-wise prefix of p of the + request path. Note that if the last element of the path is a substring + of the last element in request path, it is not a match (e.g. /foo/bar + matches /foo/bar/baz, but does not match /foo/barbaz). + * ImplementationSpecific: Interpretation of the Path matching is up to + the IngressClass. Implementations can treat this as a separate PathType + or treat it identically to Prefix or Exact path types. + Implementations are required to support all path types. type: string required: - backend @@ -729,34 +692,32 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. + description: |- + tls represents the TLS configuration. Currently the Ingress only supports a + single TLS port, 443. If multiple members of this list specify different hosts, + they will be multiplexed on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller fulfilling the + ingress supports SNI. items: description: IngressTLS describes the transport layer security associated with an ingress. properties: hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. items: type: string type: array x-kubernetes-list-type: atomic secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination and value of the "Host" header is used for routing. type: string type: object @@ -766,14 +727,15 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. + description: |- + Labels to add to the Ingress or Route during its creation. + The label with key "app" is reserved for use by the operator. type: object type: object grafanaConfig: - description: Specifications for how to expose Cryostat's Grafana - service, which serves the Grafana dashboard. + description: |- + Specifications for how to expose Cryostat's Grafana service, + which serves the Grafana dashboard. properties: annotations: additionalProperties: @@ -782,32 +744,30 @@ spec: its creation. type: object ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. + description: |- + Configuration for an Ingress object. + Currently subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate between ingresses/services. properties: defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. + description: |- + defaultBackend is the backend that should handle requests that don't + match any rule. If Rules are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests that do not match any + of the rules will be up to the Ingress controller. properties: resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type of resource being @@ -823,27 +783,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a service as a backend. + description: |- + service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -852,100 +814,92 @@ spec: type: object type: object ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. + description: |- + ingressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource, by a transitive connection + (controller -> IngressClass -> Ingress resource). Although the + `kubernetes.io/ingress.class` annotation (simple constant name) was never + formally defined, it was widely supported by Ingress controllers to create + a direct binding between Ingress controller and Ingress resources. Newly + created Ingress resources should prefer using the field. However, even + though the annotation is officially deprecated, for backwards compatibility + reasons, ingress controllers should still honor that annotation if present. type: string rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. + description: |- + rules is a list of host rules used to configure the Ingress. If unspecified, + or no rule matches, all traffic is sent to the default backend. items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. + description: |- + IngressRule represents the rules mapping the paths under a specified host to + the related backend services. Incoming requests are first evaluated for a host + match, then routed to the backend associated with the matching IngressRuleValue. properties: host: description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." + name of a network host, as defined by RFC 3986.\nNote + the following deviations from the \"host\" part + of the\nURI as defined in RFC 3986:\n1. IPs are + not allowed. Currently an IngressRuleValue can + only apply to\n the IP in the Spec of the parent + Ingress.\n2. The `:` delimiter is not respected + because ports are not allowed.\n\t Currently + the port of an Ingress is implicitly :80 for http + and\n\t :443 for https.\nBoth these may change + in the future.\nIncoming requests are matched + against the host before the\nIngressRuleValue. + If the host is unspecified, the Ingress routes + all\ntraffic based on the specified IngressRuleValue.\n\n\nhost + can be \"precise\" which is a domain name without + the terminating dot of\na network host (e.g. \"foo.bar.com\") + or \"wildcard\", which is a domain name\nprefixed + with a single wildcard label (e.g. \"*.foo.com\").\nThe + wildcard character '*' must appear by itself as + the first DNS label and\nmatches only a single + label. You cannot have a wildcard label by itself + (e.g. Host == \"*\").\nRequests will be matched + against the Host field in the following way:\n1. + If host is precise, the request matches this rule + if the http host header is equal to Host.\n2. + If host is a wildcard, then the request matches + this rule if the http host header\nis to equal + to the suffix (removing the first label) of the + wildcard rule." type: string http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' + description: |- + HTTPIngressRuleValue is a list of http selectors pointing to backends. + In the example: http:///? -> backend where + where parts of the url correspond to RFC 3986, this resource will be used + to match against everything after the last '/' and before the first '?' + or '#'. properties: paths: description: paths is a collection of paths that map requests to backends. items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. + description: |- + HTTPIngressPath associates a path with a backend. Incoming urls matching the + path are forwarded to the backend. properties: backend: - description: backend defines the referenced - service endpoint to which the traffic + description: |- + backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type @@ -961,34 +915,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". + description: |- + service references a service as a backend. + This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -997,39 +946,28 @@ spec: type: object type: object path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". + description: |- + path is matched against the path of an incoming request. Currently it can + contain characters disallowed from the conventional "path" part of a URL + as defined by RFC 3986. Paths must begin with a '/' and must be present + when using PathType with value "Exact" or "Prefix". type: string pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' + description: |- + pathType determines the interpretation of the path matching. PathType can + be one of the following values: + * Exact: Matches the URL path exactly. + * Prefix: Matches based on a URL path prefix split by '/'. Matching is + done on a path element by element basis. A path element refers is the + list of labels in the path split by the '/' separator. A request is a + match for path p if every p is an element-wise prefix of p of the + request path. Note that if the last element of the path is a substring + of the last element in request path, it is not a match (e.g. /foo/bar + matches /foo/bar/baz, but does not match /foo/barbaz). + * ImplementationSpecific: Interpretation of the Path matching is up to + the IngressClass. Implementations can treat this as a separate PathType + or treat it identically to Prefix or Exact path types. + Implementations are required to support all path types. type: string required: - backend @@ -1044,34 +982,32 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. + description: |- + tls represents the TLS configuration. Currently the Ingress only supports a + single TLS port, 443. If multiple members of this list specify different hosts, + they will be multiplexed on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller fulfilling the + ingress supports SNI. items: description: IngressTLS describes the transport layer security associated with an ingress. properties: hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. items: type: string type: array x-kubernetes-list-type: atomic secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination and value of the "Host" header is used for routing. type: string type: object @@ -1081,9 +1017,9 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. + description: |- + Labels to add to the Ingress or Route during its creation. + The label with key "app" is reserved for use by the operator. type: object type: object type: object @@ -1103,7 +1039,8 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the resources during its creation. + description: |- + Labels to add to the resources during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -1120,7 +1057,8 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the resources during its creation. + description: |- + Labels to add to the resources during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -1130,30 +1068,35 @@ spec: description: Options to configure Cryostat Automated Report Analysis. properties: replicas: - description: The number of report sidecar replica containers to - deploy. Each replica can service one report generation request - at a time. + description: |- + The number of report sidecar replica containers to deploy. + Each replica can service one report generation request at a time. format: int32 type: integer resources: - description: The resources allocated to each sidecar replica. - A replica with more resources can handle larger input recordings - and will process them faster. + description: |- + The resources allocated to each sidecar replica. + A replica with more resources can handle larger input recordings and will process them faster. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -1169,8 +1112,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1179,11 +1123,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object schedulingOptions: @@ -1197,23 +1141,20 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling term - matches all objects with implicit weight 0 (i.e. - it's a no-op). A null preferred scheduling term - matches no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -1223,32 +1164,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1261,32 +1196,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1309,53 +1238,46 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to an update), the system may or may not try - to eventually evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1368,32 +1290,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1415,19 +1331,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1446,10 +1359,9 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1457,20 +1369,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1482,36 +1390,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1519,20 +1420,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1544,46 +1441,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -1592,25 +1480,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to a pod label update), the system may or may - not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -1621,30 +1506,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1656,53 +1536,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1714,34 +1586,28 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: @@ -1754,19 +1620,16 @@ spec: Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to - the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1785,10 +1648,9 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1796,20 +1658,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1821,36 +1679,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1858,20 +1709,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1883,46 +1730,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -1931,25 +1769,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - anti-affinity requirements specified by this field - cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may - or may not try to eventually evict the pod from - its node. When there are multiple elements, the - lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -1960,30 +1795,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1995,53 +1825,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2053,34 +1875,28 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: @@ -2099,42 +1915,39 @@ spec: description: 'Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period - of time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the value should - be empty, otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -2148,66 +1961,68 @@ spec: generator pod. properties: fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow - the Kubelet to change the ownership of that volume to - be owned by the pod: \n 1. The owning GID will be the - FSGroup 2. The setgid bit is set (new files created - in the volume will be owned by FSGroup) 3. The permission - bits are OR'd with rw-rw---- \n If unset, the Kubelet - will not modify the ownership and permissions of any - volume. Note that this field cannot be set when spec.os.name - is windows." + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of - changing ownership and permission of the volume before - being exposed inside Pod. This field will only apply - to volume types which support fsGroup based ownership(and - permissions). It will have no effect on ephemeral volume - types such as: secret, configmaps and emptydir. Valid - values are "OnRootMismatch" and "Always". If not specified, - "Always" is used. Note that this field cannot be set - when spec.os.name is windows.' + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. type: string runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to all - containers. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -2227,50 +2042,48 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by the containers - in this pod. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The seccomp 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 - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must be set - if type is "Localhost". Must NOT be set for any - other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID, the fsGroup (if specified), and group memberships - defined in the container image for the uid of the container - process. If unspecified, no additional groups are added - to any container. Note that group memberships defined - in the container image for the uid of the container - process are still effective, even if they are not included - in this list. Note that this field cannot be set when - spec.os.name is windows. + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array sysctls: - description: Sysctls hold a list of namespaced sysctls - used for the pod. Pods with unsupported sysctls (by - the container runtime) might fail to launch. Note that - this field cannot be set when spec.os.name is windows. + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. items: description: Sysctl defines a kernel parameter to be set @@ -2287,39 +2100,35 @@ spec: type: object type: array windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options within a - container's SecurityContext will be used. If set in - both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. All - of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork - must also be set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -2328,19 +2137,20 @@ spec: generator container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag - will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -2358,61 +2168,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that this - field cannot be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -2432,75 +2241,71 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name - is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must be set - if type is "Localhost". Must NOT be set for any - other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. All - of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork - must also be set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object type: object subProcessMaxHeapSize: - description: When zero report sidecar replicas are requested, - SubProcessMaxHeapSize configures the maximum heap size of the - basic subprocess report generator in MiB. The default heap size - is `200` (MiB). + description: |- + When zero report sidecar replicas are requested, SubProcessMaxHeapSize configures + the maximum heap size of the basic subprocess report generator in MiB. + The default heap size is `200` (MiB). format: int32 type: integer type: object @@ -2512,19 +2317,24 @@ spec: If specifying a memory limit, at least 768MiB is recommended. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -2540,8 +2350,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2550,30 +2361,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object dataSourceResources: description: Resource requirements for the JFR Data Source container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -2589,8 +2405,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2599,30 +2416,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object grafanaResources: description: Resource requirements for the Grafana container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -2638,8 +2460,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2648,11 +2471,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object type: object @@ -2667,22 +2490,20 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with @@ -2692,32 +2513,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2730,32 +2545,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2777,53 +2586,46 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2836,32 +2638,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2883,18 +2679,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -2913,30 +2707,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2948,53 +2737,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3006,42 +2787,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -3050,23 +2826,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -3077,28 +2852,24 @@ spec: selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3111,51 +2882,44 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3168,33 +2932,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -3206,18 +2966,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -3236,30 +2994,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3271,53 +3024,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3329,42 +3074,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -3373,23 +3113,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -3400,28 +3139,24 @@ spec: selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3434,51 +3169,44 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3491,33 +3219,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -3535,41 +3259,39 @@ spec: description: 'Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -3583,19 +3305,20 @@ spec: container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -3613,59 +3336,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -3685,63 +3409,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -3750,19 +3473,20 @@ spec: container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -3780,59 +3504,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -3852,63 +3577,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -3916,19 +3640,20 @@ spec: description: Security Context to apply to the storage container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -3946,59 +3671,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -4018,63 +3744,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -4082,19 +3807,20 @@ spec: description: Security Context to apply to the Grafana container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -4112,59 +3838,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -4184,63 +3911,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -4248,63 +3974,68 @@ spec: description: Security Context to apply to the Cryostat pod. properties: fsGroup: - description: "A special supplemental group that applies to - all containers in a pod. Some volume types allow the Kubelet - to change the ownership of that volume to be owned by the - pod: \n 1. The owning GID will be the FSGroup 2. The setgid - bit is set (new files created in the volume will be owned - by FSGroup) 3. The permission bits are OR'd with rw-rw---- - \n If unset, the Kubelet will not modify the ownership and - permissions of any volume. Note that this field cannot be - set when spec.os.name is windows." + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will - have no effect on ephemeral volume types such as: secret, - configmaps and emptydir. Valid values are "OnRootMismatch" - and "Always". If not specified, "Always" is used. Note that - this field cannot be set when spec.os.name is windows.' + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. type: string runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field - cannot be set when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is - windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - SecurityContext. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -4324,47 +4055,48 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by the containers - in this pod. Note that this field cannot be set when spec.os.name - is windows. + description: |- + The seccomp 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 defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's primary - GID, the fsGroup (if specified), and group memberships defined - in the container image for the uid of the container process. - If unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image - for the uid of the container process are still effective, - even if they are not included in this list. Note that this - field cannot be set when spec.os.name is windows. + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. items: description: Sysctl defines a kernel parameter to be set properties: @@ -4380,39 +4112,35 @@ spec: type: object type: array windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -4420,19 +4148,20 @@ spec: description: Security Context to apply to the storage container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -4450,59 +4179,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -4522,63 +4252,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -4598,19 +4327,22 @@ spec: creation. type: object httpPort: - description: HTTP port number for the Cryostat application - service. Defaults to 8181. + description: |- + HTTP port number for the Cryostat application service. + Defaults to 8181. format: int32 type: integer jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. + description: |- + Remote JMX port number for the Cryostat application service. + Defaults to 9091. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -4629,14 +4361,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the Grafana dashboard service. + description: |- + HTTP port number for the Grafana dashboard service. Defaults to 3000. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -4655,14 +4389,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the cryostat-reports service. + description: |- + HTTP port number for the cryostat-reports service. Defaults to 10000. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -4681,14 +4417,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the cryostat storage service. + description: |- + HTTP port number for the cryostat storage service. Defaults to 8333 format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -4702,8 +4440,9 @@ spec: and Templates. properties: emptyDir: - description: Configuration for an EmptyDir to be created by the - operator instead of a PVC. + description: |- + Configuration for an EmptyDir to be created + by the operator instead of a PVC. properties: enabled: description: When enabled, Cryostat will use EmptyDir volumes @@ -4711,10 +4450,10 @@ spec: will be ignored. type: boolean medium: - description: Unless specified, the emptyDir volume will be - mounted on the same storage medium backing the node. Setting - this field to "Memory" will mount the emptyDir on a tmpfs - (RAM-backed filesystem). + description: |- + Unless specified, the emptyDir volume will be mounted on + the same storage medium backing the node. Setting this field to + "Memory" will mount the emptyDir on a tmpfs (RAM-backed filesystem). type: string sizeLimit: description: The maximum memory limit for the emptyDir. Default @@ -4723,8 +4462,9 @@ spec: type: string type: object pvc: - description: Configuration for the Persistent Volume Claim to - be created by the operator. + description: |- + Configuration for the Persistent Volume Claim to be created + by the operator. properties: annotations: additionalProperties: @@ -4735,40 +4475,40 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Persistent Volume Claim - during its creation. The label with key "app" is reserved - for use by the operator. + description: |- + Labels to add to the Persistent Volume Claim during its creation. + The label with key "app" is reserved for use by the operator. type: object spec: - description: Spec for a Persistent Volume Claim, whose options - will override the defaults used by the operator. Unless - overriden, the PVC will be created with the default Storage - Class and 500MiB of storage. Once the operator has created - the PVC, changes to this field have no effect. + description: |- + Spec for a Persistent Volume Claim, whose options will override the + defaults used by the operator. Unless overriden, the PVC will be + created with the default Storage Class and 500MiB of storage. + Once the operator has created the PVC, changes to this field have + no effect. properties: accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 items: type: string type: array dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. type: string kind: @@ -4783,39 +4523,35 @@ spec: type: object x-kubernetes-map-type: atomic dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. type: string kind: @@ -4825,43 +4561,43 @@ spec: description: Name is the name of resource being referenced type: string namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. type: string required: - kind - name type: object resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the status - field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + 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. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n This field is immutable. It can only be set for - containers." + 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. + 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 @@ -4877,8 +4613,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -4887,12 +4624,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: - https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object selector: @@ -4903,8 +4639,8 @@ spec: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4912,17 +4648,16 @@ spec: applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -4934,22 +4669,22 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic storageClassName: - description: 'storageClassName is the name of the StorageClass - required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: |- + 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 volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. type: string volumeName: description: volumeName is the binding reference to the @@ -5017,42 +4752,42 @@ spec: Operator. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -5066,11 +4801,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -5109,21 +4845,27 @@ spec: name: v1beta2 schema: openAPIV3Schema: - description: Cryostat allows you to install Cryostat for a single namespace, - or multiple namespaces. It contains configuration options for controlling - the Deployment of the Cryostat application and its related components. A - Cryostat instance must be created to instruct the operator to deploy the - Cryostat application. + description: |- + Cryostat allows you to install Cryostat for a single namespace, or multiple namespaces. + It contains configuration options for controlling the Deployment of the Cryostat + application and its related components. + A Cryostat instance must be created to instruct the operator + to deploy the Cryostat application. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -5135,12 +4877,10 @@ spec: proxy. properties: basicAuth: - description: Reference to a secret and file name containing the - Basic authentication htpasswd file. If deploying on OpenShift - this defines additional user accounts that can access the Cryostat - application, on top of the OpenShift user accounts which pass - the OpenShift SSO Roles checks. If not on OpenShift then this - defines the only user accounts that have access. + description: |- + Reference to a secret and file name containing the Basic authentication htpasswd file. If deploying on OpenShift this + defines additional user accounts that can access the Cryostat application, on top of the OpenShift user accounts which + pass the OpenShift SSO Roles checks. If not on OpenShift then this defines the only user accounts that have access. properties: filename: description: Name of the file within the secret. @@ -5154,12 +4894,10 @@ spec: OpenShift user accounts may access the Cryostat application. properties: accessReview: - description: The SubjectAccessReview or TokenAccessReview - that all clients (users visiting the application via web - browser as well as CLI utilities and other programs presenting - Bearer auth tokens) must pass in order to access the application. - If not specified, the default role required is "create pods/exec" - in the Cryostat application's installation namespace. + description: |- + The SubjectAccessReview or TokenAccessReview that all clients (users visiting the application via web browser as well + as CLI utilities and other programs presenting Bearer auth tokens) must pass in order to access the application. + If not specified, the default role required is "create pods/exec" in the Cryostat application's installation namespace. properties: group: description: Group is the API Group of the Resource. "*" @@ -5171,13 +4909,11 @@ spec: all. type: string namespace: - description: Namespace is the namespace of the action - being requested. Currently, there is no distinction - between no namespace and all namespaces "" (empty) is - defaulted for LocalSubjectAccessReviews "" (empty) is - empty for cluster-scoped resources "" (empty) means - "all" for namespace scoped resources from a SubjectAccessReview - or SelfSubjectAccessReview + description: |- + Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + "" (empty) is defaulted for LocalSubjectAccessReviews + "" (empty) is empty for cluster-scoped resources + "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview type: string resource: description: Resource is one of the existing resource @@ -5198,9 +4934,9 @@ spec: type: string type: object disable: - description: Disable OpenShift SSO integration and allow all - users to access the application without authentication. - This will also bypass the BasicAuth, if specified. + description: |- + Disable OpenShift SSO integration and allow all users to access the application without authentication. This + will also bypass the BasicAuth, if specified. type: boolean type: object type: object @@ -5208,19 +4944,18 @@ spec: description: Options to configure the Cryostat application's database. properties: secretName: - description: 'Name of the secret containing database keys. This - secret must contain a CONNECTION_KEY secret which is the database - connection password, and an ENCRYPTION_KEY secret which is the - key used to encrypt sensitive data stored within the database, - such as the target credentials keyring. This field cannot be - updated. It is recommended that the secret should be marked - as immutable to avoid accidental changes to secret''s data. - More details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable' + description: |- + Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the + database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data + stored within the database, such as the target credentials keyring. This field cannot be updated. + It is recommended that the secret should be marked as immutable to avoid accidental changes to secret's data. + More details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable type: string type: object enableCertManager: - description: Use cert-manager to secure in-cluster communication between - Cryostat components. Requires cert-manager to be installed. + description: |- + Use cert-manager to secure in-cluster communication between Cryostat components. + Requires cert-manager to be installed. type: boolean eventTemplates: description: List of Flight Recorder Event Templates to preconfigure @@ -5241,11 +4976,13 @@ spec: type: object type: array networkOptions: - description: Options to control how the operator exposes the application - outside of the cluster, such as using an Ingress or Route. + description: |- + Options to control how the operator exposes the application outside of the cluster, + such as using an Ingress or Route. properties: coreConfig: - description: Specifications for how to expose the Cryostat service, + description: |- + Specifications for how to expose the Cryostat service, which serves the Cryostat application. properties: annotations: @@ -5255,32 +4992,30 @@ spec: its creation. type: object ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. + description: |- + Configuration for an Ingress object. + Currently subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate between ingresses/services. properties: defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. + description: |- + defaultBackend is the backend that should handle requests that don't + match any rule. If Rules are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests that do not match any + of the rules will be up to the Ingress controller. properties: resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type of resource being @@ -5296,27 +5031,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a service as a backend. + description: |- + service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -5325,100 +5062,92 @@ spec: type: object type: object ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. + description: |- + ingressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource, by a transitive connection + (controller -> IngressClass -> Ingress resource). Although the + `kubernetes.io/ingress.class` annotation (simple constant name) was never + formally defined, it was widely supported by Ingress controllers to create + a direct binding between Ingress controller and Ingress resources. Newly + created Ingress resources should prefer using the field. However, even + though the annotation is officially deprecated, for backwards compatibility + reasons, ingress controllers should still honor that annotation if present. type: string rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. + description: |- + rules is a list of host rules used to configure the Ingress. If unspecified, + or no rule matches, all traffic is sent to the default backend. items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. + description: |- + IngressRule represents the rules mapping the paths under a specified host to + the related backend services. Incoming requests are first evaluated for a host + match, then routed to the backend associated with the matching IngressRuleValue. properties: host: description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." + name of a network host, as defined by RFC 3986.\nNote + the following deviations from the \"host\" part + of the\nURI as defined in RFC 3986:\n1. IPs are + not allowed. Currently an IngressRuleValue can + only apply to\n the IP in the Spec of the parent + Ingress.\n2. The `:` delimiter is not respected + because ports are not allowed.\n\t Currently + the port of an Ingress is implicitly :80 for http + and\n\t :443 for https.\nBoth these may change + in the future.\nIncoming requests are matched + against the host before the\nIngressRuleValue. + If the host is unspecified, the Ingress routes + all\ntraffic based on the specified IngressRuleValue.\n\n\nhost + can be \"precise\" which is a domain name without + the terminating dot of\na network host (e.g. \"foo.bar.com\") + or \"wildcard\", which is a domain name\nprefixed + with a single wildcard label (e.g. \"*.foo.com\").\nThe + wildcard character '*' must appear by itself as + the first DNS label and\nmatches only a single + label. You cannot have a wildcard label by itself + (e.g. Host == \"*\").\nRequests will be matched + against the Host field in the following way:\n1. + If host is precise, the request matches this rule + if the http host header is equal to Host.\n2. + If host is a wildcard, then the request matches + this rule if the http host header\nis to equal + to the suffix (removing the first label) of the + wildcard rule." type: string http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' + description: |- + HTTPIngressRuleValue is a list of http selectors pointing to backends. + In the example: http:///? -> backend where + where parts of the url correspond to RFC 3986, this resource will be used + to match against everything after the last '/' and before the first '?' + or '#'. properties: paths: description: paths is a collection of paths that map requests to backends. items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. + description: |- + HTTPIngressPath associates a path with a backend. Incoming urls matching the + path are forwarded to the backend. properties: backend: - description: backend defines the referenced - service endpoint to which the traffic + description: |- + backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type @@ -5434,34 +5163,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". + description: |- + service references a service as a backend. + This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -5470,39 +5194,28 @@ spec: type: object type: object path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". + description: |- + path is matched against the path of an incoming request. Currently it can + contain characters disallowed from the conventional "path" part of a URL + as defined by RFC 3986. Paths must begin with a '/' and must be present + when using PathType with value "Exact" or "Prefix". type: string pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' + description: |- + pathType determines the interpretation of the path matching. PathType can + be one of the following values: + * Exact: Matches the URL path exactly. + * Prefix: Matches based on a URL path prefix split by '/'. Matching is + done on a path element by element basis. A path element refers is the + list of labels in the path split by the '/' separator. A request is a + match for path p if every p is an element-wise prefix of p of the + request path. Note that if the last element of the path is a substring + of the last element in request path, it is not a match (e.g. /foo/bar + matches /foo/bar/baz, but does not match /foo/barbaz). + * ImplementationSpecific: Interpretation of the Path matching is up to + the IngressClass. Implementations can treat this as a separate PathType + or treat it identically to Prefix or Exact path types. + Implementations are required to support all path types. type: string required: - backend @@ -5517,34 +5230,32 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. + description: |- + tls represents the TLS configuration. Currently the Ingress only supports a + single TLS port, 443. If multiple members of this list specify different hosts, + they will be multiplexed on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller fulfilling the + ingress supports SNI. items: description: IngressTLS describes the transport layer security associated with an ingress. properties: hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. items: type: string type: array x-kubernetes-list-type: atomic secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination and value of the "Host" header is used for routing. type: string type: object @@ -5554,9 +5265,9 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. + description: |- + Labels to add to the Ingress or Route during its creation. + The label with key "app" is reserved for use by the operator. type: object type: object type: object @@ -5576,7 +5287,8 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the resources during its creation. + description: |- + Labels to add to the resources during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -5593,7 +5305,8 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the resources during its creation. + description: |- + Labels to add to the resources during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -5603,30 +5316,35 @@ spec: description: Options to configure Cryostat Automated Report Analysis. properties: replicas: - description: The number of report sidecar replica containers to - deploy. Each replica can service one report generation request - at a time. + description: |- + The number of report sidecar replica containers to deploy. + Each replica can service one report generation request at a time. format: int32 type: integer resources: - description: The resources allocated to each sidecar replica. - A replica with more resources can handle larger input recordings - and will process them faster. + description: |- + The resources allocated to each sidecar replica. + A replica with more resources can handle larger input recordings and will process them faster. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -5642,8 +5360,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5652,11 +5371,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object schedulingOptions: @@ -5670,23 +5389,20 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling term - matches all objects with implicit weight 0 (i.e. - it's a no-op). A null preferred scheduling term - matches no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -5696,32 +5412,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5734,32 +5444,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5782,53 +5486,46 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to an update), the system may or may not try - to eventually evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5841,32 +5538,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5888,19 +5579,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -5919,10 +5607,9 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5930,20 +5617,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5955,36 +5638,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5992,20 +5668,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6017,46 +5689,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -6065,25 +5728,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to a pod label update), the system may or may - not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -6094,30 +5754,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6129,53 +5784,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6187,34 +5834,28 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: @@ -6227,19 +5868,16 @@ spec: Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to - the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -6258,10 +5896,9 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6269,20 +5906,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6294,36 +5927,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6331,20 +5957,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6356,46 +5978,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -6404,25 +6017,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - anti-affinity requirements specified by this field - cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may - or may not try to eventually evict the pod from - its node. When there are multiple elements, the - lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -6433,30 +6043,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6468,53 +6073,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6526,34 +6123,28 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: @@ -6572,42 +6163,39 @@ spec: description: 'Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period - of time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the value should - be empty, otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -6621,66 +6209,68 @@ spec: generator pod. properties: fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow - the Kubelet to change the ownership of that volume to - be owned by the pod: \n 1. The owning GID will be the - FSGroup 2. The setgid bit is set (new files created - in the volume will be owned by FSGroup) 3. The permission - bits are OR'd with rw-rw---- \n If unset, the Kubelet - will not modify the ownership and permissions of any - volume. Note that this field cannot be set when spec.os.name - is windows." + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of - changing ownership and permission of the volume before - being exposed inside Pod. This field will only apply - to volume types which support fsGroup based ownership(and - permissions). It will have no effect on ephemeral volume - types such as: secret, configmaps and emptydir. Valid - values are "OnRootMismatch" and "Always". If not specified, - "Always" is used. Note that this field cannot be set - when spec.os.name is windows.' + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. type: string runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to all - containers. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -6700,50 +6290,48 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by the containers - in this pod. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The seccomp 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 - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must be set - if type is "Localhost". Must NOT be set for any - other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID, the fsGroup (if specified), and group memberships - defined in the container image for the uid of the container - process. If unspecified, no additional groups are added - to any container. Note that group memberships defined - in the container image for the uid of the container - process are still effective, even if they are not included - in this list. Note that this field cannot be set when - spec.os.name is windows. + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array sysctls: - description: Sysctls hold a list of namespaced sysctls - used for the pod. Pods with unsupported sysctls (by - the container runtime) might fail to launch. Note that - this field cannot be set when spec.os.name is windows. + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. items: description: Sysctl defines a kernel parameter to be set @@ -6760,39 +6348,35 @@ spec: type: object type: array windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options within a - container's SecurityContext will be used. If set in - both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. All - of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork - must also be set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -6801,19 +6385,20 @@ spec: generator container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag - will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -6831,61 +6416,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that this - field cannot be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -6905,75 +6489,71 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name - is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must be set - if type is "Localhost". Must NOT be set for any - other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. All - of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork - must also be set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object type: object subProcessMaxHeapSize: - description: When zero report sidecar replicas are requested, - SubProcessMaxHeapSize configures the maximum heap size of the - basic subprocess report generator in MiB. The default heap size - is `200` (MiB). + description: |- + When zero report sidecar replicas are requested, SubProcessMaxHeapSize configures + the maximum heap size of the basic subprocess report generator in MiB. + The default heap size is `200` (MiB). format: int32 type: integer type: object @@ -6984,19 +6564,24 @@ spec: description: Resource requirements for the auth proxy. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7012,8 +6597,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7022,11 +6608,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object coreResources: @@ -7034,19 +6620,24 @@ spec: If specifying a memory limit, at least 384MiB is recommended. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7062,8 +6653,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7072,30 +6664,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object dataSourceResources: description: Resource requirements for the JFR Data Source container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7111,8 +6708,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7121,30 +6719,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object databaseResources: description: Resource requirements for the database container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7160,8 +6763,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7170,30 +6774,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object grafanaResources: description: Resource requirements for the Grafana container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7209,8 +6818,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7219,30 +6829,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object objectStorageResources: description: Resource requirements for the object storage container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7258,8 +6873,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7268,11 +6884,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object type: object @@ -7287,22 +6903,20 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with @@ -7312,32 +6926,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7350,32 +6958,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7397,53 +6999,46 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7456,32 +7051,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7503,18 +7092,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -7533,30 +7120,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7568,53 +7150,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7626,42 +7200,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -7670,23 +7239,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -7697,28 +7265,24 @@ spec: selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7731,51 +7295,44 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7788,33 +7345,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -7826,18 +7379,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -7856,30 +7407,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7891,53 +7437,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7949,42 +7487,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -7993,23 +7526,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -8020,28 +7552,24 @@ spec: selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8054,51 +7582,44 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8111,33 +7632,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8155,41 +7672,39 @@ spec: description: 'Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -8202,19 +7717,20 @@ spec: description: Security Context to apply to the auth proxy container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8232,59 +7748,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8304,63 +7821,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -8369,19 +7885,20 @@ spec: container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8399,59 +7916,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8471,63 +7989,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -8536,19 +8053,20 @@ spec: container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8566,59 +8084,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8638,63 +8157,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -8702,19 +8220,20 @@ spec: description: Security Context to apply to the database container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8732,59 +8251,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8804,63 +8324,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -8868,19 +8387,20 @@ spec: description: Security Context to apply to the Grafana container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8898,59 +8418,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8970,63 +8491,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -9034,63 +8554,68 @@ spec: description: Security Context to apply to the Cryostat pod. properties: fsGroup: - description: "A special supplemental group that applies to - all containers in a pod. Some volume types allow the Kubelet - to change the ownership of that volume to be owned by the - pod: \n 1. The owning GID will be the FSGroup 2. The setgid - bit is set (new files created in the volume will be owned - by FSGroup) 3. The permission bits are OR'd with rw-rw---- - \n If unset, the Kubelet will not modify the ownership and - permissions of any volume. Note that this field cannot be - set when spec.os.name is windows." + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will - have no effect on ephemeral volume types such as: secret, - configmaps and emptydir. Valid values are "OnRootMismatch" - and "Always". If not specified, "Always" is used. Note that - this field cannot be set when spec.os.name is windows.' + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. type: string runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field - cannot be set when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is - windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - SecurityContext. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -9110,47 +8635,48 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by the containers - in this pod. Note that this field cannot be set when spec.os.name - is windows. + description: |- + The seccomp 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 defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's primary - GID, the fsGroup (if specified), and group memberships defined - in the container image for the uid of the container process. - If unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image - for the uid of the container process are still effective, - even if they are not included in this list. Note that this - field cannot be set when spec.os.name is windows. + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. items: description: Sysctl defines a kernel parameter to be set properties: @@ -9166,39 +8692,35 @@ spec: type: object type: array windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -9206,19 +8728,20 @@ spec: description: Security Context to apply to the storage container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -9236,59 +8759,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -9308,63 +8832,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -9384,14 +8907,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the Cryostat application - service. Defaults to 8181. + description: |- + HTTP port number for the Cryostat application service. + Defaults to 8181. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -9410,14 +8935,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the cryostat-reports service. + description: |- + HTTP port number for the cryostat-reports service. Defaults to 10000. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -9431,8 +8958,9 @@ spec: database and object storage. properties: emptyDir: - description: Configuration for an EmptyDir to be created by the - operator instead of a PVC. + description: |- + Configuration for an EmptyDir to be created + by the operator instead of a PVC. properties: enabled: description: When enabled, Cryostat will use EmptyDir volumes @@ -9440,10 +8968,10 @@ spec: will be ignored. type: boolean medium: - description: Unless specified, the emptyDir volume will be - mounted on the same storage medium backing the node. Setting - this field to "Memory" will mount the emptyDir on a tmpfs - (RAM-backed filesystem). + description: |- + Unless specified, the emptyDir volume will be mounted on + the same storage medium backing the node. Setting this field to + "Memory" will mount the emptyDir on a tmpfs (RAM-backed filesystem). type: string sizeLimit: description: The maximum memory limit for the emptyDir. Default @@ -9452,8 +8980,9 @@ spec: type: string type: object pvc: - description: Configuration for the Persistent Volume Claim to - be created by the operator. + description: |- + Configuration for the Persistent Volume Claim to be created + by the operator. properties: annotations: additionalProperties: @@ -9464,40 +8993,40 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Persistent Volume Claim - during its creation. The label with key "app" is reserved - for use by the operator. + description: |- + Labels to add to the Persistent Volume Claim during its creation. + The label with key "app" is reserved for use by the operator. type: object spec: - description: Spec for a Persistent Volume Claim, whose options - will override the defaults used by the operator. Unless - overriden, the PVC will be created with the default Storage - Class and 500MiB of storage. Once the operator has created - the PVC, changes to this field have no effect. + description: |- + Spec for a Persistent Volume Claim, whose options will override the + defaults used by the operator. Unless overriden, the PVC will be + created with the default Storage Class and 500MiB of storage. + Once the operator has created the PVC, changes to this field have + no effect. properties: accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 items: type: string type: array dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. type: string kind: @@ -9512,39 +9041,35 @@ spec: type: object x-kubernetes-map-type: atomic dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. type: string kind: @@ -9554,43 +9079,43 @@ spec: description: Name is the name of resource being referenced type: string namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. type: string required: - kind - name type: object resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the status - field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + 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. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n This field is immutable. It can only be set for - containers." + 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. + 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 @@ -9606,8 +9131,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -9616,12 +9142,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: - https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object selector: @@ -9632,8 +9157,8 @@ spec: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9641,17 +9166,16 @@ spec: applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -9663,22 +9187,22 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic storageClassName: - description: 'storageClassName is the name of the StorageClass - required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: |- + 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 volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. type: string volumeName: description: volumeName is the binding reference to the @@ -9738,10 +9262,12 @@ spec: type: array type: object targetNamespaces: - description: 'List of namespaces whose workloads Cryostat should be - permitted to access and profile. Defaults to this Cryostat''s namespace. - Warning: All Cryostat users will be able to create and manage recordings - for workloads in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + description: |- + List of namespaces whose workloads Cryostat should be + permitted to access and profile. Defaults to this Cryostat's namespace. + Warning: All Cryostat users will be able to create and manage + recordings for workloads in the listed namespaces. + More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation items: type: string type: array @@ -9772,42 +9298,42 @@ spec: Operator. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -9821,11 +9347,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -9846,7 +9373,8 @@ spec: key. type: string targetNamespaces: - description: List of namespaces that Cryostat has been configured + description: |- + List of namespaces that Cryostat has been configured and authorized to access and profile. items: type: string diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 63a11693b..6a2f6a726 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.14.0 name: cryostats.operator.cryostat.io spec: group: operator.cryostat.io @@ -25,20 +24,27 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: Cryostat allows you to install Cryostat for a single namespace. - It contains configuration options for controlling the Deployment of the - Cryostat application and its related components. A Cryostat instance must - be created to instruct the operator to deploy the Cryostat application. + description: |- + Cryostat allows you to install Cryostat for a single namespace. + It contains configuration options for controlling the Deployment of the Cryostat + application and its related components. + A Cryostat instance must be created to instruct the operator + to deploy the Cryostat application. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -50,10 +56,10 @@ spec: on OpenShift. properties: clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' + description: |- + Name of the ClusterRole to use when Cryostat requests a role-scoped OAuth token. + This ClusterRole should contain permissions for all Kubernetes objects listed in custom permission mapping. + More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth type: string configMapName: description: Name of config map in the local namespace. @@ -68,8 +74,9 @@ spec: - filename type: object enableCertManager: - description: Use cert-manager to secure in-cluster communication between - Cryostat components. Requires cert-manager to be installed. + description: |- + Use cert-manager to secure in-cluster communication between Cryostat components. + Requires cert-manager to be installed. type: boolean eventTemplates: description: List of Flight Recorder Event Templates to preconfigure @@ -127,13 +134,17 @@ spec: Dashboard or JFR Data Source. type: boolean networkOptions: - description: Options to control how the operator exposes the application - outside of the cluster, such as using an Ingress or Route. + description: |- + Options to control how the operator exposes the application outside of the cluster, + such as using an Ingress or Route. properties: commandConfig: - description: "Specifications for how to expose the Cryostat command - service, which serves the WebSocket command channel. \n Deprecated: - CommandConfig is no longer used." + description: |- + Specifications for how to expose the Cryostat command service, + which serves the WebSocket command channel. + + + Deprecated: CommandConfig is no longer used. properties: annotations: additionalProperties: @@ -142,32 +153,30 @@ spec: its creation. type: object ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. + description: |- + Configuration for an Ingress object. + Currently subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate between ingresses/services. properties: defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. + description: |- + defaultBackend is the backend that should handle requests that don't + match any rule. If Rules are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests that do not match any + of the rules will be up to the Ingress controller. properties: resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type of resource being @@ -183,27 +192,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a service as a backend. + description: |- + service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -212,100 +223,92 @@ spec: type: object type: object ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. + description: |- + ingressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource, by a transitive connection + (controller -> IngressClass -> Ingress resource). Although the + `kubernetes.io/ingress.class` annotation (simple constant name) was never + formally defined, it was widely supported by Ingress controllers to create + a direct binding between Ingress controller and Ingress resources. Newly + created Ingress resources should prefer using the field. However, even + though the annotation is officially deprecated, for backwards compatibility + reasons, ingress controllers should still honor that annotation if present. type: string rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. + description: |- + rules is a list of host rules used to configure the Ingress. If unspecified, + or no rule matches, all traffic is sent to the default backend. items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. + description: |- + IngressRule represents the rules mapping the paths under a specified host to + the related backend services. Incoming requests are first evaluated for a host + match, then routed to the backend associated with the matching IngressRuleValue. properties: host: description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." + name of a network host, as defined by RFC 3986.\nNote + the following deviations from the \"host\" part + of the\nURI as defined in RFC 3986:\n1. IPs are + not allowed. Currently an IngressRuleValue can + only apply to\n the IP in the Spec of the parent + Ingress.\n2. The `:` delimiter is not respected + because ports are not allowed.\n\t Currently + the port of an Ingress is implicitly :80 for http + and\n\t :443 for https.\nBoth these may change + in the future.\nIncoming requests are matched + against the host before the\nIngressRuleValue. + If the host is unspecified, the Ingress routes + all\ntraffic based on the specified IngressRuleValue.\n\n\nhost + can be \"precise\" which is a domain name without + the terminating dot of\na network host (e.g. \"foo.bar.com\") + or \"wildcard\", which is a domain name\nprefixed + with a single wildcard label (e.g. \"*.foo.com\").\nThe + wildcard character '*' must appear by itself as + the first DNS label and\nmatches only a single + label. You cannot have a wildcard label by itself + (e.g. Host == \"*\").\nRequests will be matched + against the Host field in the following way:\n1. + If host is precise, the request matches this rule + if the http host header is equal to Host.\n2. + If host is a wildcard, then the request matches + this rule if the http host header\nis to equal + to the suffix (removing the first label) of the + wildcard rule." type: string http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' + description: |- + HTTPIngressRuleValue is a list of http selectors pointing to backends. + In the example: http:///? -> backend where + where parts of the url correspond to RFC 3986, this resource will be used + to match against everything after the last '/' and before the first '?' + or '#'. properties: paths: description: paths is a collection of paths that map requests to backends. items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. + description: |- + HTTPIngressPath associates a path with a backend. Incoming urls matching the + path are forwarded to the backend. properties: backend: - description: backend defines the referenced - service endpoint to which the traffic + description: |- + backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type @@ -321,34 +324,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". + description: |- + service references a service as a backend. + This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -357,39 +355,28 @@ spec: type: object type: object path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". + description: |- + path is matched against the path of an incoming request. Currently it can + contain characters disallowed from the conventional "path" part of a URL + as defined by RFC 3986. Paths must begin with a '/' and must be present + when using PathType with value "Exact" or "Prefix". type: string pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' + description: |- + pathType determines the interpretation of the path matching. PathType can + be one of the following values: + * Exact: Matches the URL path exactly. + * Prefix: Matches based on a URL path prefix split by '/'. Matching is + done on a path element by element basis. A path element refers is the + list of labels in the path split by the '/' separator. A request is a + match for path p if every p is an element-wise prefix of p of the + request path. Note that if the last element of the path is a substring + of the last element in request path, it is not a match (e.g. /foo/bar + matches /foo/bar/baz, but does not match /foo/barbaz). + * ImplementationSpecific: Interpretation of the Path matching is up to + the IngressClass. Implementations can treat this as a separate PathType + or treat it identically to Prefix or Exact path types. + Implementations are required to support all path types. type: string required: - backend @@ -404,34 +391,32 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. + description: |- + tls represents the TLS configuration. Currently the Ingress only supports a + single TLS port, 443. If multiple members of this list specify different hosts, + they will be multiplexed on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller fulfilling the + ingress supports SNI. items: description: IngressTLS describes the transport layer security associated with an ingress. properties: hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. items: type: string type: array x-kubernetes-list-type: atomic secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination and value of the "Host" header is used for routing. type: string type: object @@ -441,13 +426,14 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. + description: |- + Labels to add to the Ingress or Route during its creation. + The label with key "app" is reserved for use by the operator. type: object type: object coreConfig: - description: Specifications for how to expose the Cryostat service, + description: |- + Specifications for how to expose the Cryostat service, which serves the Cryostat application. properties: annotations: @@ -457,32 +443,30 @@ spec: its creation. type: object ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. + description: |- + Configuration for an Ingress object. + Currently subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate between ingresses/services. properties: defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. + description: |- + defaultBackend is the backend that should handle requests that don't + match any rule. If Rules are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests that do not match any + of the rules will be up to the Ingress controller. properties: resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type of resource being @@ -498,27 +482,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a service as a backend. + description: |- + service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -527,100 +513,92 @@ spec: type: object type: object ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. + description: |- + ingressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource, by a transitive connection + (controller -> IngressClass -> Ingress resource). Although the + `kubernetes.io/ingress.class` annotation (simple constant name) was never + formally defined, it was widely supported by Ingress controllers to create + a direct binding between Ingress controller and Ingress resources. Newly + created Ingress resources should prefer using the field. However, even + though the annotation is officially deprecated, for backwards compatibility + reasons, ingress controllers should still honor that annotation if present. type: string rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. + description: |- + rules is a list of host rules used to configure the Ingress. If unspecified, + or no rule matches, all traffic is sent to the default backend. items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. + description: |- + IngressRule represents the rules mapping the paths under a specified host to + the related backend services. Incoming requests are first evaluated for a host + match, then routed to the backend associated with the matching IngressRuleValue. properties: host: description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." + name of a network host, as defined by RFC 3986.\nNote + the following deviations from the \"host\" part + of the\nURI as defined in RFC 3986:\n1. IPs are + not allowed. Currently an IngressRuleValue can + only apply to\n the IP in the Spec of the parent + Ingress.\n2. The `:` delimiter is not respected + because ports are not allowed.\n\t Currently + the port of an Ingress is implicitly :80 for http + and\n\t :443 for https.\nBoth these may change + in the future.\nIncoming requests are matched + against the host before the\nIngressRuleValue. + If the host is unspecified, the Ingress routes + all\ntraffic based on the specified IngressRuleValue.\n\n\nhost + can be \"precise\" which is a domain name without + the terminating dot of\na network host (e.g. \"foo.bar.com\") + or \"wildcard\", which is a domain name\nprefixed + with a single wildcard label (e.g. \"*.foo.com\").\nThe + wildcard character '*' must appear by itself as + the first DNS label and\nmatches only a single + label. You cannot have a wildcard label by itself + (e.g. Host == \"*\").\nRequests will be matched + against the Host field in the following way:\n1. + If host is precise, the request matches this rule + if the http host header is equal to Host.\n2. + If host is a wildcard, then the request matches + this rule if the http host header\nis to equal + to the suffix (removing the first label) of the + wildcard rule." type: string http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' + description: |- + HTTPIngressRuleValue is a list of http selectors pointing to backends. + In the example: http:///? -> backend where + where parts of the url correspond to RFC 3986, this resource will be used + to match against everything after the last '/' and before the first '?' + or '#'. properties: paths: description: paths is a collection of paths that map requests to backends. items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. + description: |- + HTTPIngressPath associates a path with a backend. Incoming urls matching the + path are forwarded to the backend. properties: backend: - description: backend defines the referenced - service endpoint to which the traffic + description: |- + backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type @@ -636,34 +614,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". + description: |- + service references a service as a backend. + This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -672,39 +645,28 @@ spec: type: object type: object path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". + description: |- + path is matched against the path of an incoming request. Currently it can + contain characters disallowed from the conventional "path" part of a URL + as defined by RFC 3986. Paths must begin with a '/' and must be present + when using PathType with value "Exact" or "Prefix". type: string pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' + description: |- + pathType determines the interpretation of the path matching. PathType can + be one of the following values: + * Exact: Matches the URL path exactly. + * Prefix: Matches based on a URL path prefix split by '/'. Matching is + done on a path element by element basis. A path element refers is the + list of labels in the path split by the '/' separator. A request is a + match for path p if every p is an element-wise prefix of p of the + request path. Note that if the last element of the path is a substring + of the last element in request path, it is not a match (e.g. /foo/bar + matches /foo/bar/baz, but does not match /foo/barbaz). + * ImplementationSpecific: Interpretation of the Path matching is up to + the IngressClass. Implementations can treat this as a separate PathType + or treat it identically to Prefix or Exact path types. + Implementations are required to support all path types. type: string required: - backend @@ -719,34 +681,32 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. + description: |- + tls represents the TLS configuration. Currently the Ingress only supports a + single TLS port, 443. If multiple members of this list specify different hosts, + they will be multiplexed on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller fulfilling the + ingress supports SNI. items: description: IngressTLS describes the transport layer security associated with an ingress. properties: hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. items: type: string type: array x-kubernetes-list-type: atomic secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination and value of the "Host" header is used for routing. type: string type: object @@ -756,14 +716,15 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. + description: |- + Labels to add to the Ingress or Route during its creation. + The label with key "app" is reserved for use by the operator. type: object type: object grafanaConfig: - description: Specifications for how to expose Cryostat's Grafana - service, which serves the Grafana dashboard. + description: |- + Specifications for how to expose Cryostat's Grafana service, + which serves the Grafana dashboard. properties: annotations: additionalProperties: @@ -772,32 +733,30 @@ spec: its creation. type: object ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. + description: |- + Configuration for an Ingress object. + Currently subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate between ingresses/services. properties: defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. + description: |- + defaultBackend is the backend that should handle requests that don't + match any rule. If Rules are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests that do not match any + of the rules will be up to the Ingress controller. properties: resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type of resource being @@ -813,27 +772,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a service as a backend. + description: |- + service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -842,100 +803,92 @@ spec: type: object type: object ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. + description: |- + ingressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource, by a transitive connection + (controller -> IngressClass -> Ingress resource). Although the + `kubernetes.io/ingress.class` annotation (simple constant name) was never + formally defined, it was widely supported by Ingress controllers to create + a direct binding between Ingress controller and Ingress resources. Newly + created Ingress resources should prefer using the field. However, even + though the annotation is officially deprecated, for backwards compatibility + reasons, ingress controllers should still honor that annotation if present. type: string rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. + description: |- + rules is a list of host rules used to configure the Ingress. If unspecified, + or no rule matches, all traffic is sent to the default backend. items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. + description: |- + IngressRule represents the rules mapping the paths under a specified host to + the related backend services. Incoming requests are first evaluated for a host + match, then routed to the backend associated with the matching IngressRuleValue. properties: host: description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." + name of a network host, as defined by RFC 3986.\nNote + the following deviations from the \"host\" part + of the\nURI as defined in RFC 3986:\n1. IPs are + not allowed. Currently an IngressRuleValue can + only apply to\n the IP in the Spec of the parent + Ingress.\n2. The `:` delimiter is not respected + because ports are not allowed.\n\t Currently + the port of an Ingress is implicitly :80 for http + and\n\t :443 for https.\nBoth these may change + in the future.\nIncoming requests are matched + against the host before the\nIngressRuleValue. + If the host is unspecified, the Ingress routes + all\ntraffic based on the specified IngressRuleValue.\n\n\nhost + can be \"precise\" which is a domain name without + the terminating dot of\na network host (e.g. \"foo.bar.com\") + or \"wildcard\", which is a domain name\nprefixed + with a single wildcard label (e.g. \"*.foo.com\").\nThe + wildcard character '*' must appear by itself as + the first DNS label and\nmatches only a single + label. You cannot have a wildcard label by itself + (e.g. Host == \"*\").\nRequests will be matched + against the Host field in the following way:\n1. + If host is precise, the request matches this rule + if the http host header is equal to Host.\n2. + If host is a wildcard, then the request matches + this rule if the http host header\nis to equal + to the suffix (removing the first label) of the + wildcard rule." type: string http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' + description: |- + HTTPIngressRuleValue is a list of http selectors pointing to backends. + In the example: http:///? -> backend where + where parts of the url correspond to RFC 3986, this resource will be used + to match against everything after the last '/' and before the first '?' + or '#'. properties: paths: description: paths is a collection of paths that map requests to backends. items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. + description: |- + HTTPIngressPath associates a path with a backend. Incoming urls matching the + path are forwarded to the backend. properties: backend: - description: backend defines the referenced - service endpoint to which the traffic + description: |- + backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type @@ -951,34 +904,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". + description: |- + service references a service as a backend. + This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -987,39 +935,28 @@ spec: type: object type: object path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". + description: |- + path is matched against the path of an incoming request. Currently it can + contain characters disallowed from the conventional "path" part of a URL + as defined by RFC 3986. Paths must begin with a '/' and must be present + when using PathType with value "Exact" or "Prefix". type: string pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' + description: |- + pathType determines the interpretation of the path matching. PathType can + be one of the following values: + * Exact: Matches the URL path exactly. + * Prefix: Matches based on a URL path prefix split by '/'. Matching is + done on a path element by element basis. A path element refers is the + list of labels in the path split by the '/' separator. A request is a + match for path p if every p is an element-wise prefix of p of the + request path. Note that if the last element of the path is a substring + of the last element in request path, it is not a match (e.g. /foo/bar + matches /foo/bar/baz, but does not match /foo/barbaz). + * ImplementationSpecific: Interpretation of the Path matching is up to + the IngressClass. Implementations can treat this as a separate PathType + or treat it identically to Prefix or Exact path types. + Implementations are required to support all path types. type: string required: - backend @@ -1034,34 +971,32 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. + description: |- + tls represents the TLS configuration. Currently the Ingress only supports a + single TLS port, 443. If multiple members of this list specify different hosts, + they will be multiplexed on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller fulfilling the + ingress supports SNI. items: description: IngressTLS describes the transport layer security associated with an ingress. properties: hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. items: type: string type: array x-kubernetes-list-type: atomic secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination and value of the "Host" header is used for routing. type: string type: object @@ -1071,9 +1006,9 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. + description: |- + Labels to add to the Ingress or Route during its creation. + The label with key "app" is reserved for use by the operator. type: object type: object type: object @@ -1093,7 +1028,8 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the resources during its creation. + description: |- + Labels to add to the resources during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -1110,7 +1046,8 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the resources during its creation. + description: |- + Labels to add to the resources during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -1120,30 +1057,35 @@ spec: description: Options to configure Cryostat Automated Report Analysis. properties: replicas: - description: The number of report sidecar replica containers to - deploy. Each replica can service one report generation request - at a time. + description: |- + The number of report sidecar replica containers to deploy. + Each replica can service one report generation request at a time. format: int32 type: integer resources: - description: The resources allocated to each sidecar replica. - A replica with more resources can handle larger input recordings - and will process them faster. + description: |- + The resources allocated to each sidecar replica. + A replica with more resources can handle larger input recordings and will process them faster. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -1159,8 +1101,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -1169,11 +1112,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object schedulingOptions: @@ -1187,23 +1130,20 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling term - matches all objects with implicit weight 0 (i.e. - it's a no-op). A null preferred scheduling term - matches no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -1213,32 +1153,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1251,32 +1185,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1299,53 +1227,46 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to an update), the system may or may not try - to eventually evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1358,32 +1279,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -1405,19 +1320,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1436,10 +1348,9 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1447,20 +1358,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1472,36 +1379,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1509,20 +1409,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1534,46 +1430,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -1582,25 +1469,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to a pod label update), the system may or may - not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -1611,30 +1495,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1646,53 +1525,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1704,34 +1575,28 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: @@ -1744,19 +1609,16 @@ spec: Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to - the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -1775,10 +1637,9 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1786,20 +1647,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1811,36 +1668,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -1848,20 +1698,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1873,46 +1719,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -1921,25 +1758,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - anti-affinity requirements specified by this field - cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may - or may not try to eventually evict the pod from - its node. When there are multiple elements, the - lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -1950,30 +1784,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -1985,53 +1814,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2043,34 +1864,28 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: @@ -2089,42 +1904,39 @@ spec: description: 'Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period - of time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the value should - be empty, otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -2138,66 +1950,68 @@ spec: generator pod. properties: fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow - the Kubelet to change the ownership of that volume to - be owned by the pod: \n 1. The owning GID will be the - FSGroup 2. The setgid bit is set (new files created - in the volume will be owned by FSGroup) 3. The permission - bits are OR'd with rw-rw---- \n If unset, the Kubelet - will not modify the ownership and permissions of any - volume. Note that this field cannot be set when spec.os.name - is windows." + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of - changing ownership and permission of the volume before - being exposed inside Pod. This field will only apply - to volume types which support fsGroup based ownership(and - permissions). It will have no effect on ephemeral volume - types such as: secret, configmaps and emptydir. Valid - values are "OnRootMismatch" and "Always". If not specified, - "Always" is used. Note that this field cannot be set - when spec.os.name is windows.' + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. type: string runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to all - containers. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -2217,50 +2031,48 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by the containers - in this pod. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The seccomp 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 - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must be set - if type is "Localhost". Must NOT be set for any - other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID, the fsGroup (if specified), and group memberships - defined in the container image for the uid of the container - process. If unspecified, no additional groups are added - to any container. Note that group memberships defined - in the container image for the uid of the container - process are still effective, even if they are not included - in this list. Note that this field cannot be set when - spec.os.name is windows. + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array sysctls: - description: Sysctls hold a list of namespaced sysctls - used for the pod. Pods with unsupported sysctls (by - the container runtime) might fail to launch. Note that - this field cannot be set when spec.os.name is windows. + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. items: description: Sysctl defines a kernel parameter to be set @@ -2277,39 +2089,35 @@ spec: type: object type: array windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options within a - container's SecurityContext will be used. If set in - both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. All - of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork - must also be set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -2318,19 +2126,20 @@ spec: generator container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag - will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -2348,61 +2157,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that this - field cannot be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -2422,75 +2230,71 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name - is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must be set - if type is "Localhost". Must NOT be set for any - other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. All - of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork - must also be set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object type: object subProcessMaxHeapSize: - description: When zero report sidecar replicas are requested, - SubProcessMaxHeapSize configures the maximum heap size of the - basic subprocess report generator in MiB. The default heap size - is `200` (MiB). + description: |- + When zero report sidecar replicas are requested, SubProcessMaxHeapSize configures + the maximum heap size of the basic subprocess report generator in MiB. + The default heap size is `200` (MiB). format: int32 type: integer type: object @@ -2502,19 +2306,24 @@ spec: If specifying a memory limit, at least 768MiB is recommended. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -2530,8 +2339,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2540,30 +2350,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object dataSourceResources: description: Resource requirements for the JFR Data Source container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -2579,8 +2394,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2589,30 +2405,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object grafanaResources: description: Resource requirements for the Grafana container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -2628,8 +2449,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -2638,11 +2460,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object type: object @@ -2657,22 +2479,20 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with @@ -2682,32 +2502,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2720,32 +2534,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2767,53 +2575,46 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2826,32 +2627,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -2873,18 +2668,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -2903,30 +2696,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2938,53 +2726,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -2996,42 +2776,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -3040,23 +2815,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -3067,28 +2841,24 @@ spec: selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3101,51 +2871,44 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3158,33 +2921,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -3196,18 +2955,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -3226,30 +2983,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3261,53 +3013,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -3319,42 +3063,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -3363,23 +3102,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -3390,28 +3128,24 @@ spec: selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3424,51 +3158,44 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -3481,33 +3208,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -3525,41 +3248,39 @@ spec: description: 'Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -3573,19 +3294,20 @@ spec: container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -3603,59 +3325,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -3675,63 +3398,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -3740,19 +3462,20 @@ spec: container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -3770,59 +3493,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -3842,63 +3566,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -3906,19 +3629,20 @@ spec: description: Security Context to apply to the storage container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -3936,59 +3660,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -4008,63 +3733,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -4072,19 +3796,20 @@ spec: description: Security Context to apply to the Grafana container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -4102,59 +3827,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -4174,63 +3900,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -4238,63 +3963,68 @@ spec: description: Security Context to apply to the Cryostat pod. properties: fsGroup: - description: "A special supplemental group that applies to - all containers in a pod. Some volume types allow the Kubelet - to change the ownership of that volume to be owned by the - pod: \n 1. The owning GID will be the FSGroup 2. The setgid - bit is set (new files created in the volume will be owned - by FSGroup) 3. The permission bits are OR'd with rw-rw---- - \n If unset, the Kubelet will not modify the ownership and - permissions of any volume. Note that this field cannot be - set when spec.os.name is windows." + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will - have no effect on ephemeral volume types such as: secret, - configmaps and emptydir. Valid values are "OnRootMismatch" - and "Always". If not specified, "Always" is used. Note that - this field cannot be set when spec.os.name is windows.' + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. type: string runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field - cannot be set when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is - windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - SecurityContext. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -4314,47 +4044,48 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by the containers - in this pod. Note that this field cannot be set when spec.os.name - is windows. + description: |- + The seccomp 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 defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's primary - GID, the fsGroup (if specified), and group memberships defined - in the container image for the uid of the container process. - If unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image - for the uid of the container process are still effective, - even if they are not included in this list. Note that this - field cannot be set when spec.os.name is windows. + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. items: description: Sysctl defines a kernel parameter to be set properties: @@ -4370,39 +4101,35 @@ spec: type: object type: array windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -4410,19 +4137,20 @@ spec: description: Security Context to apply to the storage container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -4440,59 +4168,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -4512,63 +4241,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -4588,19 +4316,22 @@ spec: creation. type: object httpPort: - description: HTTP port number for the Cryostat application - service. Defaults to 8181. + description: |- + HTTP port number for the Cryostat application service. + Defaults to 8181. format: int32 type: integer jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. + description: |- + Remote JMX port number for the Cryostat application service. + Defaults to 9091. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -4619,14 +4350,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the Grafana dashboard service. + description: |- + HTTP port number for the Grafana dashboard service. Defaults to 3000. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -4645,14 +4378,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the cryostat-reports service. + description: |- + HTTP port number for the cryostat-reports service. Defaults to 10000. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -4671,14 +4406,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the cryostat storage service. + description: |- + HTTP port number for the cryostat storage service. Defaults to 8333 format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -4692,8 +4429,9 @@ spec: and Templates. properties: emptyDir: - description: Configuration for an EmptyDir to be created by the - operator instead of a PVC. + description: |- + Configuration for an EmptyDir to be created + by the operator instead of a PVC. properties: enabled: description: When enabled, Cryostat will use EmptyDir volumes @@ -4701,10 +4439,10 @@ spec: will be ignored. type: boolean medium: - description: Unless specified, the emptyDir volume will be - mounted on the same storage medium backing the node. Setting - this field to "Memory" will mount the emptyDir on a tmpfs - (RAM-backed filesystem). + description: |- + Unless specified, the emptyDir volume will be mounted on + the same storage medium backing the node. Setting this field to + "Memory" will mount the emptyDir on a tmpfs (RAM-backed filesystem). type: string sizeLimit: description: The maximum memory limit for the emptyDir. Default @@ -4713,8 +4451,9 @@ spec: type: string type: object pvc: - description: Configuration for the Persistent Volume Claim to - be created by the operator. + description: |- + Configuration for the Persistent Volume Claim to be created + by the operator. properties: annotations: additionalProperties: @@ -4725,40 +4464,40 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Persistent Volume Claim - during its creation. The label with key "app" is reserved - for use by the operator. + description: |- + Labels to add to the Persistent Volume Claim during its creation. + The label with key "app" is reserved for use by the operator. type: object spec: - description: Spec for a Persistent Volume Claim, whose options - will override the defaults used by the operator. Unless - overriden, the PVC will be created with the default Storage - Class and 500MiB of storage. Once the operator has created - the PVC, changes to this field have no effect. + description: |- + Spec for a Persistent Volume Claim, whose options will override the + defaults used by the operator. Unless overriden, the PVC will be + created with the default Storage Class and 500MiB of storage. + Once the operator has created the PVC, changes to this field have + no effect. properties: accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 items: type: string type: array dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. type: string kind: @@ -4773,39 +4512,35 @@ spec: type: object x-kubernetes-map-type: atomic dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. type: string kind: @@ -4815,43 +4550,43 @@ spec: description: Name is the name of resource being referenced type: string namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. type: string required: - kind - name type: object resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the status - field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + 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. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n This field is immutable. It can only be set for - containers." + 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. + 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 @@ -4867,8 +4602,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -4877,12 +4613,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: - https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object selector: @@ -4893,8 +4628,8 @@ spec: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -4902,17 +4637,16 @@ spec: applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -4924,22 +4658,22 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic storageClassName: - description: 'storageClassName is the name of the StorageClass - required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: |- + 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 volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. type: string volumeName: description: volumeName is the binding reference to the @@ -5007,42 +4741,42 @@ spec: Operator. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -5056,11 +4790,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -5099,21 +4834,27 @@ spec: name: v1beta2 schema: openAPIV3Schema: - description: Cryostat allows you to install Cryostat for a single namespace, - or multiple namespaces. It contains configuration options for controlling - the Deployment of the Cryostat application and its related components. A - Cryostat instance must be created to instruct the operator to deploy the - Cryostat application. + description: |- + Cryostat allows you to install Cryostat for a single namespace, or multiple namespaces. + It contains configuration options for controlling the Deployment of the Cryostat + application and its related components. + A Cryostat instance must be created to instruct the operator + to deploy the Cryostat application. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -5125,12 +4866,10 @@ spec: proxy. properties: basicAuth: - description: Reference to a secret and file name containing the - Basic authentication htpasswd file. If deploying on OpenShift - this defines additional user accounts that can access the Cryostat - application, on top of the OpenShift user accounts which pass - the OpenShift SSO Roles checks. If not on OpenShift then this - defines the only user accounts that have access. + description: |- + Reference to a secret and file name containing the Basic authentication htpasswd file. If deploying on OpenShift this + defines additional user accounts that can access the Cryostat application, on top of the OpenShift user accounts which + pass the OpenShift SSO Roles checks. If not on OpenShift then this defines the only user accounts that have access. properties: filename: description: Name of the file within the secret. @@ -5144,12 +4883,10 @@ spec: OpenShift user accounts may access the Cryostat application. properties: accessReview: - description: The SubjectAccessReview or TokenAccessReview - that all clients (users visiting the application via web - browser as well as CLI utilities and other programs presenting - Bearer auth tokens) must pass in order to access the application. - If not specified, the default role required is "create pods/exec" - in the Cryostat application's installation namespace. + description: |- + The SubjectAccessReview or TokenAccessReview that all clients (users visiting the application via web browser as well + as CLI utilities and other programs presenting Bearer auth tokens) must pass in order to access the application. + If not specified, the default role required is "create pods/exec" in the Cryostat application's installation namespace. properties: group: description: Group is the API Group of the Resource. "*" @@ -5161,13 +4898,11 @@ spec: all. type: string namespace: - description: Namespace is the namespace of the action - being requested. Currently, there is no distinction - between no namespace and all namespaces "" (empty) is - defaulted for LocalSubjectAccessReviews "" (empty) is - empty for cluster-scoped resources "" (empty) means - "all" for namespace scoped resources from a SubjectAccessReview - or SelfSubjectAccessReview + description: |- + Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces + "" (empty) is defaulted for LocalSubjectAccessReviews + "" (empty) is empty for cluster-scoped resources + "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview type: string resource: description: Resource is one of the existing resource @@ -5188,9 +4923,9 @@ spec: type: string type: object disable: - description: Disable OpenShift SSO integration and allow all - users to access the application without authentication. - This will also bypass the BasicAuth, if specified. + description: |- + Disable OpenShift SSO integration and allow all users to access the application without authentication. This + will also bypass the BasicAuth, if specified. type: boolean type: object type: object @@ -5198,19 +4933,18 @@ spec: description: Options to configure the Cryostat application's database. properties: secretName: - description: 'Name of the secret containing database keys. This - secret must contain a CONNECTION_KEY secret which is the database - connection password, and an ENCRYPTION_KEY secret which is the - key used to encrypt sensitive data stored within the database, - such as the target credentials keyring. This field cannot be - updated. It is recommended that the secret should be marked - as immutable to avoid accidental changes to secret''s data. - More details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable' + description: |- + Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the + database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data + stored within the database, such as the target credentials keyring. This field cannot be updated. + It is recommended that the secret should be marked as immutable to avoid accidental changes to secret's data. + More details: https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable type: string type: object enableCertManager: - description: Use cert-manager to secure in-cluster communication between - Cryostat components. Requires cert-manager to be installed. + description: |- + Use cert-manager to secure in-cluster communication between Cryostat components. + Requires cert-manager to be installed. type: boolean eventTemplates: description: List of Flight Recorder Event Templates to preconfigure @@ -5231,11 +4965,13 @@ spec: type: object type: array networkOptions: - description: Options to control how the operator exposes the application - outside of the cluster, such as using an Ingress or Route. + description: |- + Options to control how the operator exposes the application outside of the cluster, + such as using an Ingress or Route. properties: coreConfig: - description: Specifications for how to expose the Cryostat service, + description: |- + Specifications for how to expose the Cryostat service, which serves the Cryostat application. properties: annotations: @@ -5245,32 +4981,30 @@ spec: its creation. type: object ingressSpec: - description: Configuration for an Ingress object. Currently - subpaths are not supported, so unique hosts must be specified - (if a single external IP is being used) to differentiate - between ingresses/services. + description: |- + Configuration for an Ingress object. + Currently subpaths are not supported, so unique hosts must be specified + (if a single external IP is being used) to differentiate between ingresses/services. properties: defaultBackend: - description: defaultBackend is the backend that should - handle requests that don't match any rule. If Rules - are not specified, DefaultBackend must be specified. - If DefaultBackend is not set, the handling of requests - that do not match any of the rules will be up to the - Ingress controller. + description: |- + defaultBackend is the backend that should handle requests that don't + match any rule. If Rules are not specified, DefaultBackend must be specified. + If DefaultBackend is not set, the handling of requests that do not match any + of the rules will be up to the Ingress controller. properties: resource: - description: resource is an ObjectRef to another Kubernetes - resource in the namespace of the Ingress object. - If resource is specified, a service.Name and service.Port - must not be specified. This is a mutually exclusive - setting with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type of resource being @@ -5286,27 +5020,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a service as a backend. + description: |- + service references a service as a backend. This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced service. The - service must exist in the same namespace as - the Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced service. A - port name or port number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name of the port - on the Service. This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the numerical port - number (e.g. 80) on the Service. This is - a mutually exclusive setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -5315,100 +5051,92 @@ spec: type: object type: object ingressClassName: - description: ingressClassName is the name of an IngressClass - cluster resource. Ingress controller implementations - use this field to know whether they should be serving - this Ingress resource, by a transitive connection (controller - -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` - annotation (simple constant name) was never formally - defined, it was widely supported by Ingress controllers - to create a direct binding between Ingress controller - and Ingress resources. Newly created Ingress resources - should prefer using the field. However, even though - the annotation is officially deprecated, for backwards - compatibility reasons, ingress controllers should still - honor that annotation if present. + description: |- + ingressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource, by a transitive connection + (controller -> IngressClass -> Ingress resource). Although the + `kubernetes.io/ingress.class` annotation (simple constant name) was never + formally defined, it was widely supported by Ingress controllers to create + a direct binding between Ingress controller and Ingress resources. Newly + created Ingress resources should prefer using the field. However, even + though the annotation is officially deprecated, for backwards compatibility + reasons, ingress controllers should still honor that annotation if present. type: string rules: - description: rules is a list of host rules used to configure - the Ingress. If unspecified, or no rule matches, all - traffic is sent to the default backend. + description: |- + rules is a list of host rules used to configure the Ingress. If unspecified, + or no rule matches, all traffic is sent to the default backend. items: - description: IngressRule represents the rules mapping - the paths under a specified host to the related backend - services. Incoming requests are first evaluated for - a host match, then routed to the backend associated - with the matching IngressRuleValue. + description: |- + IngressRule represents the rules mapping the paths under a specified host to + the related backend services. Incoming requests are first evaluated for a host + match, then routed to the backend associated with the matching IngressRuleValue. properties: host: description: "host is the fully qualified domain - name of a network host, as defined by RFC 3986. - Note the following deviations from the \"host\" - part of the URI as defined in RFC 3986: 1. IPs - are not allowed. Currently an IngressRuleValue - can only apply to the IP in the Spec of the parent - Ingress. 2. The `:` delimiter is not respected - because ports are not allowed. Currently the port - of an Ingress is implicitly :80 for http and :443 - for https. Both these may change in the future. - Incoming requests are matched against the host - before the IngressRuleValue. If the host is unspecified, - the Ingress routes all traffic based on the specified - IngressRuleValue. \n host can be \"precise\" which - is a domain name without the terminating dot of - a network host (e.g. \"foo.bar.com\") or \"wildcard\", - which is a domain name prefixed with a single - wildcard label (e.g. \"*.foo.com\"). The wildcard - character '*' must appear by itself as the first - DNS label and matches only a single label. You - cannot have a wildcard label by itself (e.g. Host - == \"*\"). Requests will be matched against the - Host field in the following way: 1. If host is - precise, the request matches this rule if the - http host header is equal to Host. 2. If host - is a wildcard, then the request matches this rule - if the http host header is to equal to the suffix - (removing the first label) of the wildcard rule." + name of a network host, as defined by RFC 3986.\nNote + the following deviations from the \"host\" part + of the\nURI as defined in RFC 3986:\n1. IPs are + not allowed. Currently an IngressRuleValue can + only apply to\n the IP in the Spec of the parent + Ingress.\n2. The `:` delimiter is not respected + because ports are not allowed.\n\t Currently + the port of an Ingress is implicitly :80 for http + and\n\t :443 for https.\nBoth these may change + in the future.\nIncoming requests are matched + against the host before the\nIngressRuleValue. + If the host is unspecified, the Ingress routes + all\ntraffic based on the specified IngressRuleValue.\n\n\nhost + can be \"precise\" which is a domain name without + the terminating dot of\na network host (e.g. \"foo.bar.com\") + or \"wildcard\", which is a domain name\nprefixed + with a single wildcard label (e.g. \"*.foo.com\").\nThe + wildcard character '*' must appear by itself as + the first DNS label and\nmatches only a single + label. You cannot have a wildcard label by itself + (e.g. Host == \"*\").\nRequests will be matched + against the Host field in the following way:\n1. + If host is precise, the request matches this rule + if the http host header is equal to Host.\n2. + If host is a wildcard, then the request matches + this rule if the http host header\nis to equal + to the suffix (removing the first label) of the + wildcard rule." type: string http: - description: 'HTTPIngressRuleValue is a list of - http selectors pointing to backends. In the example: - http:///? -> backend where - where parts of the url correspond to RFC 3986, - this resource will be used to match against everything - after the last ''/'' and before the first ''?'' - or ''#''.' + description: |- + HTTPIngressRuleValue is a list of http selectors pointing to backends. + In the example: http:///? -> backend where + where parts of the url correspond to RFC 3986, this resource will be used + to match against everything after the last '/' and before the first '?' + or '#'. properties: paths: description: paths is a collection of paths that map requests to backends. items: - description: HTTPIngressPath associates a - path with a backend. Incoming urls matching - the path are forwarded to the backend. + description: |- + HTTPIngressPath associates a path with a backend. Incoming urls matching the + path are forwarded to the backend. properties: backend: - description: backend defines the referenced - service endpoint to which the traffic + description: |- + backend defines the referenced service endpoint to which the traffic will be forwarded to. properties: resource: - description: resource is an ObjectRef - to another Kubernetes resource in - the namespace of the Ingress object. - If resource is specified, a service.Name - and service.Port must not be specified. - This is a mutually exclusive setting - with "Service". + description: |- + resource is an ObjectRef to another Kubernetes resource in the namespace + of the Ingress object. If resource is specified, a service.Name and + service.Port must not be specified. + This is a mutually exclusive setting with "Service". properties: apiGroup: - description: APIGroup is the group - for the resource being referenced. - If APIGroup is not specified, - the specified Kind must be in - the core API group. For any - other third-party types, APIGroup - is required. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. type: string kind: description: Kind is the type @@ -5424,34 +5152,29 @@ spec: type: object x-kubernetes-map-type: atomic service: - description: service references a - service as a backend. This is a - mutually exclusive setting with - "Resource". + description: |- + service references a service as a backend. + This is a mutually exclusive setting with "Resource". properties: name: - description: name is the referenced - service. The service must exist - in the same namespace as the - Ingress object. + description: |- + name is the referenced service. The service must exist in + the same namespace as the Ingress object. type: string port: - description: port of the referenced - service. A port name or port - number is required for a IngressServiceBackend. + description: |- + port of the referenced service. A port name or port number + is required for a IngressServiceBackend. properties: name: - description: name is the name - of the port on the Service. - This is a mutually exclusive - setting with "Number". + description: |- + name is the name of the port on the Service. + This is a mutually exclusive setting with "Number". type: string number: - description: number is the - numerical port number (e.g. - 80) on the Service. This - is a mutually exclusive - setting with "Name". + description: |- + number is the numerical port number (e.g. 80) on the Service. + This is a mutually exclusive setting with "Name". format: int32 type: integer type: object @@ -5460,39 +5183,28 @@ spec: type: object type: object path: - description: path is matched against the - path of an incoming request. Currently - it can contain characters disallowed - from the conventional "path" part of - a URL as defined by RFC 3986. Paths - must begin with a '/' and must be present - when using PathType with value "Exact" - or "Prefix". + description: |- + path is matched against the path of an incoming request. Currently it can + contain characters disallowed from the conventional "path" part of a URL + as defined by RFC 3986. Paths must begin with a '/' and must be present + when using PathType with value "Exact" or "Prefix". type: string pathType: - description: 'pathType determines the - interpretation of the path matching. - PathType can be one of the following - values: * Exact: Matches the URL path - exactly. * Prefix: Matches based on - a URL path prefix split by ''/''. Matching - is done on a path element by element - basis. A path element refers is the - list of labels in the path split by - the ''/'' separator. A request is a - match for path p if every p is an element-wise - prefix of p of the request path. Note - that if the last element of the path - is a substring of the last element in - request path, it is not a match (e.g. - /foo/bar matches /foo/bar/baz, but does - not match /foo/barbaz). * ImplementationSpecific: - Interpretation of the Path matching - is up to the IngressClass. Implementations - can treat this as a separate PathType - or treat it identically to Prefix or - Exact path types. Implementations are - required to support all path types.' + description: |- + pathType determines the interpretation of the path matching. PathType can + be one of the following values: + * Exact: Matches the URL path exactly. + * Prefix: Matches based on a URL path prefix split by '/'. Matching is + done on a path element by element basis. A path element refers is the + list of labels in the path split by the '/' separator. A request is a + match for path p if every p is an element-wise prefix of p of the + request path. Note that if the last element of the path is a substring + of the last element in request path, it is not a match (e.g. /foo/bar + matches /foo/bar/baz, but does not match /foo/barbaz). + * ImplementationSpecific: Interpretation of the Path matching is up to + the IngressClass. Implementations can treat this as a separate PathType + or treat it identically to Prefix or Exact path types. + Implementations are required to support all path types. type: string required: - backend @@ -5507,34 +5219,32 @@ spec: type: array x-kubernetes-list-type: atomic tls: - description: tls represents the TLS configuration. Currently - the Ingress only supports a single TLS port, 443. If - multiple members of this list specify different hosts, - they will be multiplexed on the same port according - to the hostname specified through the SNI TLS extension, - if the ingress controller fulfilling the ingress supports - SNI. + description: |- + tls represents the TLS configuration. Currently the Ingress only supports a + single TLS port, 443. If multiple members of this list specify different hosts, + they will be multiplexed on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller fulfilling the + ingress supports SNI. items: description: IngressTLS describes the transport layer security associated with an ingress. properties: hosts: - description: hosts is a list of hosts included in - the TLS certificate. The values in this list must - match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. items: type: string type: array x-kubernetes-list-type: atomic secretName: - description: secretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination and value of the "Host" header is used for routing. type: string type: object @@ -5544,9 +5254,9 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Ingress or Route during - its creation. The label with key "app" is reserved for use - by the operator. + description: |- + Labels to add to the Ingress or Route during its creation. + The label with key "app" is reserved for use by the operator. type: object type: object type: object @@ -5566,7 +5276,8 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the resources during its creation. + description: |- + Labels to add to the resources during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -5583,7 +5294,8 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the resources during its creation. + description: |- + Labels to add to the resources during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -5593,30 +5305,35 @@ spec: description: Options to configure Cryostat Automated Report Analysis. properties: replicas: - description: The number of report sidecar replica containers to - deploy. Each replica can service one report generation request - at a time. + description: |- + The number of report sidecar replica containers to deploy. + Each replica can service one report generation request at a time. format: int32 type: integer resources: - description: The resources allocated to each sidecar replica. - A replica with more resources can handle larger input recordings - and will process them faster. + description: |- + The resources allocated to each sidecar replica. + A replica with more resources can handle larger input recordings and will process them faster. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -5632,8 +5349,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -5642,11 +5360,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object schedulingOptions: @@ -5660,23 +5378,20 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling term - matches all objects with implicit weight 0 (i.e. - it's a no-op). A null preferred scheduling term - matches no objects (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated @@ -5686,32 +5401,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5724,32 +5433,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5772,53 +5475,46 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to an update), the system may or may not try - to eventually evict the pod from its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5831,32 +5527,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. - If the operator is Gt or Lt, the - values array must have a single - element, which will be interpreted - as an integer. This array is replaced - during a strategic merge patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -5878,19 +5568,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if - the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -5909,10 +5596,9 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5920,20 +5606,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -5945,36 +5627,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -5982,20 +5657,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6007,46 +5678,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -6055,25 +5717,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - affinity requirements specified by this field cease - to be met at some point during pod execution (e.g. - due to a pod label update), the system may or may - not try to eventually evict the pod from its node. - When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, - i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -6084,30 +5743,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6119,53 +5773,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6177,34 +5823,28 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: @@ -6217,19 +5857,16 @@ spec: Cryostat pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule - pods to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the - greatest sum of weights, i.e. for each node that - meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity - expressions, etc.), compute a sum by iterating through - the elements of this field and adding "weight" to - the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum - are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -6248,10 +5885,9 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6259,20 +5895,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6284,36 +5916,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label @@ -6321,20 +5946,16 @@ spec: to. type: string operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. - This array is replaced during - a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6346,46 +5967,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of - {key,value} pairs. A single {key,value} - in the matchLabels map is equivalent - to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are - ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static - list of namespace names that the term - applies to. The term is applied to the - union of the namespaces listed in this - field and the ones selected by namespaceSelector. - null or empty namespaces list and null - namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose - value of the label with key topologyKey - matches that of any node on which any - of the selected pods is running. Empty - topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching - the corresponding podAffinityTerm, in the - range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -6394,25 +6006,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the - anti-affinity requirements specified by this field - cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may - or may not try to eventually evict the pod from - its node. When there are multiple elements, the - lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those - matching the labelSelector relative to the given - namespace(s)) that this pod should be co-located - (affinity) or not co-located (anti-affinity) with, - where co-located is defined as running on a node - whose value of the label with key - matches that of any node on which a pod of the - set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -6423,30 +6032,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6458,53 +6062,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -6516,34 +6112,28 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: @@ -6562,42 +6152,39 @@ spec: description: 'Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period - of time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration - matches to. If the operator is Exists, the value should - be empty, otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -6611,66 +6198,68 @@ spec: generator pod. properties: fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow - the Kubelet to change the ownership of that volume to - be owned by the pod: \n 1. The owning GID will be the - FSGroup 2. The setgid bit is set (new files created - in the volume will be owned by FSGroup) 3. The permission - bits are OR'd with rw-rw---- \n If unset, the Kubelet - will not modify the ownership and permissions of any - volume. Note that this field cannot be set when spec.os.name - is windows." + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of - changing ownership and permission of the volume before - being exposed inside Pod. This field will only apply - to volume types which support fsGroup based ownership(and - permissions). It will have no effect on ephemeral volume - types such as: secret, configmaps and emptydir. Valid - values are "OnRootMismatch" and "Always". If not specified, - "Always" is used. Note that this field cannot be set - when spec.os.name is windows.' + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. type: string runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to all - containers. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this - field cannot be set when spec.os.name is windows. + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -6690,50 +6279,48 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by the containers - in this pod. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The seccomp 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 - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must be set - if type is "Localhost". Must NOT be set for any - other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID, the fsGroup (if specified), and group memberships - defined in the container image for the uid of the container - process. If unspecified, no additional groups are added - to any container. Note that group memberships defined - in the container image for the uid of the container - process are still effective, even if they are not included - in this list. Note that this field cannot be set when - spec.os.name is windows. + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array sysctls: - description: Sysctls hold a list of namespaced sysctls - used for the pod. Pods with unsupported sysctls (by - the container runtime) might fail to launch. Note that - this field cannot be set when spec.os.name is windows. + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. items: description: Sysctl defines a kernel parameter to be set @@ -6750,39 +6337,35 @@ spec: type: object type: array windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options within a - container's SecurityContext will be used. If set in - both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. All - of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork - must also be set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -6791,19 +6374,20 @@ spec: generator container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag - will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -6821,61 +6405,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that this - field cannot be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if it - does. If unset or false, no such validation will be - performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -6895,75 +6478,71 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name - is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. The - profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's - configured seccomp profile location. Must be set - if type is "Localhost". Must NOT be set for any - other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should - be used. RuntimeDefault - the container runtime - default profile should be used. Unconfined - no - profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. All - of a Pod's containers must have the same effective - HostProcess value (it is not allowed to have a mix - of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork - must also be set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object type: object subProcessMaxHeapSize: - description: When zero report sidecar replicas are requested, - SubProcessMaxHeapSize configures the maximum heap size of the - basic subprocess report generator in MiB. The default heap size - is `200` (MiB). + description: |- + When zero report sidecar replicas are requested, SubProcessMaxHeapSize configures + the maximum heap size of the basic subprocess report generator in MiB. + The default heap size is `200` (MiB). format: int32 type: integer type: object @@ -6974,19 +6553,24 @@ spec: description: Resource requirements for the auth proxy. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7002,8 +6586,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7012,11 +6597,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object coreResources: @@ -7024,19 +6609,24 @@ spec: If specifying a memory limit, at least 384MiB is recommended. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7052,8 +6642,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7062,30 +6653,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object dataSourceResources: description: Resource requirements for the JFR Data Source container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7101,8 +6697,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7111,30 +6708,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object databaseResources: description: Resource requirements for the database container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7150,8 +6752,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7160,30 +6763,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object grafanaResources: description: Resource requirements for the Grafana container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7199,8 +6807,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7209,30 +6818,35 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object objectStorageResources: description: Resource requirements for the object storage container. properties: claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be - set for containers." + 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. + 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 @@ -7248,8 +6862,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -7258,11 +6873,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed - Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object type: object @@ -7277,22 +6892,20 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#NodeAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). properties: preference: description: A node selector term, associated with @@ -7302,32 +6915,26 @@ spec: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7340,32 +6947,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7387,53 +6988,46 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. properties: nodeSelectorTerms: description: Required. A list of node selector terms. The terms are ORed. items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. properties: matchExpressions: description: A list of node selector requirements by node's labels. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7446,32 +7040,26 @@ spec: description: A list of node selector requirements by node's fields. items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. properties: key: description: The label key that the selector applies to. type: string operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. type: string values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. items: type: string type: array @@ -7493,18 +7081,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -7523,30 +7109,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7558,53 +7139,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7616,42 +7189,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -7660,23 +7228,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -7687,28 +7254,24 @@ spec: selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7721,51 +7284,44 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -7778,33 +7334,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -7816,18 +7368,16 @@ spec: pod. See: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodAntiAffinity' properties: preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. items: description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred @@ -7846,30 +7396,25 @@ spec: of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7881,53 +7426,45 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -7939,42 +7476,37 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. - The term is applied to the union of the namespaces - listed in this field and the ones selected - by namespaceSelector. null or empty namespaces - list and null namespaceSelector means "this - pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. Empty topologyKey is not allowed. type: string required: - topologyKey type: object weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. format: int32 type: integer required: @@ -7983,23 +7515,22 @@ spec: type: object type: array requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running properties: labelSelector: description: A label query over a set of resources, @@ -8010,28 +7541,24 @@ spec: selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8044,51 +7571,44 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-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. + 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. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic merge patch. items: type: string @@ -8101,33 +7621,29 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". items: type: string type: array topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. type: string required: - topologyKey @@ -8145,41 +7661,39 @@ spec: description: 'Tolerations to allow scheduling of Cryostat pods to tainted nodes. See: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/' items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . properties: effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. type: string key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. type: string operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. type: string tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. format: int64 type: integer value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. type: string type: object type: array @@ -8192,19 +7706,20 @@ spec: description: Security Context to apply to the auth proxy container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8222,59 +7737,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8294,63 +7810,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -8359,19 +7874,20 @@ spec: container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8389,59 +7905,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8461,63 +7978,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -8526,19 +8042,20 @@ spec: container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8556,59 +8073,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8628,63 +8146,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -8692,19 +8209,20 @@ spec: description: Security Context to apply to the database container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8722,59 +8240,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8794,63 +8313,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -8858,19 +8376,20 @@ spec: description: Security Context to apply to the Grafana container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -8888,59 +8407,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -8960,63 +8480,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -9024,63 +8543,68 @@ spec: description: Security Context to apply to the Cryostat pod. properties: fsGroup: - description: "A special supplemental group that applies to - all containers in a pod. Some volume types allow the Kubelet - to change the ownership of that volume to be owned by the - pod: \n 1. The owning GID will be the FSGroup 2. The setgid - bit is set (new files created in the volume will be owned - by FSGroup) 3. The permission bits are OR'd with rw-rw---- - \n If unset, the Kubelet will not modify the ownership and - permissions of any volume. Note that this field cannot be - set when spec.os.name is windows." + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will - have no effect on ephemeral volume types such as: secret, - configmaps and emptydir. Valid values are "OnRootMismatch" - and "Always". If not specified, "Always" is used. Note that - this field cannot be set when spec.os.name is windows.' + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. type: string runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field - cannot be set when spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is - windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - SecurityContext. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence - for that container. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -9100,47 +8624,48 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by the containers - in this pod. Note that this field cannot be set when spec.os.name - is windows. + description: |- + The seccomp 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 defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's primary - GID, the fsGroup (if specified), and group memberships defined - in the container image for the uid of the container process. - If unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image - for the uid of the container process are still effective, - even if they are not included in this list. Note that this - field cannot be set when spec.os.name is windows. + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. items: description: Sysctl defines a kernel parameter to be set properties: @@ -9156,39 +8681,35 @@ spec: type: object type: array windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -9196,19 +8717,20 @@ spec: description: Security Context to apply to the storage container. properties: allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether a - process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. type: boolean capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the - container runtime. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. properties: add: description: Added capabilities @@ -9226,59 +8748,60 @@ spec: type: array type: object privileged: - description: Run container in privileged mode. Processes in - privileged containers are essentially equivalent to root - on the host. Defaults to false. Note that this field cannot - be set when spec.os.name is windows. + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. type: boolean procMount: - description: procMount denotes the type of proc mount to use - for the containers. The default is DefaultProcMount which - uses the container runtime defaults for readonly paths and - masked paths. This requires the ProcMountType feature flag - to be enabled. Note that this field cannot be set when spec.os.name - is windows. + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. type: string readOnlyRootFilesystem: - description: Whether this container has a read-only root filesystem. - Default is false. Note that this field cannot be set when - spec.os.name is windows. + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. type: boolean runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail - to start the container if it does. If unset or false, no - such validation will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: boolean runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata if - unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. properties: level: description: Level is SELinux level label that applies @@ -9298,63 +8821,62 @@ spec: type: string type: object seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. Note - that this field cannot be set when spec.os.name is windows. + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. properties: localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must - be preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT - be set for any other type. + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a - profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile - should be used. Unconfined - no profile should be applied." + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. type: string required: - type type: object windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. properties: gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. type: string gmsaCredentialSpecName: description: GMSACredentialSpecName is the name of the GMSA credential spec to use. type: string hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also be - set to true. + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence. + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. type: string type: object type: object @@ -9374,14 +8896,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the Cryostat application - service. Defaults to 8181. + description: |- + HTTP port number for the Cryostat application service. + Defaults to 8181. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -9400,14 +8924,16 @@ spec: creation. type: object httpPort: - description: HTTP port number for the cryostat-reports service. + description: |- + HTTP port number for the cryostat-reports service. Defaults to 10000. format: int32 type: integer labels: additionalProperties: type: string - description: Labels to add to the service during its creation. + description: |- + Labels to add to the service during its creation. The labels with keys "app" and "component" are reserved for use by the operator. type: object @@ -9421,8 +8947,9 @@ spec: database and object storage. properties: emptyDir: - description: Configuration for an EmptyDir to be created by the - operator instead of a PVC. + description: |- + Configuration for an EmptyDir to be created + by the operator instead of a PVC. properties: enabled: description: When enabled, Cryostat will use EmptyDir volumes @@ -9430,10 +8957,10 @@ spec: will be ignored. type: boolean medium: - description: Unless specified, the emptyDir volume will be - mounted on the same storage medium backing the node. Setting - this field to "Memory" will mount the emptyDir on a tmpfs - (RAM-backed filesystem). + description: |- + Unless specified, the emptyDir volume will be mounted on + the same storage medium backing the node. Setting this field to + "Memory" will mount the emptyDir on a tmpfs (RAM-backed filesystem). type: string sizeLimit: description: The maximum memory limit for the emptyDir. Default @@ -9442,8 +8969,9 @@ spec: type: string type: object pvc: - description: Configuration for the Persistent Volume Claim to - be created by the operator. + description: |- + Configuration for the Persistent Volume Claim to be created + by the operator. properties: annotations: additionalProperties: @@ -9454,40 +8982,40 @@ spec: labels: additionalProperties: type: string - description: Labels to add to the Persistent Volume Claim - during its creation. The label with key "app" is reserved - for use by the operator. + description: |- + Labels to add to the Persistent Volume Claim during its creation. + The label with key "app" is reserved for use by the operator. type: object spec: - description: Spec for a Persistent Volume Claim, whose options - will override the defaults used by the operator. Unless - overriden, the PVC will be created with the default Storage - Class and 500MiB of storage. Once the operator has created - the PVC, changes to this field have no effect. + description: |- + Spec for a Persistent Volume Claim, whose options will override the + defaults used by the operator. Unless overriden, the PVC will be + created with the default Storage Class and 500MiB of storage. + Once the operator has created the PVC, changes to this field have + no effect. properties: accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 items: type: string type: array dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. type: string kind: @@ -9502,39 +9030,35 @@ spec: type: object x-kubernetes-map-type: atomic dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. properties: apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. type: string kind: @@ -9544,43 +9068,43 @@ spec: description: Name is the name of resource being referenced type: string namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. type: string required: - kind - name type: object resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the status - field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + 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. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n This field is immutable. It can only be set for - containers." + 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. + 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 @@ -9596,8 +9120,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -9606,12 +9131,11 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: - https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object selector: @@ -9622,8 +9146,8 @@ spec: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -9631,17 +9155,16 @@ spec: applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -9653,22 +9176,22 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic storageClassName: - description: 'storageClassName is the name of the StorageClass - required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: |- + 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 volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. type: string volumeName: description: volumeName is the binding reference to the @@ -9728,10 +9251,12 @@ spec: type: array type: object targetNamespaces: - description: 'List of namespaces whose workloads Cryostat should be - permitted to access and profile. Defaults to this Cryostat''s namespace. - Warning: All Cryostat users will be able to create and manage recordings - for workloads in the listed namespaces. More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation' + description: |- + List of namespaces whose workloads Cryostat should be + permitted to access and profile. Defaults to this Cryostat's namespace. + Warning: All Cryostat users will be able to create and manage + recordings for workloads in the listed namespaces. + More details: https://github.com/cryostatio/cryostat-operator/blob/v2.4.0/docs/multi-namespace.md#data-isolation items: type: string type: array @@ -9762,42 +9287,42 @@ spec: Operator. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -9811,11 +9336,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -9836,7 +9362,8 @@ spec: key. type: string targetNamespaces: - description: List of namespaces that Cryostat has been configured + description: |- + List of namespaces that Cryostat has been configured and authorized to access and profile. items: type: string diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index cbdf8900e..b629f3e36 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -2,7 +2,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: role rules: - apiGroups: @@ -182,7 +181,6 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - creationTimestamp: null name: role namespace: system rules: diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 39f016e00..8bd6292db 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -2,7 +2,6 @@ apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: - creationTimestamp: null name: mutating-webhook-configuration webhooks: - admissionReviewVersions: @@ -29,7 +28,6 @@ webhooks: apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: - creationTimestamp: null name: validating-webhook-configuration webhooks: - admissionReviewVersions: