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 }}"