diff --git a/fleetshard/config/config.go b/fleetshard/config/config.go index 96cb7f4b32..543a3551b8 100644 --- a/fleetshard/config/config.go +++ b/fleetshard/config/config.go @@ -28,6 +28,7 @@ type Config struct { MetricsAddress string `env:"FLEETSHARD_METRICS_ADDRESS" envDefault:":8080"` EgressProxyImage string `env:"EGRESS_PROXY_IMAGE"` FeatureFlagUpgradeOperatorEnabled bool `env:"FEATURE_FLAG_UPGRADE_OPERATOR_ENABLED" envDefault:"false"` + BaseCrdURL string `env:"BASE_CRD_URL" envDefault:"https://raw.githubusercontent.com/stackrox/stackrox/%s/operator/bundle/manifests/"` AWS AWS ManagedDB ManagedDB diff --git a/fleetshard/pkg/central/charts/charts.go b/fleetshard/pkg/central/charts/charts.go index 4c656a89b0..8f90910ed0 100644 --- a/fleetshard/pkg/central/charts/charts.go +++ b/fleetshard/pkg/central/charts/charts.go @@ -5,7 +5,9 @@ import ( "context" "embed" "fmt" + "io" "io/fs" + "net/http" "path" "strings" @@ -26,8 +28,8 @@ var ( data embed.FS ) -// LoadChart loads a chart from the given path on the given file system. -func LoadChart(fsys fs.FS, chartPath string) (*chart.Chart, error) { +// TraverseChart combines all chart files into memory from given file system +func TraverseChart(fsys fs.FS, chartPath string) ([]*loader.BufferedFile, error) { chartPath = strings.TrimRight(chartPath, "/") var chartFiles []*loader.BufferedFile err := fs.WalkDir(fsys, chartPath, func(path string, d fs.DirEntry, err error) error { @@ -50,22 +52,72 @@ func LoadChart(fsys fs.FS, chartPath string) (*chart.Chart, error) { if err != nil { return nil, fmt.Errorf("loading chart from %q: %w", chartPath, err) } + return chartFiles, nil +} - chrt, err := loader.LoadFiles(chartFiles) +func downloadTemplates(urls []string) ([]*loader.BufferedFile, error) { + var chartFiles []*loader.BufferedFile + for _, url := range urls { + buffered, err := downloadTemplate(url) + if err != nil { + return nil, fmt.Errorf("failed downloading template from %s: %w", url, err) + } + chartFiles = append(chartFiles, buffered) + } + return chartFiles, nil +} + +func downloadTemplate(url string) (*loader.BufferedFile, error) { + resp, err := http.Get(url) if err != nil { - return nil, fmt.Errorf("loading chart from %s: %w", chartPath, err) + return nil, fmt.Errorf("failed Get for %s: %w", url, err) + } + defer resp.Body.Close() + + bytes, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("cannot read bytes: %w", err) + } + + // parse filename from the URL + if !strings.Contains(url, "/") { + return nil, fmt.Errorf("cannot parse filename from %s", url) + } + filename := url[strings.LastIndex(url, "/")+1:] + name := path.Join("templates", filename) + + bufferedFile := &loader.BufferedFile{ + Name: name, + Data: bytes, } - return chrt, nil + + return bufferedFile, nil } // GetChart loads a chart from the data directory. The name should be the name of the containing directory. -func GetChart(name string) (*chart.Chart, error) { - return LoadChart(data, path.Join("data", name)) +// Optional: pass list of URLs to download additional template files for the chart. +func GetChart(name string, urls []string) (*chart.Chart, error) { + chartFiles, err := TraverseChart(data, path.Join("data", name)) + if err != nil { + return nil, fmt.Errorf("failed getting chart files for %q: %w", name, err) + } + if len(urls) > 0 { + downloadedFiles, err := downloadTemplates(urls) + if err != nil { + return nil, fmt.Errorf("failed downloading chart files %q: %w", name, err) + } + chartFiles = append(chartFiles, downloadedFiles...) + } + loadedChart, err := loader.LoadFiles(chartFiles) + if err != nil { + return nil, fmt.Errorf("failed loading chart %q: %w", name, err) + } + return loadedChart, nil } // MustGetChart loads a chart from the data directory. Unlike GetChart, it panics if an error is encountered. -func MustGetChart(name string) *chart.Chart { - chrt, err := GetChart(name) +func MustGetChart(name string, urls []string) *chart.Chart { + chrt, err := GetChart(name, urls) if err != nil { panic(err) } diff --git a/fleetshard/pkg/central/charts/charts_test.go b/fleetshard/pkg/central/charts/charts_test.go index cf579391e4..36a476d50b 100644 --- a/fleetshard/pkg/central/charts/charts_test.go +++ b/fleetshard/pkg/central/charts/charts_test.go @@ -9,6 +9,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ctrlClient "sigs.k8s.io/controller-runtime/pkg/client" + "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/chartutil" "github.com/stretchr/testify/assert" @@ -34,13 +35,15 @@ var dummyDeployment = &appsv1.Deployment{ } func TestTenantResourcesChart(t *testing.T) { - c, err := GetChart("tenant-resources") + c, err := GetChart("tenant-resources", nil) require.NoError(t, err) assert.NotNil(t, c) } func TestInstallOrUpdateChartCreateNew(t *testing.T) { - chart, err := LoadChart(testdata, "testdata/test-chart") + chartFiles, err := TraverseChart(testdata, "testdata/test-chart") + require.NoError(t, err) + chart, err := loader.LoadFiles(chartFiles) require.NoError(t, err) fakeClient := testutils.NewFakeClientBuilder(t).Build() ctx := context.Background() @@ -67,7 +70,9 @@ func TestInstallOrUpdateChartCreateNew(t *testing.T) { } func TestInstallOrUpdateChartUpdateExisting(t *testing.T) { - chart, err := LoadChart(testdata, "testdata/test-chart") + chartFiles, err := TraverseChart(testdata, "testdata/test-chart") + require.NoError(t, err) + chart, err := loader.LoadFiles(chartFiles) require.NoError(t, err) fakeClient := testutils.NewFakeClientBuilder(t, dummyDeployment).Build() ctx := context.Background() @@ -92,3 +97,12 @@ func TestInstallOrUpdateChartUpdateExisting(t *testing.T) { assert.NotEmpty(t, res.GetLabels()) assert.Equal(t, "baz", res.GetLabels()["foo"]) } + +func TestGetChartWithDynamicTemplate(t *testing.T) { + crdURL := "https://raw.githubusercontent.com/stackrox/stackrox/master/operator/bundle/manifests/platform.stackrox.io_securedclusters.yaml" + dynamicTemplates := []string{crdURL} + + c, err := GetChart("rhacs-operator", dynamicTemplates) + require.NoError(t, err) + assert.NotNil(t, c) +} diff --git a/fleetshard/pkg/central/charts/data/rhacs-operator/templates/platform.stackrox.io_centrals.yaml b/fleetshard/pkg/central/charts/data/rhacs-operator/templates/platform.stackrox.io_centrals.yaml deleted file mode 100644 index 6810f31761..0000000000 --- a/fleetshard/pkg/central/charts/data/rhacs-operator/templates/platform.stackrox.io_centrals.yaml +++ /dev/null @@ -1,947 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - name: centrals.platform.stackrox.io -spec: - group: platform.stackrox.io - names: - kind: Central - listKind: CentralList - plural: centrals - singular: central - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Central is the configuration template for the central services. - This includes the API server, persistent storage, and the web UI, as well - as the image scanner. - 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: CentralSpec defines the desired state of Central - properties: - central: - description: Settings for the Central component, which is responsible - for all user interaction. - properties: - adminPasswordGenerationDisabled: - description: Disable admin password generation. Do not use this - for first-time installations, as you will have no way to perform - initial setup and configuration of alternative authentication - methods. - type: boolean - adminPasswordSecret: - description: Specify a secret that contains the administrator - password in the "password" data item. If omitted, the operator - will auto-generate a password and store it in the "password" - item in the "central-htpasswd" secret. - properties: - name: - description: The name of the referenced secret. - type: string - required: - - name - type: object - db: - description: 'NOTE: Central DB is in Technology Preview. Settings - for Central DB, which is responsible for data persistence.' - properties: - connectionString: - description: Specify a connection string that corresponds - to an existing database. If set, the operator will not manage - Central DB. When using this option, you must explicitly - set a password secret; automatically generating a password - will not be supported. - type: string - isEnabled: - default: Default - description: Specify whether central-db is enabled, Default - configures central to use rocksdb. If IsEnabled the operator - will provision the Central DB or use an external DB if a - connection string is provided. - enum: - - Default - - Enabled - type: string - nodeSelector: - additionalProperties: - type: string - description: If you want this component to only run on specific - nodes, you can configure a node selector here. - type: object - passwordSecret: - description: Specify a secret that contains the password in - the "password" data item. If omitted, the operator will - auto-generate a DB password and store it in the "password" - item in the "central-db-password" secret. - properties: - name: - description: The name of the referenced secret. - type: string - required: - - name - type: object - persistence: - description: Configures how Central DB should store its persistent - data. You can choose between using a persistent volume claim - (recommended default), and a host path. - properties: - hostPath: - description: Stores persistent data on a directory on - the host. This is not recommended, and should only be - used together with a node selector (only available in - YAML view). - properties: - path: - description: The path on the host running Central. - type: string - type: object - persistentVolumeClaim: - description: Uses a Kubernetes persistent volume claim - (PVC) to manage the storage location of persistent data. - Recommended for most users. - properties: - claimName: - default: central-db - description: The name of the PVC to manage persistent - data. If no PVC with the given name exists, it will - be created. Defaults to "central-db" if not set. - type: string - size: - description: The size of the persistent volume when - created through the claim. If a claim was automatically - created, this can be used after the initial deployment - to resize (grow) the volume (only supported by some - storage class controllers). - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - type: string - storageClassName: - description: The name of the storage class to use - for the PVC. If your cluster is not configured with - a default storage class, you must select a value - here. - type: string - type: object - type: object - resources: - description: Allows overriding the default resource settings - for this component. Please consult the documentation for - an overview of default resource requirements and a sizing - guide. - properties: - 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 - tolerations: - description: If you want this component to only run on specific - nodes, you can configure tolerations of tainted nodes. - 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 - declarativeConfiguration: - description: Configures resources within Central in a declarative - manner. - properties: - configMaps: - description: List of config maps containing declarative configuration. - items: - description: LocalConfigMapReference is a reference to a - config map within the same namespace. - properties: - name: - description: The name of the referenced config map. - type: string - required: - - name - type: object - type: array - secrets: - description: List of secrets containing declarative configuration. - items: - description: LocalSecretReference is a reference to a secret - within the same namespace. - properties: - name: - description: The name of the referenced secret. - type: string - required: - - name - type: object - type: array - type: object - defaultTLSSecret: - description: By default, Central will only serve an internal TLS - certificate, which means that you will need to handle TLS termination - at the ingress or load balancer level. If you want to terminate - TLS in Central and serve a custom server certificate, you can - specify a secret containing the certificate and private key - here. - properties: - name: - description: The name of the referenced secret. - type: string - required: - - name - type: object - exposure: - description: Here you can configure if you want to expose central - through a node port, a load balancer, or an OpenShift route. - properties: - loadBalancer: - description: Expose Central through a load balancer service. - properties: - enabled: - default: false - type: boolean - ip: - description: If you have a static IP address reserved - for your load balancer, you can enter it here. - type: string - port: - default: 443 - description: Defaults to 443 if not set. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - type: object - nodePort: - description: Expose Central through a node port. - properties: - enabled: - default: false - type: boolean - port: - description: Use this to specify an explicit node port. - Most users should leave this empty. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - type: object - route: - description: Expose Central through an OpenShift route. - properties: - enabled: - default: false - type: boolean - host: - description: Specify a custom hostname for the central - route. If unspecified, an appropriate default value - will be automatically chosen by OpenShift route operator. - type: string - type: object - type: object - monitoring: - description: Configures monitoring endpoint for Central. The monitoring - endpoint allows other services to collect metrics from Central, - provided in Prometheus compatible format. - properties: - exposeEndpoint: - description: Expose the monitoring endpoint. A new service, - "monitoring", with port 9090, will be created as well as - a network policy allowing inbound connections to the port. - enum: - - Enabled - - Disabled - type: string - type: object - nodeSelector: - additionalProperties: - type: string - description: If you want this component to only run on specific - nodes, you can configure a node selector here. - type: object - persistence: - description: Configures how Central should store its persistent - data. You can choose between using a persistent volume claim - (recommended default), and a host path. - properties: - hostPath: - description: Stores persistent data on a directory on the - host. This is not recommended, and should only be used together - with a node selector (only available in YAML view). - properties: - path: - description: The path on the host running Central. - type: string - type: object - persistentVolumeClaim: - description: Uses a Kubernetes persistent volume claim (PVC) - to manage the storage location of persistent data. Recommended - for most users. - properties: - claimName: - default: stackrox-db - description: The name of the PVC to manage persistent - data. If no PVC with the given name exists, it will - be created. Defaults to "stackrox-db" if not set. - type: string - size: - description: The size of the persistent volume when created - through the claim. If a claim was automatically created, - this can be used after the initial deployment to resize - (grow) the volume (only supported by some storage class - controllers). - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - type: string - storageClassName: - description: The name of the storage class to use for - the PVC. If your cluster is not configured with a default - storage class, you must select a value here. - type: string - type: object - type: object - resources: - description: Allows overriding the default resource settings for - this component. Please consult the documentation for an overview - of default resource requirements and a sizing guide. - properties: - 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 - telemetry: - description: Configures telemetry settings for Central. If enabled, - Central transmits telemetry and diagnostic data to a remote - storage backend. - properties: - enabled: - description: Specifies if Telemetry is enabled. - type: boolean - storage: - description: Defines the telemetry storage backend for Central. - properties: - endpoint: - description: Storage API endpoint. - type: string - key: - description: Storage API key. If not set, telemetry is - disabled. - type: string - type: object - type: object - tolerations: - description: If you want this component to only run on specific - nodes, you can configure tolerations of tainted nodes. - 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 - customize: - description: Customizations to apply on all Central Services components. - properties: - annotations: - additionalProperties: - type: string - description: Custom annotations to set on all managed objects. - type: object - envVars: - description: Custom environment variables to set on managed pods' - containers. - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. If - a variable cannot be resolved, the reference in the input - string will be unchanged. Double $$ are reduced to a single - $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: 'Selects a field of the pod: supports metadata.name, - metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: 'Selects a resource of the container: only - resources limits and requests (limits.cpu, limits.memory, - limits.ephemeral-storage, requests.cpu, requests.memory - and requests.ephemeral-storage) are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - labels: - additionalProperties: - type: string - description: Custom labels to set on all managed objects. - type: object - type: object - egress: - description: Settings related to outgoing network traffic. - properties: - connectivityPolicy: - default: Online - description: Configures whether Red Hat Advanced Cluster Security - should run in online or offline (disconnected) mode. In offline - mode, automatic updates of vulnerability definitions and kernel - modules are disabled. - enum: - - Online - - Offline - type: string - type: object - imagePullSecrets: - description: Additional image pull secrets to be taken into account - for pulling images. - items: - description: LocalSecretReference is a reference to a secret within - the same namespace. - properties: - name: - description: The name of the referenced secret. - type: string - required: - - name - type: object - type: array - misc: - description: Miscellaneous settings. - properties: - createSCCs: - description: Set this to true to have the operator create SecurityContextConstraints - (SCCs) for the operands. This isn't usually needed, and may - interfere with other workloads. - type: boolean - type: object - scanner: - description: Settings for the Scanner component, which is responsible - for vulnerability scanning of container images. - properties: - analyzer: - description: Settings pertaining to the analyzer deployment, such - as for autoscaling. - properties: - nodeSelector: - additionalProperties: - type: string - description: If you want this component to only run on specific - nodes, you can configure a node selector here. - type: object - resources: - description: Allows overriding the default resource settings - for this component. Please consult the documentation for - an overview of default resource requirements and a sizing - guide. - properties: - 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 - scaling: - description: Controls the number of analyzer replicas and - autoscaling. - properties: - autoScaling: - default: Enabled - description: When enabled, the number of analyzer replicas - is managed dynamically based on the load, within the - limits specified below. - enum: - - Enabled - - Disabled - type: string - maxReplicas: - default: 5 - format: int32 - minimum: 1 - type: integer - minReplicas: - default: 2 - format: int32 - minimum: 1 - type: integer - replicas: - default: 3 - description: When autoscaling is disabled, the number - of replicas will always be configured to match this - value. - format: int32 - minimum: 1 - type: integer - type: object - tolerations: - description: If you want this component to only run on specific - nodes, you can configure tolerations of tainted nodes. - 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 - db: - description: Settings pertaining to the database used by the Red - Hat Advanced Cluster Security Scanner. - properties: - nodeSelector: - additionalProperties: - type: string - description: If you want this component to only run on specific - nodes, you can configure a node selector here. - type: object - resources: - description: Allows overriding the default resource settings - for this component. Please consult the documentation for - an overview of default resource requirements and a sizing - guide. - properties: - 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 - tolerations: - description: If you want this component to only run on specific - nodes, you can configure tolerations of tainted nodes. - 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 - monitoring: - description: Configures monitoring endpoint for Scanner. The monitoring - endpoint allows other services to collect metrics from Scanner, - provided in Prometheus compatible format. - properties: - exposeEndpoint: - description: Expose the monitoring endpoint. A new service, - "monitoring", with port 9090, will be created as well as - a network policy allowing inbound connections to the port. - enum: - - Enabled - - Disabled - type: string - type: object - scannerComponent: - default: Enabled - description: If you do not want to deploy the Red Hat Advanced - Cluster Security Scanner, you can disable it here (not recommended). - If you do so, all the settings in this section will have no - effect. - enum: - - Enabled - - Disabled - type: string - type: object - tls: - description: Allows you to specify additional trusted Root CAs. - properties: - additionalCAs: - items: - description: AdditionalCA defines a certificate for an additional - Certificate Authority. - properties: - content: - description: PEM format - type: string - name: - description: Must be a valid file basename - type: string - required: - - content - - name - type: object - type: array - type: object - type: object - status: - description: CentralStatus defines the observed state of Central. - properties: - central: - description: CentralComponentStatus describes status specific to the - central component. - properties: - adminPassword: - description: AdminPassword stores information related to the auto-generated - admin password. - properties: - adminPasswordSecretReference: - description: AdminPasswordSecretReference contains reference - for the admin password - type: string - info: - description: Info stores information on how to obtain the - admin password. - type: string - type: object - type: object - conditions: - items: - description: StackRoxCondition defines a condition for a StackRox - custom resource. - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - description: ConditionReason is a type of values of condition - reason. - type: string - status: - description: ConditionStatus is a type of values of condition - status. - type: string - type: - description: ConditionType is a type of values of condition - type. - type: string - required: - - status - - type - type: object - type: array - deployedRelease: - description: StackRoxRelease describes the Helm "release" that was - most recently applied. - properties: - version: - type: string - type: object - productVersion: - description: The deployed version of the product. - type: string - required: - - conditions - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/fleetshard/pkg/central/charts/data/rhacs-operator/templates/platform.stackrox.io_securedclusters.yaml b/fleetshard/pkg/central/charts/data/rhacs-operator/templates/platform.stackrox.io_securedclusters.yaml deleted file mode 100644 index a51ca90f1d..0000000000 --- a/fleetshard/pkg/central/charts/data/rhacs-operator/templates/platform.stackrox.io_securedclusters.yaml +++ /dev/null @@ -1,844 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - name: securedclusters.platform.stackrox.io -spec: - group: platform.stackrox.io - names: - kind: SecuredCluster - listKind: SecuredClusterList - plural: securedclusters - singular: securedcluster - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: SecuredCluster is the configuration template for the secured - cluster services. These include Sensor, which is responsible for the connection - to Central, and Collector, which performs host-level collection of process - and network events.

**Important:** Please see the _Installation Prerequisites_ - on the main RHACS operator page before deploying, or consult the RHACS documentation - on creating cluster init bundles. - 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: SecuredClusterSpec defines the desired configuration state - of a secured cluster. - properties: - admissionControl: - description: Settings for the Admission Control component, which is - necessary for preventive policy enforcement, and for Kubernetes - event monitoring. - properties: - bypass: - default: BreakGlassAnnotation - description: Enables teams to bypass admission control in a monitored - manner in the event of an emergency. - enum: - - BreakGlassAnnotation - - Disabled - type: string - contactImageScanners: - default: DoNotScanInline - description: Should inline scanning be performed on previously - unscanned images during a deployments admission review. - enum: - - ScanIfMissing - - DoNotScanInline - type: string - listenOnCreates: - default: true - description: Set this to 'true' to enable preventive policy enforcement - for object creations. - type: boolean - listenOnEvents: - default: true - description: Set this to 'true' to enable monitoring and enforcement - for Kubernetes events (port-forward and exec). - type: boolean - listenOnUpdates: - default: true - description: "Set this to 'true' to enable preventive policy enforcement - for object updates. \n Note: this will not have any effect unless - 'Listen On Creates' is set to 'true' as well." - type: boolean - nodeSelector: - additionalProperties: - type: string - description: If you want this component to only run on specific - nodes, you can configure a node selector here. - type: object - resources: - description: Allows overriding the default resource settings for - this component. Please consult the documentation for an overview - of default resource requirements and a sizing guide. - properties: - 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 - timeoutSeconds: - default: 20 - description: Maximum timeout period for admission review, upon - which admission review will fail open. Use it to set request - timeouts when you enable inline image scanning. The default - kubectl timeout is 30 seconds; taking padding into account, - this should not exceed 25 seconds. - format: int32 - maximum: 25 - minimum: 1 - type: integer - tolerations: - description: If you want this component to only run on specific - nodes, you can configure tolerations of tainted nodes. - 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 - auditLogs: - description: Settings relating to the ingestion of Kubernetes audit - logs. - properties: - collection: - default: Auto - description: Whether collection of Kubernetes audit logs should - be enabled or disabled. Currently, this is only supported on - OpenShift 4, and trying to enable it on non-OpenShift 4 clusters - will result in an error. Use the 'Auto' setting to enable it - on compatible environments, and disable it elsewhere. - enum: - - Auto - - Disabled - - Enabled - type: string - type: object - centralEndpoint: - description: 'The endpoint of the Red Hat Advanced Cluster Security - Central instance to connect to, including the port number. If using - a non-gRPC capable load balancer, use the WebSocket protocol by - prefixing the endpoint address with wss://. Note: when leaving this - blank, Sensor will attempt to connect to a Central instance running - in the same namespace.' - type: string - clusterLabels: - additionalProperties: - type: string - description: Custom labels associated with a secured cluster in Red - Hat Advanced Cluster Security. - type: object - clusterName: - description: 'The unique name of this cluster, as it will be shown - in the Red Hat Advanced Cluster Security UI. Note: Once a name is - set here, you will not be able to change it again. You will need - to delete and re-create this object in order to register a cluster - with a new name.' - type: string - customize: - description: Customizations to apply on all Central Services components. - properties: - annotations: - additionalProperties: - type: string - description: Custom annotations to set on all managed objects. - type: object - envVars: - description: Custom environment variables to set on managed pods' - containers. - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. If - a variable cannot be resolved, the reference in the input - string will be unchanged. Double $$ are reduced to a single - $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: 'Selects a field of the pod: supports metadata.name, - metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: 'Selects a resource of the container: only - resources limits and requests (limits.cpu, limits.memory, - limits.ephemeral-storage, requests.cpu, requests.memory - and requests.ephemeral-storage) are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - labels: - additionalProperties: - type: string - description: Custom labels to set on all managed objects. - type: object - type: object - imagePullSecrets: - description: Additional image pull secrets to be taken into account - for pulling images. - items: - description: LocalSecretReference is a reference to a secret within - the same namespace. - properties: - name: - description: The name of the referenced secret. - type: string - required: - - name - type: object - type: array - misc: - description: Miscellaneous settings. - properties: - createSCCs: - description: Set this to true to have the operator create SecurityContextConstraints - (SCCs) for the operands. This isn't usually needed, and may - interfere with other workloads. - type: boolean - type: object - perNode: - description: Settings for the components running on each node in the - cluster (Collector and Compliance). - properties: - collector: - description: Settings for the Collector container, which is responsible - for collecting process and networking activity at the host level. - properties: - collection: - default: EBPF - description: The method for system-level data collection. - Kernel module is recommended. If you select "NoCollection", - you will not be able to see any information about network - activity and process executions. The remaining settings - in these section will not have any effect. - enum: - - EBPF - - KernelModule - - NoCollection - type: string - imageFlavor: - default: Regular - description: The image flavor to use for collector. "Regular" - images are bigger in size, but contain kernel modules for - most kernels. If you use the "Slim" image flavor, you must - ensure that your Central instance is connected to the internet, - or regularly receives Collector Support Package updates - (for further instructions, please refer to the documentation). - enum: - - Regular - - Slim - type: string - resources: - description: Allows overriding the default resource settings - for this component. Please consult the documentation for - an overview of default resource requirements and a sizing - guide. - properties: - 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 - compliance: - description: Settings for the Compliance container, which is responsible - for checking host-level configurations. - properties: - resources: - description: Allows overriding the default resource settings - for this component. Please consult the documentation for - an overview of default resource requirements and a sizing - guide. - properties: - 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 - taintToleration: - default: TolerateTaints - description: To ensure comprehensive monitoring of your cluster - activity, Red Hat Advanced Cluster Security will run services - on every node in the cluster, including tainted nodes by default. - If you do not want this behavior, please select 'AvoidTaints' - here. - enum: - - TolerateTaints - - AvoidTaints - type: string - type: object - scanner: - description: Settings for the Scanner component, which is responsible - for vulnerability scanning of container images stored in a cluster-local - image repository. - properties: - analyzer: - description: Settings pertaining to the analyzer deployment, such - as for autoscaling. - properties: - nodeSelector: - additionalProperties: - type: string - description: If you want this component to only run on specific - nodes, you can configure a node selector here. - type: object - resources: - description: Allows overriding the default resource settings - for this component. Please consult the documentation for - an overview of default resource requirements and a sizing - guide. - properties: - 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 - scaling: - description: Controls the number of analyzer replicas and - autoscaling. - properties: - autoScaling: - default: Enabled - description: When enabled, the number of analyzer replicas - is managed dynamically based on the load, within the - limits specified below. - enum: - - Enabled - - Disabled - type: string - maxReplicas: - default: 5 - format: int32 - minimum: 1 - type: integer - minReplicas: - default: 2 - format: int32 - minimum: 1 - type: integer - replicas: - default: 3 - description: When autoscaling is disabled, the number - of replicas will always be configured to match this - value. - format: int32 - minimum: 1 - type: integer - type: object - tolerations: - description: If you want this component to only run on specific - nodes, you can configure tolerations of tainted nodes. - 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 - db: - description: Settings pertaining to the database used by the Red - Hat Advanced Cluster Security Scanner. - properties: - nodeSelector: - additionalProperties: - type: string - description: If you want this component to only run on specific - nodes, you can configure a node selector here. - type: object - resources: - description: Allows overriding the default resource settings - for this component. Please consult the documentation for - an overview of default resource requirements and a sizing - guide. - properties: - 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 - tolerations: - description: If you want this component to only run on specific - nodes, you can configure tolerations of tainted nodes. - 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 - scannerComponent: - default: AutoSense - description: If you do not want to deploy the Red Hat Advanced - Cluster Security Scanner, you can disable it here (not recommended). - If you do so, all the settings in this section will have no - effect. - enum: - - AutoSense - - Disabled - type: string - type: object - sensor: - description: Settings for the Sensor component. - properties: - nodeSelector: - additionalProperties: - type: string - description: If you want this component to only run on specific - nodes, you can configure a node selector here. - type: object - resources: - description: Allows overriding the default resource settings for - this component. Please consult the documentation for an overview - of default resource requirements and a sizing guide. - properties: - 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 - tolerations: - description: If you want this component to only run on specific - nodes, you can configure tolerations of tainted nodes. - 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 - tls: - description: Allows you to specify additional trusted Root CAs. - properties: - additionalCAs: - items: - description: AdditionalCA defines a certificate for an additional - Certificate Authority. - properties: - content: - description: PEM format - type: string - name: - description: Must be a valid file basename - type: string - required: - - content - - name - type: object - type: array - type: object - required: - - clusterName - type: object - status: - description: SecuredClusterStatus defines the observed state of SecuredCluster - properties: - clusterName: - description: The assigned cluster name per the spec. This cannot be - changed afterwards. If you need to change the cluster name, please - delete and recreate this resource. - type: string - conditions: - items: - description: StackRoxCondition defines a condition for a StackRox - custom resource. - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - description: ConditionReason is a type of values of condition - reason. - type: string - status: - description: ConditionStatus is a type of values of condition - status. - type: string - type: - description: ConditionType is a type of values of condition - type. - type: string - required: - - status - - type - type: object - type: array - deployedRelease: - description: StackRoxRelease describes the Helm "release" that was - most recently applied. - properties: - version: - type: string - type: object - productVersion: - description: The deployed version of the product. - type: string - required: - - conditions - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/fleetshard/pkg/central/operator/upgrade.go b/fleetshard/pkg/central/operator/upgrade.go index ece1d29e85..9f5a91892b 100644 --- a/fleetshard/pkg/central/operator/upgrade.go +++ b/fleetshard/pkg/central/operator/upgrade.go @@ -22,23 +22,27 @@ const ( maxOperatorDeploymentNameLength = 63 ) -func parseOperatorImages(images []string) ([]chartutil.Values, error) { +func parseOperatorImages(images []ACSOperatorImage) ([]chartutil.Values, string, error) { if len(images) == 0 { - return nil, fmt.Errorf("the list of images is empty") + return nil, "", fmt.Errorf("the list of images is empty") } var operatorImages []chartutil.Values + var crdTag string uniqueImages := make(map[string]bool) for _, img := range images { - if !strings.Contains(img, ":") { - return nil, fmt.Errorf("failed to parse image %q", img) + if !strings.Contains(img.Image, ":") { + return nil, "", fmt.Errorf("failed to parse image %q", img.Image) } - strs := strings.Split(img, ":") + strs := strings.Split(img.Image, ":") if len(strs) != 2 { - return nil, fmt.Errorf("failed to split image and tag from %q", img) + return nil, "", fmt.Errorf("failed to split image and tag from %q", img.Image) } repo, tag := strs[0], strs[1] if len(operatorDeploymentPrefix+"-"+tag) > maxOperatorDeploymentNameLength { - return nil, fmt.Errorf("%s-%s contains more than %d characters and cannot be used as a deployment name", operatorDeploymentPrefix, tag, maxOperatorDeploymentNameLength) + return nil, "", fmt.Errorf("%s-%s contains more than %d characters and cannot be used as a deployment name", operatorDeploymentPrefix, tag, maxOperatorDeploymentNameLength) + } + if img.InstallCRD { + crdTag = tag } if _, used := uniqueImages[repo+tag]; !used { uniqueImages[repo+tag] = true @@ -46,18 +50,25 @@ func parseOperatorImages(images []string) ([]chartutil.Values, error) { operatorImages = append(operatorImages, img) } } - return operatorImages, nil + return operatorImages, crdTag, nil } // ACSOperatorManager keeps data necessary for managing ACS Operator type ACSOperatorManager struct { client ctrlClient.Client + crdURL string resourcesChart *chart.Chart } +// ACSOperatorImage operator image representation which tells when to download CRD or skip it +type ACSOperatorImage struct { + Image string + InstallCRD bool +} + // InstallOrUpgrade provisions or upgrades an existing ACS Operator from helm chart template -func (u *ACSOperatorManager) InstallOrUpgrade(ctx context.Context, images []string) error { - operatorImages, err := parseOperatorImages(images) +func (u *ACSOperatorManager) InstallOrUpgrade(ctx context.Context, images []ACSOperatorImage) error { + operatorImages, crdTag, err := parseOperatorImages(images) if err != nil { return fmt.Errorf("failed to parse images: %w", err) } @@ -68,7 +79,11 @@ func (u *ACSOperatorManager) InstallOrUpgrade(ctx context.Context, images []stri }, } - u.resourcesChart = charts.MustGetChart("rhacs-operator") + var dynamicTemplatesUrls []string + if crdTag != "" { + dynamicTemplatesUrls = u.generateCRDTemplateUrls(crdTag) + } + u.resourcesChart = charts.MustGetChart("rhacs-operator", dynamicTemplatesUrls) objs, err := charts.RenderToObjects(releaseName, operatorNamespace, u.resourcesChart, chartVals) if err != nil { return fmt.Errorf("failed rendering operator chart: %w", err) @@ -88,9 +103,17 @@ func (u *ACSOperatorManager) InstallOrUpgrade(ctx context.Context, images []stri } +func (u *ACSOperatorManager) generateCRDTemplateUrls(tag string) []string { + stackroxWithTag := fmt.Sprintf(u.crdURL, tag) + centralCrdURL := stackroxWithTag + "platform.stackrox.io_centrals.yaml" + securedClusterCrdURL := stackroxWithTag + "platform.stackrox.io_securedclusters.yaml" + return []string{centralCrdURL, securedClusterCrdURL} +} + // NewACSOperatorManager creates a new ACS Operator Manager -func NewACSOperatorManager(k8sClient ctrlClient.Client) *ACSOperatorManager { +func NewACSOperatorManager(k8sClient ctrlClient.Client, baseCrdURL string) *ACSOperatorManager { return &ACSOperatorManager{ client: k8sClient, + crdURL: baseCrdURL, } } diff --git a/fleetshard/pkg/central/operator/upgrade_test.go b/fleetshard/pkg/central/operator/upgrade_test.go index 02b89147d0..65f99b96d7 100644 --- a/fleetshard/pkg/central/operator/upgrade_test.go +++ b/fleetshard/pkg/central/operator/upgrade_test.go @@ -23,6 +23,7 @@ const ( operatorRepository = "quay.io/rhacs-eng/stackrox-operator" operatorImage1 = "quay.io/rhacs-eng/stackrox-operator:3.74.1" operatorImage2 = "quay.io/rhacs-eng/stackrox-operator:3.74.2" + crdURL = "https://raw.githubusercontent.com/stackrox/stackrox/%s/operator/bundle/manifests/" ) var securedClusterCRD = &unstructured.Unstructured{ @@ -83,9 +84,14 @@ var metricService = &unstructured.Unstructured{ func TestOperatorUpgradeFreshInstall(t *testing.T) { fakeClient := testutils.NewFakeClientBuilder(t).Build() - u := NewACSOperatorManager(fakeClient) + u := NewACSOperatorManager(fakeClient, crdURL) - err := u.InstallOrUpgrade(context.Background(), []string{operatorImage1}) + err := u.InstallOrUpgrade(context.Background(), []ACSOperatorImage{ + { + Image: operatorImage1, + InstallCRD: true, + }, + }) require.NoError(t, err) // check Secured Cluster CRD exists and correct @@ -127,9 +133,18 @@ func TestOperatorUpgradeFreshInstall(t *testing.T) { func TestOperatorUpgradeMultipleVersions(t *testing.T) { fakeClient := testutils.NewFakeClientBuilder(t).Build() - u := NewACSOperatorManager(fakeClient) + u := NewACSOperatorManager(fakeClient, crdURL) - operatorImages := []string{operatorImage1, operatorImage2} + operatorImages := []ACSOperatorImage{ + { + Image: operatorImage1, + InstallCRD: false, + }, + { + Image: operatorImage2, + InstallCRD: false, + }, + } err := u.InstallOrUpgrade(context.Background(), operatorImages) require.NoError(t, err) @@ -146,10 +161,14 @@ func TestOperatorUpgradeMultipleVersions(t *testing.T) { func TestOperatorUpgradeDoNotInstallLongTagVersion(t *testing.T) { fakeClient := testutils.NewFakeClientBuilder(t).Build() - u := NewACSOperatorManager(fakeClient) + u := NewACSOperatorManager(fakeClient, crdURL) operatorImageWithLongTag := "quay.io/rhacs-eng/stackrox-operator:3.74.1-with-ridiculously-long-tag-version-name" - err := u.InstallOrUpgrade(context.Background(), []string{operatorImageWithLongTag}) + err := u.InstallOrUpgrade(context.Background(), []ACSOperatorImage{ + { + Image: operatorImageWithLongTag, + InstallCRD: false, + }}) require.Errorf(t, err, "zero tags parsed from images") deployments := &appsv1.DeploymentList{} @@ -160,57 +179,102 @@ func TestOperatorUpgradeDoNotInstallLongTagVersion(t *testing.T) { func TestParseOperatorImages(t *testing.T) { cases := map[string]struct { - images []string - expected []map[string]string - shouldFail bool + images []ACSOperatorImage + expected []map[string]string + expectedCrdVersion string + shouldFail bool }{ "should parse one valid operator image": { - images: []string{operatorImage1}, + images: []ACSOperatorImage{{ + Image: operatorImage1, + InstallCRD: false, + }}, expected: []map[string]string{ {"repository": operatorRepository, "tag": "3.74.1"}, }, }, "should parse two valid operator images": { - images: []string{operatorImage1, operatorImage2}, + images: []ACSOperatorImage{{ + Image: operatorImage1, + InstallCRD: false, + }, { + Image: operatorImage2, + InstallCRD: false, + }}, + expected: []map[string]string{ + {"repository": operatorRepository, "tag": "3.74.1"}, + {"repository": operatorRepository, "tag": "3.74.2"}, + }, + }, + "should return correct desired CRD version": { + images: []ACSOperatorImage{{ + Image: operatorImage1, + InstallCRD: false, + }, { + Image: operatorImage2, + InstallCRD: true, + }}, expected: []map[string]string{ {"repository": operatorRepository, "tag": "3.74.1"}, {"repository": operatorRepository, "tag": "3.74.2"}, }, + expectedCrdVersion: "3.74.2", }, "should ignore duplicate operator images": { - images: []string{operatorImage1, operatorImage1}, + images: []ACSOperatorImage{{ + Image: operatorImage1, + InstallCRD: false, + }, { + Image: operatorImage1, + InstallCRD: false, + }}, expected: []map[string]string{ {"repository": operatorRepository, "tag": "3.74.1"}, }, }, "fail if images list is empty": { - images: []string{}, + images: []ACSOperatorImage{}, shouldFail: true, }, "should accept images from multiple repositories with the same tag": { - images: []string{"repo1:tag", "repo2:tag"}, + images: []ACSOperatorImage{{ + Image: "repo1:tag", + InstallCRD: false, + }, { + Image: "repo2:tag", + InstallCRD: false, + }}, expected: []map[string]string{ {"repository": "repo1", "tag": "tag"}, {"repository": "repo2", "tag": "tag"}, }, }, "fail if image does contain colon": { - images: []string{"quay.io/without-colon-123-tag"}, + images: []ACSOperatorImage{{ + Image: "quay.io/without-colon-123-tag", + InstallCRD: false, + }}, shouldFail: true, }, "fail if image contains more than one colon": { - images: []string{"quay.io/image-name:1.2.3:"}, + images: []ACSOperatorImage{{ + Image: "quay.io/image-name:1.2.3:", + InstallCRD: false, + }}, shouldFail: true, }, "fail if image tag is too long": { - images: []string{"quay.io/image-name:1.2.3-with-ridiculously-long-tag-version-name"}, + images: []ACSOperatorImage{{ + Image: "quay.io/image-name:1.2.3-with-ridiculously-long-tag-version-name", + InstallCRD: false, + }}, shouldFail: true, }, } for name, c := range cases { t.Run(name, func(t *testing.T) { - got, err := parseOperatorImages(c.images) + gotImages, gotCrdVersion, err := parseOperatorImages(c.images) if c.shouldFail { assert.Error(t, err) } else { @@ -220,7 +284,8 @@ func TestParseOperatorImages(t *testing.T) { val := chartutil.Values{"repository": m["repository"], "tag": m["tag"]} expectedRepositoryAndTags = append(expectedRepositoryAndTags, val) } - assert.Equal(t, expectedRepositoryAndTags, got) + assert.Equal(t, c.expectedCrdVersion, gotCrdVersion) + assert.Equal(t, expectedRepositoryAndTags, gotImages) } }) } diff --git a/fleetshard/pkg/central/reconciler/reconciler.go b/fleetshard/pkg/central/reconciler/reconciler.go index d0571b0951..ae6b725524 100644 --- a/fleetshard/pkg/central/reconciler/reconciler.go +++ b/fleetshard/pkg/central/reconciler/reconciler.go @@ -942,7 +942,7 @@ func (r *CentralReconciler) needsReconcile(changed bool, forceReconcile string) return changed || forceReconcile == "always" } -var resourcesChart = charts.MustGetChart("tenant-resources") +var resourcesChart = charts.MustGetChart("tenant-resources", nil) // NewCentralReconciler ... func NewCentralReconciler(k8sClient ctrlClient.Client, central private.ManagedCentral, diff --git a/fleetshard/pkg/central/reconciler/reconciler_test.go b/fleetshard/pkg/central/reconciler/reconciler_test.go index 0023a0be1b..3574235d93 100644 --- a/fleetshard/pkg/central/reconciler/reconciler_test.go +++ b/fleetshard/pkg/central/reconciler/reconciler_test.go @@ -27,6 +27,7 @@ import ( "github.com/stackrox/rox/operator/apis/platform/v1alpha1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "helm.sh/helm/v3/pkg/chart/loader" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" @@ -557,12 +558,14 @@ func TestReportRoutesStatuses(t *testing.T) { } func TestChartResourcesAreAddedAndRemoved(t *testing.T) { - chrt, err := charts.LoadChart(testdata, "testdata/tenant-resources") + chartFiles, err := charts.TraverseChart(testdata, "testdata/tenant-resources") + require.NoError(t, err) + chart, err := loader.LoadFiles(chartFiles) require.NoError(t, err) fakeClient := testutils.NewFakeClientBuilder(t).Build() r := NewCentralReconciler(fakeClient, private.ManagedCentral{}, nil, centralDBInitFunc, CentralReconcilerOptions{}) - r.resourcesChart = chrt + r.resourcesChart = chart _, err = r.Reconcile(context.TODO(), simpleManagedCentral) require.NoError(t, err) @@ -588,7 +591,9 @@ func TestChartResourcesAreAddedAndRemoved(t *testing.T) { } func TestChartResourcesAreAddedAndUpdated(t *testing.T) { - chart, err := charts.LoadChart(testdata, "testdata/tenant-resources") + chartFiles, err := charts.TraverseChart(testdata, "testdata/tenant-resources") + require.NoError(t, err) + chart, err := loader.LoadFiles(chartFiles) require.NoError(t, err) fakeClient := testutils.NewFakeClientBuilder(t).Build() diff --git a/fleetshard/pkg/runtime/runtime.go b/fleetshard/pkg/runtime/runtime.go index 721abbf076..e740629f01 100644 --- a/fleetshard/pkg/runtime/runtime.go +++ b/fleetshard/pkg/runtime/runtime.go @@ -4,7 +4,6 @@ package runtime import ( "context" "fmt" - "strings" "time" "github.com/stackrox/acs-fleet-manager/fleetshard/pkg/central/operator" @@ -86,7 +85,7 @@ func NewRuntime(config *config.Config, k8sClient ctrlClient.Client) (*Runtime, e } } - operatorManager := operator.NewACSOperatorManager(k8sClient) + operatorManager := operator.NewACSOperatorManager(k8sClient, config.BaseCrdURL) return &Runtime{ config: config, @@ -217,8 +216,19 @@ func (r *Runtime) upgradeOperator() error { ctx := context.Background() // TODO: gather desired operator versions from fleet-manager and update operators based on ticker // TODO: Leave Operator installation before reconciler run until migration - operatorImages := []string{"quay.io/rhacs-eng/stackrox-operator:3.74.0", "quay.io/rhacs-eng/stackrox-operator:3.74.1"} - glog.Infof("Installing Operators: %s", strings.Join(operatorImages, ", ")) + operatorImages := []operator.ACSOperatorImage{ + { + Image: "quay.io/rhacs-eng/stackrox-operator:4.0.0", + InstallCRD: false, + }, + { + Image: "quay.io/rhacs-eng/stackrox-operator:4.0.1", + InstallCRD: false, + }, + } + for _, img := range operatorImages { + glog.Infof("Installing Operator: %s and download CRD: %t", img.Image, img.InstallCRD) + } err := r.operatorManager.InstallOrUpgrade(ctx, operatorImages) if err != nil { return fmt.Errorf("ensuring initial operator installation failed: %w", err)