From e21b1e7c9b3c8156151b70ebad32e28efe7ac6b7 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 17 Aug 2022 19:04:31 -0400 Subject: [PATCH 01/32] feat(oauth-properties): add spec to specify oauth properties as configMap --- api/v1beta1/cryostat_types.go | 13 ++++++++ api/v1beta1/zz_generated.deepcopy.go | 16 +++++++++ .../bases/operator.cryostat.io_cryostats.yaml | 15 +++++++++ .../resource_definitions.go | 33 +++++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 5237ba1c8..10408ddf8 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -90,6 +90,10 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec Resources ResourceConfigList `json:"resources,omitempty"` + // A mapping from Cryostat resources to Kubernetes resources used in OAuth. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + OAuthProperties OAuthPropertiesConfigMap `json:"oAuthProperties,omitempty"` } type ResourceConfigList struct { @@ -402,3 +406,12 @@ type TemplateConfigMap struct { // Filename within config map containing the template file Filename string `json:"filename"` } + +// A ConfigMap containing a mapping between Cryostat resources to Kubernetes resources. +type OAuthPropertiesConfigMap struct { + // Name of config map in the local namespace. + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ConfigMap"} + ConfigMapName string `json:"configMapName"` + // Filename within config map containing the resource mapping. + Filename string `json:"filename"` +} diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index f4b4543d3..83a71a17a 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -199,6 +199,7 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { **out = **in } in.Resources.DeepCopyInto(&out.Resources) + out.OAuthProperties = in.OAuthProperties } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CryostatSpec. @@ -516,6 +517,21 @@ func (in *NetworkConfigurationList) DeepCopy() *NetworkConfigurationList { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OAuthPropertiesConfigMap) DeepCopyInto(out *OAuthPropertiesConfigMap) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OAuthPropertiesConfigMap. +func (in *OAuthPropertiesConfigMap) DeepCopy() *OAuthPropertiesConfigMap { + if in == nil { + return nil + } + out := new(OAuthPropertiesConfigMap) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OptionDescriptor) DeepCopyInto(out *OptionDescriptor) { *out = *in diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 5ad43b84b..cedfbd29c 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -1033,6 +1033,21 @@ spec: type: object type: object type: object + oAuthProperties: + description: A mapping from Cryostat resources to Kubernetes resources + used in OAuth. + properties: + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the resource + mapping. + type: string + required: + - configMapName + - filename + type: object reportOptions: description: Options to configure Cryostat Automated Report Analysis properties: diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 289dd3bc1..c592f3765 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -351,6 +351,28 @@ func NewPodForCR(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTags *I volumes = append(volumes, eventTemplateVolume) } + // Add OAuth properties as a volume if specified + if cr.Spec.OAuthProperties != (operatorv1beta1.OAuthPropertiesConfigMap{}) { + OAuthResourceVolume := corev1.Volume{ + Name: "oauth-properties-" + cr.Spec.OAuthProperties.ConfigMapName, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Spec.OAuthProperties.ConfigMapName, + }, + Items: []corev1.KeyToPath{ + { + Key: cr.Spec.OAuthProperties.Filename, + Path: "OpenShiftAuthManager.properties", + Mode: &readOnlyMode, + }, + }, + }, + }, + } + volumes = append(volumes, OAuthResourceVolume) + } + // Ensure PV mounts are writable sc := &corev1.PodSecurityContext{ FSGroup: &fsGroup, @@ -498,6 +520,7 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa templatesPath := "/opt/cryostat.d/templates.d" clientlibPath := "/opt/cryostat.d/clientlib.d" probesPath := "/opt/cryostat.d/probes.d" + OAuthPropertiesPath := "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties" envs := []corev1.EnvVar{ { Name: "CRYOSTAT_WEB_PORT", @@ -669,6 +692,16 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa }, } + // Mount OAuth properties if specified + if cr.Spec.OAuthProperties != (operatorv1beta1.OAuthPropertiesConfigMap{}) { + mounts = append(mounts, corev1.VolumeMount{ + Name: "oauth-properties-" + cr.Spec.OAuthProperties.ConfigMapName, + MountPath: OAuthPropertiesPath, + SubPath: "OpenShiftAuthManager.properties", + ReadOnly: true, + }) + } + if !cr.Spec.Minimal { grafanaVars := []corev1.EnvVar{ { From ef7183a1fb33c87682459f2e9ecb01a32cc31844 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 17 Aug 2022 21:41:16 -0400 Subject: [PATCH 02/32] docs(oauth): add docs on oauth properties spec --- docs/config.md | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index dd368186e..862ea4aa9 100644 --- a/docs/config.md +++ b/docs/config.md @@ -146,7 +146,7 @@ kind: Cryostat metadata: name: cryostat-sample spec: - reportOptions: + reportOptions:resource replicas: 0 subProcessMaxHeapSize: 200 ``` @@ -267,3 +267,37 @@ spec: targetCacheSize: -1 targetCacheTTL: 10 ``` + + +### OAuth Properties + +When running on Kubernetes or Openshift, the user is required to have sufficient permissions to certain resources that +are mapped into Cryostat-managed resources to authenticate via Openshift OAuth. + +The mappings can be specified using a ConfigMap that is compatible with [`OpenShiftAuthManager.properties`](https://github.com/cryostatio/cryostat/blob/main/src/main/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties). For example: +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: oauth-properties +data: + oauth.properties: | + TARGET=pods,deployments.apps + RECORDING=pods,pods/exec + CERTIFICATE=deployments.apps,pods,cryostats.operator.cryostat.io + CREDENTIALS=cryostats.operator.cryostat.io +``` + +The property `.spec.OAuthProperties` can then be set to this ConfigMap to configure Cryostat to use this mapping instead of the default ones. +```yaml +apiVersion: operator.cryostat.io/v1beta1 +kind: Cryostat +metadata: + name: cryostat-sample +spec: + OAuthProperties: + configMapName: oauth-properties + filename: oauth.properties +``` + +Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containting resource mappings. From 07c11ee8a854554c870815143ecf0f4e68110f24 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 17 Aug 2022 21:08:51 -0400 Subject: [PATCH 03/32] test(resources): add resources for testing cryostat with oauth properties option --- internal/test/resources.go | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/internal/test/resources.go b/internal/test/resources.go index 641200b6b..3923af050 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -369,6 +369,15 @@ func NewCryostatWithResources() *operatorv1beta1.Cryostat { return cr } +func NewCryostatWithOAuthProperties() *operatorv1beta1.Cryostat { + cr := NewCryostat() + cr.Spec.OAuthProperties = operatorv1beta1.OAuthPropertiesConfigMap{ + ConfigMapName: "oauth-propertiesCM1", + Filename: "oauth.properties", + } + return cr +} + func newPVCSpec(storageClass string, storageRequest string, accessModes ...corev1.PersistentVolumeAccessMode) *corev1.PersistentVolumeClaimSpec { return &corev1.PersistentVolumeClaimSpec{ @@ -1576,6 +1585,16 @@ func NewVolumeMountsWithTemplates(tls bool) []corev1.VolumeMount { }) } +func NewVolumeMountsWithOAuthProperties(tls bool) []corev1.VolumeMount { + return append(NewCoreVolumeMounts(tls), + corev1.VolumeMount{ + Name: "oauth-properties-" + "configMapName", + ReadOnly: true, + MountPath: "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties", + SubPath: "OpenShiftAuthManager.properties", + }) +} + func NewCoreLivenessProbe(tls bool) *corev1.Probe { return &corev1.Probe{ ProbeHandler: newCoreProbeHandler(tls), @@ -1781,6 +1800,29 @@ func NewVolumesWithTemplates(tls bool) []corev1.Volume { }) } +func NewVolumeWithOAuthProperties(tls bool) []corev1.Volume { + readOnlyMode := int32(0440) + return append(NewVolumes(false, tls), + corev1.Volume{ + Name: "oauth-properties-" + "configMapName", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "oauth-propertiesCM1", + }, + Items: []corev1.KeyToPath{ + { + Key: "oauth.properties", + Path: "OpenShiftAuthManager.properties", + Mode: &readOnlyMode, + }, + }, + }, + }, + }, + ) +} + func newVolumes(minimal bool, tls bool, certProjections []corev1.VolumeProjection) []corev1.Volume { readOnlymode := int32(0440) volumes := []corev1.Volume{ @@ -2254,6 +2296,18 @@ func NewOtherTemplateConfigMap() *corev1.ConfigMap { } } +func NewOAuthPropertiesConfigMap() *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "oauth-propertiesCM1", + Namespace: "default", + }, + Data: map[string]string{ + "oauth.properties": "CRYOSTAT_RESOURCE=K8S_RESOURCE", + }, + } +} + func NewNamespace() *corev1.Namespace { return &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ From 028c7caa99f6baed1149db26bbeb85a8136f705c Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 17 Aug 2022 22:10:16 -0400 Subject: [PATCH 04/32] test(oauth): add unit tests for present oauth properties --- .../controllers/cryostat_controller_test.go | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index c1f4d8a2c..8e7805ba5 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -1297,6 +1297,17 @@ var _ = Describe("CryostatController", func() { }) }) }) + Context("Cryostat CR has OAuth properties", func() { + BeforeEach(func() { + t.objs = append(t.objs, test.NewCryostatWithOAuthProperties(), test.NewOAuthPropertiesConfigMap()) + }) + JustBeforeEach(func() { + t.reconcileCryostatFully() + }) + It("Should add volumes and volumeMounts to deployment", func() { + t.checkDeploymentHasOAuthProperties() + }) + }) }) Describe("reconciling a request in Kubernetes", func() { JustBeforeEach(func() { @@ -1418,6 +1429,17 @@ var _ = Describe("CryostatController", func() { Expect(kerrors.IsNotFound(err)).To(BeTrue()) }) }) + Context("Cryostat CR has OAuth properties", func() { + BeforeEach(func() { + t.objs = append(t.objs, test.NewCryostatWithOAuthProperties(), test.NewOAuthPropertiesConfigMap()) + }) + JustBeforeEach(func() { + t.reconcileCryostatFully() + }) + It("Should add volumes and volumeMounts to deployment", func() { + t.checkDeploymentHasOAuthProperties() + }) + }) }) }) @@ -2053,6 +2075,20 @@ func (t *cryostatTestInput) checkDeploymentHasTemplates() { Expect(volumeMounts).To(Equal(expectedVolumeMounts)) } +func (t *cryostatTestInput) checkDeploymentHasOAuthProperties() { + deployment := &appsv1.Deployment{} + err := t.Client.Get(context.Background(), types.NamespacedName{Name: "cryostat", Namespace: "default"}, deployment) + Expect(err).ToNot(HaveOccurred()) + + volumes := deployment.Spec.Template.Spec.Volumes + expectedVolumes := test.NewVolumeWithOAuthProperties(t.TLS) + Expect(volumes).To(Equal(expectedVolumes)) + + volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts + expectedVolumeMounts := test.NewVolumeMountsWithOAuthProperties(t.TLS) + Expect(volumeMounts).To(Equal(expectedVolumeMounts)) +} + func checkCoreContainer(container *corev1.Container, minimal bool, tls bool, externalTLS bool, tag *string, openshift bool, reportsUrl string, resources corev1.ResourceRequirements) { Expect(container.Name).To(Equal("cryostat")) From 335e6695bbdbfa94bb963e30fbe468300d9db5b5 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 14:08:55 -0400 Subject: [PATCH 05/32] chore(test): rename test oauth-props configmap --- internal/test/resources.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/test/resources.go b/internal/test/resources.go index 3923af050..e0ad549c4 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -372,7 +372,7 @@ func NewCryostatWithResources() *operatorv1beta1.Cryostat { func NewCryostatWithOAuthProperties() *operatorv1beta1.Cryostat { cr := NewCryostat() cr.Spec.OAuthProperties = operatorv1beta1.OAuthPropertiesConfigMap{ - ConfigMapName: "oauth-propertiesCM1", + ConfigMapName: "oauthConfigMapName", Filename: "oauth.properties", } return cr @@ -1588,7 +1588,7 @@ func NewVolumeMountsWithTemplates(tls bool) []corev1.VolumeMount { func NewVolumeMountsWithOAuthProperties(tls bool) []corev1.VolumeMount { return append(NewCoreVolumeMounts(tls), corev1.VolumeMount{ - Name: "oauth-properties-" + "configMapName", + Name: "oauth-properties-oauthConfigMapName", ReadOnly: true, MountPath: "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties", SubPath: "OpenShiftAuthManager.properties", @@ -1804,11 +1804,11 @@ func NewVolumeWithOAuthProperties(tls bool) []corev1.Volume { readOnlyMode := int32(0440) return append(NewVolumes(false, tls), corev1.Volume{ - Name: "oauth-properties-" + "configMapName", + Name: "oauth-properties-oauthConfigMapName", VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "oauth-propertiesCM1", + Name: "oauthConfigMapName", }, Items: []corev1.KeyToPath{ { @@ -2299,11 +2299,11 @@ func NewOtherTemplateConfigMap() *corev1.ConfigMap { func NewOAuthPropertiesConfigMap() *corev1.ConfigMap { return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: "oauth-propertiesCM1", + Name: "oauthConfigMapName", Namespace: "default", }, Data: map[string]string{ - "oauth.properties": "CRYOSTAT_RESOURCE=K8S_RESOURCE", + "oauth.properties": "CRYOSTAT_RESOURCE=K8S_RESOURCE\nANOTHER_CRYOSTAT_RESOURCE=ANOTHER_K8S_RESOURCE", }, } } From a63ba6b383ee1bca8380977836e6e92250e0716c Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 14:17:44 -0400 Subject: [PATCH 06/32] fix(tests): fix failed unit tests for oauth props --- internal/controllers/cryostat_controller_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index 8e7805ba5..446608a7e 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -2082,11 +2082,11 @@ func (t *cryostatTestInput) checkDeploymentHasOAuthProperties() { volumes := deployment.Spec.Template.Spec.Volumes expectedVolumes := test.NewVolumeWithOAuthProperties(t.TLS) - Expect(volumes).To(Equal(expectedVolumes)) + Expect(volumes).To(ConsistOf(expectedVolumes)) volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts expectedVolumeMounts := test.NewVolumeMountsWithOAuthProperties(t.TLS) - Expect(volumeMounts).To(Equal(expectedVolumeMounts)) + Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) } func checkCoreContainer(container *corev1.Container, minimal bool, tls bool, externalTLS bool, From dd62b117d52460c0786a20d958ca31193384bd2d Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 14:23:25 -0400 Subject: [PATCH 07/32] fix(manifests): update markers, manifests and bundle --- api/v1beta1/cryostat_types.go | 4 ++-- .../cryostat-operator.clusterserviceversion.yaml | 9 +++++++++ .../manifests/operator.cryostat.io_cryostats.yaml | 15 +++++++++++++++ .../crd/bases/operator.cryostat.io_cryostats.yaml | 4 ++-- .../cryostat-operator.clusterserviceversion.yaml | 9 +++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 10408ddf8..5741fd936 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -90,7 +90,7 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec Resources ResourceConfigList `json:"resources,omitempty"` - // A mapping from Cryostat resources to Kubernetes resources used in OAuth. + // A permission mapping from Cryostat resources to Kubernetes resources used in OAuth. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec OAuthProperties OAuthPropertiesConfigMap `json:"oAuthProperties,omitempty"` @@ -407,7 +407,7 @@ type TemplateConfigMap struct { Filename string `json:"filename"` } -// A ConfigMap containing a mapping between Cryostat resources to Kubernetes resources. +// A ConfigMap containing a permission mapping between Cryostat resources to Kubernetes resources. type OAuthPropertiesConfigMap struct { // Name of config map in the local namespace. // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ConfigMap"} diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 1737168ad..0bd38971c 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -217,6 +217,15 @@ spec: label with key "app" is reserved for use by the operator. displayName: Labels path: networkOptions.grafanaConfig.labels + - description: A permission mapping from Cryostat resources to Kubernetes resources + used in OAuth. + displayName: OAuth Properties + path: oAuthProperties + - description: Name of config map in the local namespace. + displayName: Config Map Name + path: oAuthProperties.configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap - description: Options to configure Cryostat Automated Report Analysis displayName: Report Options path: reportOptions diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index fe4780ee3..f62b5f467 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -1032,6 +1032,21 @@ spec: type: object type: object type: object + oAuthProperties: + description: A permission mapping from Cryostat resources to Kubernetes + resources used in OAuth. + properties: + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the resource + mapping. + type: string + required: + - configMapName + - filename + type: object reportOptions: description: Options to configure Cryostat Automated Report Analysis properties: diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index cedfbd29c..a49fe8398 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -1034,8 +1034,8 @@ spec: type: object type: object oAuthProperties: - description: A mapping from Cryostat resources to Kubernetes resources - used in OAuth. + description: A permission mapping from Cryostat resources to Kubernetes + resources used in OAuth. properties: configMapName: description: Name of config map in the local namespace. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 84d42dabd..c55006dfa 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -205,6 +205,15 @@ spec: label with key "app" is reserved for use by the operator. displayName: Labels path: networkOptions.grafanaConfig.labels + - description: A permission mapping from Cryostat resources to Kubernetes resources + used in OAuth. + displayName: OAuth Properties + path: oAuthProperties + - description: Name of config map in the local namespace. + displayName: Config Map Name + path: oAuthProperties.configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap - description: Options to configure Cryostat Automated Report Analysis displayName: Report Options path: reportOptions From 715c8a73d38ef1ca0654c1cb52527e006deca95d Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 16:52:24 -0400 Subject: [PATCH 08/32] fix(crd): rename prefix oauth to auth for permission mapping --- api/v1beta1/cryostat_types.go | 6 ++-- api/v1beta1/zz_generated.deepcopy.go | 32 +++++++++---------- ...yostat-operator.clusterserviceversion.yaml | 18 +++++------ .../operator.cryostat.io_cryostats.yaml | 30 ++++++++--------- .../bases/operator.cryostat.io_cryostats.yaml | 30 ++++++++--------- ...yostat-operator.clusterserviceversion.yaml | 18 +++++------ .../resource_definitions.go | 24 +++++++------- .../controllers/cryostat_controller_test.go | 8 ++--- internal/test/resources.go | 26 +++++++-------- 9 files changed, 96 insertions(+), 96 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 5741fd936..0002fa24e 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -90,10 +90,10 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec Resources ResourceConfigList `json:"resources,omitempty"` - // A permission mapping from Cryostat resources to Kubernetes resources used in OAuth. + // A permission mapping from Cryostat resources to Kubernetes resources used for authorization. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec - OAuthProperties OAuthPropertiesConfigMap `json:"oAuthProperties,omitempty"` + AuthProperties AuthPropertiesConfigMap `json:"authProperties,omitempty"` } type ResourceConfigList struct { @@ -408,7 +408,7 @@ type TemplateConfigMap struct { } // A ConfigMap containing a permission mapping between Cryostat resources to Kubernetes resources. -type OAuthPropertiesConfigMap struct { +type AuthPropertiesConfigMap struct { // Name of config map in the local namespace. // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ConfigMap"} ConfigMapName string `json:"configMapName"` diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 83a71a17a..03cdbb626 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -48,6 +48,21 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthPropertiesConfigMap) DeepCopyInto(out *AuthPropertiesConfigMap) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthPropertiesConfigMap. +func (in *AuthPropertiesConfigMap) DeepCopy() *AuthPropertiesConfigMap { + if in == nil { + return nil + } + out := new(AuthPropertiesConfigMap) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CertificateSecret) DeepCopyInto(out *CertificateSecret) { *out = *in @@ -199,7 +214,7 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { **out = **in } in.Resources.DeepCopyInto(&out.Resources) - out.OAuthProperties = in.OAuthProperties + out.AuthProperties = in.AuthProperties } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CryostatSpec. @@ -517,21 +532,6 @@ func (in *NetworkConfigurationList) DeepCopy() *NetworkConfigurationList { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OAuthPropertiesConfigMap) DeepCopyInto(out *OAuthPropertiesConfigMap) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OAuthPropertiesConfigMap. -func (in *OAuthPropertiesConfigMap) DeepCopy() *OAuthPropertiesConfigMap { - if in == nil { - return nil - } - out := new(OAuthPropertiesConfigMap) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OptionDescriptor) DeepCopyInto(out *OptionDescriptor) { *out = *in diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 0bd38971c..850242c47 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -120,6 +120,15 @@ spec: name: "" version: v1 specDescriptors: + - description: A permission mapping from Cryostat resources to Kubernetes resources + used for authorization. + displayName: Auth Properties + path: authProperties + - description: Name of config map in the local namespace. + displayName: Config Map Name + path: authProperties.configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap - description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. displayName: Enable cert-manager Integration @@ -217,15 +226,6 @@ spec: label with key "app" is reserved for use by the operator. displayName: Labels path: networkOptions.grafanaConfig.labels - - description: A permission mapping from Cryostat resources to Kubernetes resources - used in OAuth. - displayName: OAuth Properties - path: oAuthProperties - - description: Name of config map in the local namespace. - displayName: Config Map Name - path: oAuthProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - description: Options to configure Cryostat Automated Report Analysis displayName: Report Options path: reportOptions diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index f62b5f467..353cde498 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -43,6 +43,21 @@ spec: spec: description: CryostatSpec defines the desired state of Cryostat properties: + authProperties: + description: A permission mapping from Cryostat resources to Kubernetes + resources used for authorization. + properties: + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the resource + mapping. + type: string + required: + - configMapName + - filename + type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. @@ -1032,21 +1047,6 @@ spec: type: object type: object type: object - oAuthProperties: - description: A permission mapping from Cryostat resources to Kubernetes - resources used in OAuth. - properties: - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - configMapName - - filename - type: object reportOptions: description: Options to configure Cryostat Automated Report Analysis properties: diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index a49fe8398..d7fad9a18 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -44,6 +44,21 @@ spec: spec: description: CryostatSpec defines the desired state of Cryostat properties: + authProperties: + description: A permission mapping from Cryostat resources to Kubernetes + resources used for authorization. + properties: + configMapName: + description: Name of config map in the local namespace. + type: string + filename: + description: Filename within config map containing the resource + mapping. + type: string + required: + - configMapName + - filename + type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. @@ -1033,21 +1048,6 @@ spec: type: object type: object type: object - oAuthProperties: - description: A permission mapping from Cryostat resources to Kubernetes - resources used in OAuth. - properties: - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - configMapName - - filename - type: object reportOptions: description: Options to configure Cryostat Automated Report Analysis properties: diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index c55006dfa..db2f2f4fd 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -108,6 +108,15 @@ spec: name: "" version: v1 specDescriptors: + - description: A permission mapping from Cryostat resources to Kubernetes resources + used for authorization. + displayName: Auth Properties + path: authProperties + - description: Name of config map in the local namespace. + displayName: Config Map Name + path: authProperties.configMapName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ConfigMap - description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. displayName: Enable cert-manager Integration @@ -205,15 +214,6 @@ spec: label with key "app" is reserved for use by the operator. displayName: Labels path: networkOptions.grafanaConfig.labels - - description: A permission mapping from Cryostat resources to Kubernetes resources - used in OAuth. - displayName: OAuth Properties - path: oAuthProperties - - description: Name of config map in the local namespace. - displayName: Config Map Name - path: oAuthProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - description: Options to configure Cryostat Automated Report Analysis displayName: Report Options path: reportOptions diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index c592f3765..c46f933ae 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -351,18 +351,18 @@ func NewPodForCR(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTags *I volumes = append(volumes, eventTemplateVolume) } - // Add OAuth properties as a volume if specified - if cr.Spec.OAuthProperties != (operatorv1beta1.OAuthPropertiesConfigMap{}) { - OAuthResourceVolume := corev1.Volume{ - Name: "oauth-properties-" + cr.Spec.OAuthProperties.ConfigMapName, + // Add Auth properties as a volume if specified + if cr.Spec.AuthProperties != (operatorv1beta1.AuthPropertiesConfigMap{}) { + authResourceVolume := corev1.Volume{ + Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Spec.OAuthProperties.ConfigMapName, + Name: cr.Spec.AuthProperties.ConfigMapName, }, Items: []corev1.KeyToPath{ { - Key: cr.Spec.OAuthProperties.Filename, + Key: cr.Spec.AuthProperties.Filename, Path: "OpenShiftAuthManager.properties", Mode: &readOnlyMode, }, @@ -370,7 +370,7 @@ func NewPodForCR(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTags *I }, }, } - volumes = append(volumes, OAuthResourceVolume) + volumes = append(volumes, authResourceVolume) } // Ensure PV mounts are writable @@ -520,7 +520,7 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa templatesPath := "/opt/cryostat.d/templates.d" clientlibPath := "/opt/cryostat.d/clientlib.d" probesPath := "/opt/cryostat.d/probes.d" - OAuthPropertiesPath := "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties" + authPropertiesPath := "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties" envs := []corev1.EnvVar{ { Name: "CRYOSTAT_WEB_PORT", @@ -692,11 +692,11 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa }, } - // Mount OAuth properties if specified - if cr.Spec.OAuthProperties != (operatorv1beta1.OAuthPropertiesConfigMap{}) { + // Mount Auth properties if specified + if cr.Spec.AuthProperties != (operatorv1beta1.AuthPropertiesConfigMap{}) { mounts = append(mounts, corev1.VolumeMount{ - Name: "oauth-properties-" + cr.Spec.OAuthProperties.ConfigMapName, - MountPath: OAuthPropertiesPath, + Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, + MountPath: authPropertiesPath, SubPath: "OpenShiftAuthManager.properties", ReadOnly: true, }) diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index 446608a7e..f161b5536 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -1299,7 +1299,7 @@ var _ = Describe("CryostatController", func() { }) Context("Cryostat CR has OAuth properties", func() { BeforeEach(func() { - t.objs = append(t.objs, test.NewCryostatWithOAuthProperties(), test.NewOAuthPropertiesConfigMap()) + t.objs = append(t.objs, test.NewCryostatWithAuthProperties(), test.NewAuthPropertiesConfigMap()) }) JustBeforeEach(func() { t.reconcileCryostatFully() @@ -1431,7 +1431,7 @@ var _ = Describe("CryostatController", func() { }) Context("Cryostat CR has OAuth properties", func() { BeforeEach(func() { - t.objs = append(t.objs, test.NewCryostatWithOAuthProperties(), test.NewOAuthPropertiesConfigMap()) + t.objs = append(t.objs, test.NewCryostatWithAuthProperties(), test.NewAuthPropertiesConfigMap()) }) JustBeforeEach(func() { t.reconcileCryostatFully() @@ -2081,11 +2081,11 @@ func (t *cryostatTestInput) checkDeploymentHasOAuthProperties() { Expect(err).ToNot(HaveOccurred()) volumes := deployment.Spec.Template.Spec.Volumes - expectedVolumes := test.NewVolumeWithOAuthProperties(t.TLS) + expectedVolumes := test.NewVolumeWithAuthProperties(t.TLS) Expect(volumes).To(ConsistOf(expectedVolumes)) volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts - expectedVolumeMounts := test.NewVolumeMountsWithOAuthProperties(t.TLS) + expectedVolumeMounts := test.NewVolumeMountsWithAuthProperties(t.TLS) Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) } diff --git a/internal/test/resources.go b/internal/test/resources.go index e0ad549c4..e9716c787 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -369,11 +369,11 @@ func NewCryostatWithResources() *operatorv1beta1.Cryostat { return cr } -func NewCryostatWithOAuthProperties() *operatorv1beta1.Cryostat { +func NewCryostatWithAuthProperties() *operatorv1beta1.Cryostat { cr := NewCryostat() - cr.Spec.OAuthProperties = operatorv1beta1.OAuthPropertiesConfigMap{ - ConfigMapName: "oauthConfigMapName", - Filename: "oauth.properties", + cr.Spec.AuthProperties = operatorv1beta1.AuthPropertiesConfigMap{ + ConfigMapName: "authConfigMapName", + Filename: "auth.properties", } return cr } @@ -1585,10 +1585,10 @@ func NewVolumeMountsWithTemplates(tls bool) []corev1.VolumeMount { }) } -func NewVolumeMountsWithOAuthProperties(tls bool) []corev1.VolumeMount { +func NewVolumeMountsWithAuthProperties(tls bool) []corev1.VolumeMount { return append(NewCoreVolumeMounts(tls), corev1.VolumeMount{ - Name: "oauth-properties-oauthConfigMapName", + Name: "auth-properties-authConfigMapName", ReadOnly: true, MountPath: "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties", SubPath: "OpenShiftAuthManager.properties", @@ -1800,19 +1800,19 @@ func NewVolumesWithTemplates(tls bool) []corev1.Volume { }) } -func NewVolumeWithOAuthProperties(tls bool) []corev1.Volume { +func NewVolumeWithAuthProperties(tls bool) []corev1.Volume { readOnlyMode := int32(0440) return append(NewVolumes(false, tls), corev1.Volume{ - Name: "oauth-properties-oauthConfigMapName", + Name: "auth-properties-authConfigMapName", VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "oauthConfigMapName", + Name: "authConfigMapName", }, Items: []corev1.KeyToPath{ { - Key: "oauth.properties", + Key: "auth.properties", Path: "OpenShiftAuthManager.properties", Mode: &readOnlyMode, }, @@ -2296,14 +2296,14 @@ func NewOtherTemplateConfigMap() *corev1.ConfigMap { } } -func NewOAuthPropertiesConfigMap() *corev1.ConfigMap { +func NewAuthPropertiesConfigMap() *corev1.ConfigMap { return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: "oauthConfigMapName", + Name: "authConfigMapName", Namespace: "default", }, Data: map[string]string{ - "oauth.properties": "CRYOSTAT_RESOURCE=K8S_RESOURCE\nANOTHER_CRYOSTAT_RESOURCE=ANOTHER_K8S_RESOURCE", + "auth.properties": "CRYOSTAT_RESOURCE=K8S_RESOURCE\nANOTHER_CRYOSTAT_RESOURCE=ANOTHER_K8S_RESOURCE", }, } } From 8689c9d427359df631115128f5f9e7c99a26b5d2 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 17:19:36 -0400 Subject: [PATCH 09/32] docs(auth): update docs on permission mappings --- docs/config.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/config.md b/docs/config.md index 862ea4aa9..b4f2f61e6 100644 --- a/docs/config.md +++ b/docs/config.md @@ -269,35 +269,35 @@ spec: ``` -### OAuth Properties +### Authorization Properties -When running on Kubernetes or Openshift, the user is required to have sufficient permissions to certain resources that -are mapped into Cryostat-managed resources to authenticate via Openshift OAuth. +When running on Openshift, the user is required to have sufficient permissions to certain resources that +are mapped into Cryostat-managed resources for authorization. The mappings can be specified using a ConfigMap that is compatible with [`OpenShiftAuthManager.properties`](https://github.com/cryostatio/cryostat/blob/main/src/main/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties). For example: ```yaml apiVersion: v1 kind: ConfigMap metadata: - name: oauth-properties + name: auth-properties data: - oauth.properties: | + auth.properties: | TARGET=pods,deployments.apps RECORDING=pods,pods/exec CERTIFICATE=deployments.apps,pods,cryostats.operator.cryostat.io CREDENTIALS=cryostats.operator.cryostat.io ``` -The property `.spec.OAuthProperties` can then be set to this ConfigMap to configure Cryostat to use this mapping instead of the default ones. +The property `.spec.authProperties` can then be set to this ConfigMap to configure Cryostat to use this mapping instead of the default ones. ```yaml apiVersion: operator.cryostat.io/v1beta1 kind: Cryostat metadata: name: cryostat-sample spec: - OAuthProperties: - configMapName: oauth-properties - filename: oauth.properties + authProperties: + configMapName: auth-properties + filename: auth.properties ``` Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containting resource mappings. From d3bbbd66767f9d08f113100a06aec004d16d273d Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 17:31:06 -0400 Subject: [PATCH 10/32] docs(config): fix typo --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index b4f2f61e6..a22330dd4 100644 --- a/docs/config.md +++ b/docs/config.md @@ -146,7 +146,7 @@ kind: Cryostat metadata: name: cryostat-sample spec: - reportOptions:resource + reportOptions: replicas: 0 subProcessMaxHeapSize: 200 ``` From 7774e28f6b471d1765e55ba136147418bda87e6f Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 17:34:10 -0400 Subject: [PATCH 11/32] docs(config): fix report example yaml --- docs/config.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/config.md b/docs/config.md index a22330dd4..071985cde 100644 --- a/docs/config.md +++ b/docs/config.md @@ -133,9 +133,10 @@ metadata: spec: reportOptions: replicas: 1 - requests: - cpu: 1000m - memory: 512Mi + resources: + requests: + cpu: 1000m + memory: 512Mi ``` If zero sidecar replicas are configured, SubProcessMaxHeapSize configures the maximum heap size of the main Cryostat container's subprocess report generator in MiB. From 4e47149949adeddd77d9e9eafebdfa63293e5ff3 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 17:42:27 -0400 Subject: [PATCH 12/32] fix(apis): update descriptions for authProperties --- api/v1beta1/cryostat_types.go | 2 +- bundle/manifests/cryostat-operator.clusterserviceversion.yaml | 3 ++- bundle/manifests/operator.cryostat.io_cryostats.yaml | 3 ++- config/crd/bases/operator.cryostat.io_cryostats.yaml | 3 ++- .../bases/cryostat-operator.clusterserviceversion.yaml | 3 ++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 0002fa24e..d59ec53b6 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -91,6 +91,7 @@ type CryostatSpec struct { // +operator-sdk:csv:customresourcedefinitions:type=spec Resources ResourceConfigList `json:"resources,omitempty"` // A permission mapping from Cryostat resources to Kubernetes resources used for authorization. + // If the mapping is updated, Cryostat must be manually restarted. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec AuthProperties AuthPropertiesConfigMap `json:"authProperties,omitempty"` @@ -155,7 +156,6 @@ type StorageConfiguration struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec PVC *PersistentVolumeClaimConfig `json:"pvc,omitempty"` - // Configuration for an EmptyDir to be created // by the operator instead of a PVC. // +optional diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 850242c47..ffce37d7a 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -121,7 +121,8 @@ spec: version: v1 specDescriptors: - description: A permission mapping from Cryostat resources to Kubernetes resources - used for authorization. + used for authorization. If the mapping is updated, Cryostat must be manually + restarted. displayName: Auth Properties path: authProperties - description: Name of config map in the local namespace. diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 353cde498..694ad62bd 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -45,7 +45,8 @@ spec: properties: authProperties: description: A permission mapping from Cryostat resources to Kubernetes - resources used for authorization. + resources used for authorization. If the mapping is updated, Cryostat + must be manually restarted. properties: configMapName: description: Name of config map in the local namespace. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index d7fad9a18..7f447daa3 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -46,7 +46,8 @@ spec: properties: authProperties: description: A permission mapping from Cryostat resources to Kubernetes - resources used for authorization. + resources used for authorization. If the mapping is updated, Cryostat + must be manually restarted. properties: configMapName: description: Name of config map in the local namespace. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index db2f2f4fd..aef3f3a99 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -109,7 +109,8 @@ spec: version: v1 specDescriptors: - description: A permission mapping from Cryostat resources to Kubernetes resources - used for authorization. + used for authorization. If the mapping is updated, Cryostat must be manually + restarted. displayName: Auth Properties path: authProperties - description: Name of config map in the local namespace. From 9b5d94b6210d2936dbf6eb8b3d526908272d8bad Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 17:44:05 -0400 Subject: [PATCH 13/32] docs(config): update config docs --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 071985cde..30839eda5 100644 --- a/docs/config.md +++ b/docs/config.md @@ -301,4 +301,4 @@ spec: filename: auth.properties ``` -Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containting resource mappings. +Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containting resource mappings. If the mapping is updated, Cryostat must be manually restarted. From 3495ebdd4ad7b83530916b0e3ccce4fc298e1458 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 17:57:21 -0400 Subject: [PATCH 14/32] fix(apis): add full display name for auth properties --- api/v1beta1/cryostat_types.go | 2 +- bundle/manifests/cryostat-operator.clusterserviceversion.yaml | 2 +- .../bases/cryostat-operator.clusterserviceversion.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index d59ec53b6..7041b7035 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -93,7 +93,7 @@ type CryostatSpec struct { // A permission mapping from Cryostat resources to Kubernetes resources used for authorization. // If the mapping is updated, Cryostat must be manually restarted. // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties" AuthProperties AuthPropertiesConfigMap `json:"authProperties,omitempty"` } diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index ffce37d7a..b24cdaa78 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -123,7 +123,7 @@ spec: - description: A permission mapping from Cryostat resources to Kubernetes resources used for authorization. If the mapping is updated, Cryostat must be manually restarted. - displayName: Auth Properties + displayName: Authorization Properties path: authProperties - description: Name of config map in the local namespace. displayName: Config Map Name diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index aef3f3a99..468279707 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -111,7 +111,7 @@ spec: - description: A permission mapping from Cryostat resources to Kubernetes resources used for authorization. If the mapping is updated, Cryostat must be manually restarted. - displayName: Auth Properties + displayName: Authorization Properties path: authProperties - description: Name of config map in the local namespace. displayName: Config Map Name From 3113d70e09147b631d23ad8f063f6e9d5eaf486e Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 17:59:36 -0400 Subject: [PATCH 15/32] fix(apis): make authProperties as pointer --- api/v1beta1/cryostat_types.go | 2 +- api/v1beta1/zz_generated.deepcopy.go | 6 +++++- .../common/resource_definitions/resource_definitions.go | 4 ++-- internal/test/resources.go | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 7041b7035..cd6ffc181 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -94,7 +94,7 @@ type CryostatSpec struct { // If the mapping is updated, Cryostat must be manually restarted. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties" - AuthProperties AuthPropertiesConfigMap `json:"authProperties,omitempty"` + AuthProperties *AuthPropertiesConfigMap `json:"authProperties,omitempty"` } type ResourceConfigList struct { diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 03cdbb626..39157aad7 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -214,7 +214,11 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { **out = **in } in.Resources.DeepCopyInto(&out.Resources) - out.AuthProperties = in.AuthProperties + if in.AuthProperties != nil { + in, out := &in.AuthProperties, &out.AuthProperties + *out = new(AuthPropertiesConfigMap) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CryostatSpec. diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index c46f933ae..f4a2d63e8 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -352,7 +352,7 @@ func NewPodForCR(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTags *I } // Add Auth properties as a volume if specified - if cr.Spec.AuthProperties != (operatorv1beta1.AuthPropertiesConfigMap{}) { + if cr.Spec.AuthProperties != nil { authResourceVolume := corev1.Volume{ Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, VolumeSource: corev1.VolumeSource{ @@ -693,7 +693,7 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa } // Mount Auth properties if specified - if cr.Spec.AuthProperties != (operatorv1beta1.AuthPropertiesConfigMap{}) { + if cr.Spec.AuthProperties != nil { mounts = append(mounts, corev1.VolumeMount{ Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, MountPath: authPropertiesPath, diff --git a/internal/test/resources.go b/internal/test/resources.go index e9716c787..3ca895889 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -371,7 +371,7 @@ func NewCryostatWithResources() *operatorv1beta1.Cryostat { func NewCryostatWithAuthProperties() *operatorv1beta1.Cryostat { cr := NewCryostat() - cr.Spec.AuthProperties = operatorv1beta1.AuthPropertiesConfigMap{ + cr.Spec.AuthProperties = &operatorv1beta1.AuthPropertiesConfigMap{ ConfigMapName: "authConfigMapName", Filename: "auth.properties", } From 7143ec984396a0d22be4f2a66ff220d34e6c0601 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 18:05:04 -0400 Subject: [PATCH 16/32] docs(config): update config docs --- docs/config.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/config.md b/docs/config.md index 30839eda5..be8b724dd 100644 --- a/docs/config.md +++ b/docs/config.md @@ -272,10 +272,9 @@ spec: ### Authorization Properties -When running on Openshift, the user is required to have sufficient permissions to certain resources that -are mapped into Cryostat-managed resources for authorization. +When running on OpenShift, the user is required to have sufficient permissions for certain Kubernetes resources that are mapped into Cryostat-managed resources for authorization. -The mappings can be specified using a ConfigMap that is compatible with [`OpenShiftAuthManager.properties`](https://github.com/cryostatio/cryostat/blob/main/src/main/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties). For example: +The mappings can be specified using a ConfigMap that is compatible with [`OpenShiftAuthManager.properties`](https://github.com/cryostatio/cryostat/blob/bd95e1a11e9e29cc39559f4a5fdeaae77e81b4c6/src/main/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties). For example: ```yaml apiVersion: v1 kind: ConfigMap @@ -301,4 +300,4 @@ spec: filename: auth.properties ``` -Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containting resource mappings. If the mapping is updated, Cryostat must be manually restarted. +Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containing resource mappings. If the mapping is updated, Cryostat must be manually restarted. From 8df56bc2eed1cc72be97dc4d27ba1a8e9be1bda5 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 18:32:59 -0400 Subject: [PATCH 17/32] fix(test): update methods name and context descriptions --- internal/controllers/cryostat_controller_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index f161b5536..fff4ee52e 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -1297,7 +1297,7 @@ var _ = Describe("CryostatController", func() { }) }) }) - Context("Cryostat CR has OAuth properties", func() { + Context("Cryostat CR has authorization properties", func() { BeforeEach(func() { t.objs = append(t.objs, test.NewCryostatWithAuthProperties(), test.NewAuthPropertiesConfigMap()) }) @@ -1305,7 +1305,7 @@ var _ = Describe("CryostatController", func() { t.reconcileCryostatFully() }) It("Should add volumes and volumeMounts to deployment", func() { - t.checkDeploymentHasOAuthProperties() + t.checkDeploymentHasAuthProperties() }) }) }) @@ -1429,7 +1429,7 @@ var _ = Describe("CryostatController", func() { Expect(kerrors.IsNotFound(err)).To(BeTrue()) }) }) - Context("Cryostat CR has OAuth properties", func() { + Context("Cryostat CR has authorization properties", func() { BeforeEach(func() { t.objs = append(t.objs, test.NewCryostatWithAuthProperties(), test.NewAuthPropertiesConfigMap()) }) @@ -1437,7 +1437,7 @@ var _ = Describe("CryostatController", func() { t.reconcileCryostatFully() }) It("Should add volumes and volumeMounts to deployment", func() { - t.checkDeploymentHasOAuthProperties() + t.checkDeploymentHasAuthProperties() }) }) }) @@ -2075,7 +2075,7 @@ func (t *cryostatTestInput) checkDeploymentHasTemplates() { Expect(volumeMounts).To(Equal(expectedVolumeMounts)) } -func (t *cryostatTestInput) checkDeploymentHasOAuthProperties() { +func (t *cryostatTestInput) checkDeploymentHasAuthProperties() { deployment := &appsv1.Deployment{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: "cryostat", Namespace: "default"}, deployment) Expect(err).ToNot(HaveOccurred()) From 4bd844b81a728d71385a4b2e0147bf2b99021a09 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 18 Aug 2022 19:20:55 -0400 Subject: [PATCH 18/32] fix(tests): use ConsistsOf to compare slices --- internal/controllers/cryostat_controller_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index fff4ee52e..6570a5137 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -658,11 +658,11 @@ var _ = Describe("CryostatController", func() { volumes := deployment.Spec.Template.Spec.Volumes expectedVolumes := test.NewVolumesWithSecrets(t.TLS) - Expect(volumes).To(Equal(expectedVolumes)) + Expect(volumes).To(ConsistOf(expectedVolumes)) volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts expectedVolumeMounts := test.NewCoreVolumeMounts(t.TLS) - Expect(volumeMounts).To(Equal(expectedVolumeMounts)) + Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) }) }) Context("Cryostat CR has list of event templates", func() { @@ -1824,11 +1824,11 @@ func (t *cryostatTestInput) expectDeploymentHasCertSecrets() { volumes := deployment.Spec.Template.Spec.Volumes expectedVolumes := test.NewVolumesWithSecrets(t.TLS) - Expect(volumes).To(Equal(expectedVolumes)) + Expect(volumes).To(ConsistOf(expectedVolumes)) volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts expectedVolumeMounts := test.NewCoreVolumeMounts(t.TLS) - Expect(volumeMounts).To(Equal(expectedVolumeMounts)) + Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) } func (t *cryostatTestInput) expectIdempotence() { @@ -1982,7 +1982,7 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, "kind": "cryostat", "component": "cryostat", })) - Expect(template.Spec.Volumes).To(Equal(test.NewVolumes(t.minimal, t.TLS))) + Expect(template.Spec.Volumes).To(ConsistOf(test.NewVolumes(t.minimal, t.TLS))) Expect(template.Spec.SecurityContext).To(Equal(test.NewPodSecurityContext())) // Check that the networking environment variables are set correctly @@ -2050,7 +2050,7 @@ func (t *cryostatTestInput) checkReportsDeployment() { "kind": "cryostat", "component": "reports", })) - Expect(template.Spec.Volumes).To(Equal(test.NewReportsVolumes(t.TLS))) + Expect(template.Spec.Volumes).To(ConsistOf(test.NewReportsVolumes(t.TLS))) var resources corev1.ResourceRequirements if cr.Spec.ReportOptions != nil { @@ -2068,11 +2068,11 @@ func (t *cryostatTestInput) checkDeploymentHasTemplates() { volumes := deployment.Spec.Template.Spec.Volumes expectedVolumes := test.NewVolumesWithTemplates(t.TLS) - Expect(volumes).To(Equal(expectedVolumes)) + Expect(volumes).To(ConsistOf(expectedVolumes)) volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts expectedVolumeMounts := test.NewVolumeMountsWithTemplates(t.TLS) - Expect(volumeMounts).To(Equal(expectedVolumeMounts)) + Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) } func (t *cryostatTestInput) checkDeploymentHasAuthProperties() { From 6a69dea181a711be3a8de1a6e7b53c7f32e75799 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Mon, 22 Aug 2022 14:35:09 -0400 Subject: [PATCH 19/32] fix(crds): refine authorization spec field --- api/v1beta1/cryostat_types.go | 13 ++++++++----- api/v1beta1/zz_generated.deepcopy.go | 10 +++++----- .../cryostat-operator.clusterserviceversion.yaml | 10 +++++++--- .../manifests/operator.cryostat.io_cryostats.yaml | 9 ++++++--- .../crd/bases/operator.cryostat.io_cryostats.yaml | 9 ++++++--- .../cryostat-operator.clusterserviceversion.yaml | 10 +++++++--- .../resource_definitions/resource_definitions.go | 8 +++++++- 7 files changed, 46 insertions(+), 23 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index cd6ffc181..f15e29cda 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -90,11 +90,10 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec Resources ResourceConfigList `json:"resources,omitempty"` - // A permission mapping from Cryostat resources to Kubernetes resources used for authorization. - // If the mapping is updated, Cryostat must be manually restarted. + // Authorization properties tp preconfigure for Cryostat. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties" - AuthProperties *AuthPropertiesConfigMap `json:"authProperties,omitempty"` + AuthProperties *AuthorizationProperties `json:"authProperties,omitempty"` } type ResourceConfigList struct { @@ -407,8 +406,12 @@ type TemplateConfigMap struct { Filename string `json:"filename"` } -// A ConfigMap containing a permission mapping between Cryostat resources to Kubernetes resources. -type AuthPropertiesConfigMap struct { +// Authorization properties provide custom permission mapping between Cryostat resources to Kubernetes resources. +// If the mapping is updated, Cryostat must be manually restarted. +type AuthorizationProperties struct { + // Name of cluster role defining access rules for mapped Kubernetes resources. + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ClusterRole"} + CluserRoleName string `json:"clusterRoleName"` // Name of config map in the local namespace. // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ConfigMap"} ConfigMapName string `json:"configMapName"` diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 39157aad7..51a99e176 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -49,16 +49,16 @@ import ( ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AuthPropertiesConfigMap) DeepCopyInto(out *AuthPropertiesConfigMap) { +func (in *AuthorizationProperties) DeepCopyInto(out *AuthorizationProperties) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthPropertiesConfigMap. -func (in *AuthPropertiesConfigMap) DeepCopy() *AuthPropertiesConfigMap { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthorizationProperties. +func (in *AuthorizationProperties) DeepCopy() *AuthorizationProperties { if in == nil { return nil } - out := new(AuthPropertiesConfigMap) + out := new(AuthorizationProperties) in.DeepCopyInto(out) return out } @@ -216,7 +216,7 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { in.Resources.DeepCopyInto(&out.Resources) if in.AuthProperties != nil { in, out := &in.AuthProperties, &out.AuthProperties - *out = new(AuthPropertiesConfigMap) + *out = new(AuthorizationProperties) **out = **in } } diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index b24cdaa78..9d244d87c 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -120,11 +120,15 @@ spec: name: "" version: v1 specDescriptors: - - description: A permission mapping from Cryostat resources to Kubernetes resources - used for authorization. If the mapping is updated, Cryostat must be manually - restarted. + - description: Authorization properties tp preconfigure for Cryostat. displayName: Authorization Properties path: authProperties + - description: Name of cluster role defining access rules for mapped Kubernetes + resources. + displayName: Cluser Role Name + path: authProperties.clusterRoleName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ClusterRole - description: Name of config map in the local namespace. displayName: Config Map Name path: authProperties.configMapName diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 694ad62bd..ac3d5843a 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -44,10 +44,12 @@ spec: description: CryostatSpec defines the desired state of Cryostat properties: authProperties: - description: A permission mapping from Cryostat resources to Kubernetes - resources used for authorization. If the mapping is updated, Cryostat - must be manually restarted. + description: Authorization properties tp preconfigure for Cryostat. properties: + clusterRoleName: + description: Name of cluster role defining access rules for mapped + Kubernetes resources. + type: string configMapName: description: Name of config map in the local namespace. type: string @@ -56,6 +58,7 @@ spec: mapping. type: string required: + - clusterRoleName - configMapName - filename type: object diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 7f447daa3..5047eea96 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -45,10 +45,12 @@ spec: description: CryostatSpec defines the desired state of Cryostat properties: authProperties: - description: A permission mapping from Cryostat resources to Kubernetes - resources used for authorization. If the mapping is updated, Cryostat - must be manually restarted. + description: Authorization properties tp preconfigure for Cryostat. properties: + clusterRoleName: + description: Name of cluster role defining access rules for mapped + Kubernetes resources. + type: string configMapName: description: Name of config map in the local namespace. type: string @@ -57,6 +59,7 @@ spec: mapping. type: string required: + - clusterRoleName - configMapName - filename type: object diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 468279707..77dbf1cd5 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -108,11 +108,15 @@ spec: name: "" version: v1 specDescriptors: - - description: A permission mapping from Cryostat resources to Kubernetes resources - used for authorization. If the mapping is updated, Cryostat must be manually - restarted. + - description: Authorization properties tp preconfigure for Cryostat. displayName: Authorization Properties path: authProperties + - description: Name of cluster role defining access rules for mapped Kubernetes + resources. + displayName: Cluser Role Name + path: authProperties.clusterRoleName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:ClusterRole - description: Name of config map in the local namespace. displayName: Config Map Name path: authProperties.configMapName diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index f4a2d63e8..34180d85f 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -622,6 +622,11 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa envs = append(envs, jmxCacheEnvs...) if openshift { + OAuthClusterRoleName := "cryostat-operator-oauth-client" + if cr.Spec.AuthProperties != nil { + OAuthClusterRoleName = cr.Spec.AuthProperties.CluserRoleName + } + // Force OpenShift platform strategy openshiftEnvs := []corev1.EnvVar{ { @@ -638,9 +643,10 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa }, { Name: "CRYOSTAT_OAUTH_ROLE", - Value: "cryostat-operator-oauth-client", + Value: OAuthClusterRoleName, }, } + envs = append(envs, openshiftEnvs...) } envsFrom := []corev1.EnvFromSource{ From 023239205990deea55f5367f7527c0ee3cf72967 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Mon, 22 Aug 2022 15:26:21 -0400 Subject: [PATCH 20/32] fix(crds): fix description typo --- api/v1beta1/cryostat_types.go | 4 ++-- bundle/manifests/cryostat-operator.clusterserviceversion.yaml | 4 ++-- bundle/manifests/operator.cryostat.io_cryostats.yaml | 4 ++-- config/crd/bases/operator.cryostat.io_cryostats.yaml | 4 ++-- .../bases/cryostat-operator.clusterserviceversion.yaml | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index f15e29cda..b2a0c2b42 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -90,7 +90,7 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec Resources ResourceConfigList `json:"resources,omitempty"` - // Authorization properties tp preconfigure for Cryostat. + // Authorization properties to preconfigure in Cryostat. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties" AuthProperties *AuthorizationProperties `json:"authProperties,omitempty"` @@ -409,7 +409,7 @@ type TemplateConfigMap struct { // Authorization properties provide custom permission mapping between Cryostat resources to Kubernetes resources. // If the mapping is updated, Cryostat must be manually restarted. type AuthorizationProperties struct { - // Name of cluster role defining access rules for mapped Kubernetes resources. + // Name of ClusterRole defining access rules for mapped Kubernetes resources. // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ClusterRole"} CluserRoleName string `json:"clusterRoleName"` // Name of config map in the local namespace. diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 9d244d87c..1f42d14e9 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -120,10 +120,10 @@ spec: name: "" version: v1 specDescriptors: - - description: Authorization properties tp preconfigure for Cryostat. + - description: Authorization properties to preconfigure in Cryostat. displayName: Authorization Properties path: authProperties - - description: Name of cluster role defining access rules for mapped Kubernetes + - description: Name of ClusterRole defining access rules for mapped Kubernetes resources. displayName: Cluser Role Name path: authProperties.clusterRoleName diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index ac3d5843a..0800da7db 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -44,10 +44,10 @@ spec: description: CryostatSpec defines the desired state of Cryostat properties: authProperties: - description: Authorization properties tp preconfigure for Cryostat. + description: Authorization properties to preconfigure in Cryostat. properties: clusterRoleName: - description: Name of cluster role defining access rules for mapped + description: Name of ClusterRole defining access rules for mapped Kubernetes resources. type: string configMapName: diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 5047eea96..63593359f 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -45,10 +45,10 @@ spec: description: CryostatSpec defines the desired state of Cryostat properties: authProperties: - description: Authorization properties tp preconfigure for Cryostat. + description: Authorization properties to preconfigure in Cryostat. properties: clusterRoleName: - description: Name of cluster role defining access rules for mapped + description: Name of ClusterRole defining access rules for mapped Kubernetes resources. type: string configMapName: diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 77dbf1cd5..46b1fa016 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -108,10 +108,10 @@ spec: name: "" version: v1 specDescriptors: - - description: Authorization properties tp preconfigure for Cryostat. + - description: Authorization properties to preconfigure in Cryostat. displayName: Authorization Properties path: authProperties - - description: Name of cluster role defining access rules for mapped Kubernetes + - description: Name of ClusterRole defining access rules for mapped Kubernetes resources. displayName: Cluser Role Name path: authProperties.clusterRoleName From fb5f8c8ca5a4361bb9aaa90021247a40e3c3c17e Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Mon, 22 Aug 2022 15:32:15 -0400 Subject: [PATCH 21/32] docs(config): update config docs --- docs/config.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index be8b724dd..18b60e7c9 100644 --- a/docs/config.md +++ b/docs/config.md @@ -288,7 +288,9 @@ data: CREDENTIALS=cryostats.operator.cryostat.io ``` -The property `.spec.authProperties` can then be set to this ConfigMap to configure Cryostat to use this mapping instead of the default ones. +If custom mapping is specified, the user is also required to create a ClusterRole that defines access rules for mapped Kubernetes resources. + +The property `.spec.authProperties` can then be set to configure Cryostat to use this mapping instead of the default ones. ```yaml apiVersion: operator.cryostat.io/v1beta1 kind: Cryostat @@ -298,6 +300,9 @@ spec: authProperties: configMapName: auth-properties filename: auth.properties + clusterRoleName: oauth-cluster-role ``` -Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containing resource mappings. If the mapping is updated, Cryostat must be manually restarted. +Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containing resource mappings. The `clusterRoleName` must be a valid name of an existing Cluster Role. + +**Note:** If the mapping is updated, Cryostat must be manually restarted. From 6b816735e5dab7f3c80b86de62278b794a39235e Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Mon, 22 Aug 2022 15:34:42 -0400 Subject: [PATCH 22/32] fix(tests): fix test resource definition --- internal/test/resources.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/test/resources.go b/internal/test/resources.go index 3ca895889..af26f4a1d 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -371,9 +371,10 @@ func NewCryostatWithResources() *operatorv1beta1.Cryostat { func NewCryostatWithAuthProperties() *operatorv1beta1.Cryostat { cr := NewCryostat() - cr.Spec.AuthProperties = &operatorv1beta1.AuthPropertiesConfigMap{ - ConfigMapName: "authConfigMapName", - Filename: "auth.properties", + cr.Spec.AuthProperties = &operatorv1beta1.AuthorizationProperties{ + ConfigMapName: "authConfigMapName", + Filename: "auth.properties", + CluserRoleName: "oauth-cluster-role", } return cr } From 956d3389aa18541acb4f9c3763bfc16b641b315c Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Mon, 22 Aug 2022 18:04:18 -0400 Subject: [PATCH 23/32] tests(auth): update auth-props to check env vars on openshift --- internal/controllers/cryostat_controller_test.go | 14 ++++++++++---- internal/test/resources.go | 8 ++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index 6570a5137..72f0d0ef6 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -2001,7 +2001,7 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, reportsUrl = "http://cryostat-reports:" + port } - checkCoreContainer(&coreContainer, t.minimal, t.TLS, t.externalTLS, t.EnvCoreImageTag, t.controller.IsOpenShift, reportsUrl, cr.Spec.Resources.CoreResources) + checkCoreContainer(&coreContainer, t.minimal, t.TLS, t.externalTLS, t.EnvCoreImageTag, t.controller.IsOpenShift, reportsUrl, cr.Spec.AuthProperties != nil, cr.Spec.Resources.CoreResources) if !t.minimal { // Check that Grafana is configured properly, depending on the environment @@ -2084,13 +2084,19 @@ func (t *cryostatTestInput) checkDeploymentHasAuthProperties() { expectedVolumes := test.NewVolumeWithAuthProperties(t.TLS) Expect(volumes).To(ConsistOf(expectedVolumes)) - volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts + coreContainer := deployment.Spec.Template.Spec.Containers[0] + + volumeMounts := coreContainer.VolumeMounts expectedVolumeMounts := test.NewVolumeMountsWithAuthProperties(t.TLS) Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) + + if t.controller.IsOpenShift { // Only check env vars if running on Openshift + Expect(coreContainer.Env).To(ConsistOf(test.NewCoreEnvironmentVariables(t.minimal, t.TLS, t.externalTLS, t.controller.IsOpenShift, "", true))) + } } func checkCoreContainer(container *corev1.Container, minimal bool, tls bool, externalTLS bool, - tag *string, openshift bool, reportsUrl string, resources corev1.ResourceRequirements) { + tag *string, openshift bool, reportsUrl string, authProps bool, resources corev1.ResourceRequirements) { Expect(container.Name).To(Equal("cryostat")) if tag == nil { Expect(container.Image).To(HavePrefix("quay.io/cryostat/cryostat:")) @@ -2098,7 +2104,7 @@ func checkCoreContainer(container *corev1.Container, minimal bool, tls bool, ext Expect(container.Image).To(Equal(*tag)) } Expect(container.Ports).To(ConsistOf(test.NewCorePorts())) - Expect(container.Env).To(ConsistOf(test.NewCoreEnvironmentVariables(minimal, tls, externalTLS, openshift, reportsUrl))) + Expect(container.Env).To(ConsistOf(test.NewCoreEnvironmentVariables(minimal, tls, externalTLS, openshift, reportsUrl, authProps))) Expect(container.EnvFrom).To(ConsistOf(test.NewCoreEnvFromSource(tls))) Expect(container.VolumeMounts).To(ConsistOf(test.NewCoreVolumeMounts(tls))) Expect(container.LivenessProbe).To(Equal(test.NewCoreLivenessProbe(tls))) diff --git a/internal/test/resources.go b/internal/test/resources.go index af26f4a1d..0412dee5f 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1209,7 +1209,7 @@ func NewReportsPorts() []corev1.ContainerPort { } } -func NewCoreEnvironmentVariables(minimal bool, tls bool, externalTLS bool, openshift bool, reportsUrl string) []corev1.EnvVar { +func NewCoreEnvironmentVariables(minimal bool, tls bool, externalTLS bool, openshift bool, reportsUrl string, authProps bool) []corev1.EnvVar { envs := []corev1.EnvVar{ { Name: "CRYOSTAT_WEB_PORT", @@ -1320,6 +1320,10 @@ func NewCoreEnvironmentVariables(minimal bool, tls bool, externalTLS bool, opens }) } if openshift { + OAuthClusterRoleName := "cryostat-operator-oauth-client" + if authProps { + OAuthClusterRoleName = "oauth-cluster-role" + } envs = append(envs, corev1.EnvVar{ Name: "CRYOSTAT_PLATFORM", @@ -1335,7 +1339,7 @@ func NewCoreEnvironmentVariables(minimal bool, tls bool, externalTLS bool, opens }, corev1.EnvVar{ Name: "CRYOSTAT_OAUTH_ROLE", - Value: "cryostat-operator-oauth-client", + Value: OAuthClusterRoleName, }) } if reportsUrl != "" { From 7a47f00dd14d31eda9a20a00b525a4e856b2f08b Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 23 Aug 2022 16:26:19 -0400 Subject: [PATCH 24/32] temp: modify default-oauth --- config/rbac/oauth_client.yaml | 62 ++++++++++++++++------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/config/rbac/oauth_client.yaml b/config/rbac/oauth_client.yaml index cb58d7caf..8d42bf2e0 100644 --- a/config/rbac/oauth_client.yaml +++ b/config/rbac/oauth_client.yaml @@ -6,20 +6,6 @@ metadata: creationTimestamp: null name: oauth-client rules: -- apiGroups: - - "" - resources: - - pods - verbs: - - create - - get -- apiGroups: - - "" - resources: - - replicationcontrollers - - endpoints - verbs: - - get - apiGroups: - operator.cryostat.io resources: @@ -29,27 +15,35 @@ rules: - delete - get - apiGroups: - - operator.cryostat.io - resources: - - flightrecorders - - recordings - verbs: - - create - - delete - - get - - patch -- apiGroups: - - apps + - "" resources: - - deployments + - pods + - pods/exec + - services + - secrets verbs: - create - get -- apiGroups: - - apps - resources: - - daemonsets - - replicasets - - statefulsets - verbs: - - get + - delete +# - apiGroups: +# - "" +# resources: +# - replicationcontrollers +# - endpoints +# verbs: +# - get +# - apiGroups: +# - apps +# resources: +# - deployments +# verbs: +# - create +# - get +# - apiGroups: +# - apps +# resources: +# - daemonsets +# - replicasets +# - statefulsets +# verbs: +# - get From 44db0d079ee9c8bb3c492f1e8d42f12436b2339a Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 24 Aug 2022 12:42:05 -0400 Subject: [PATCH 25/32] fix(apis): update descriptions for CR specs --- api/v1beta1/cryostat_types.go | 8 ++-- ...c.authorization.k8s.io_v1_clusterrole.yaml | 40 +++---------------- ...yostat-operator.clusterserviceversion.yaml | 9 +++-- .../operator.cryostat.io_cryostats.yaml | 9 +++-- .../bases/operator.cryostat.io_cryostats.yaml | 9 +++-- ...yostat-operator.clusterserviceversion.yaml | 9 +++-- 6 files changed, 35 insertions(+), 49 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index b2a0c2b42..958fe80e6 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -90,9 +90,9 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec Resources ResourceConfigList `json:"resources,omitempty"` - // Authorization properties to preconfigure in Cryostat. + // Override default authorization properties for Cryostat on OpenShift. // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties" + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} AuthProperties *AuthorizationProperties `json:"authProperties,omitempty"` } @@ -409,7 +409,9 @@ type TemplateConfigMap struct { // Authorization properties provide custom permission mapping between Cryostat resources to Kubernetes resources. // If the mapping is updated, Cryostat must be manually restarted. type AuthorizationProperties struct { - // Name of ClusterRole defining access rules for mapped Kubernetes resources. + // Name of the ClusterRole to use when Cryostat requests a role-scoped OAuth token. + // This ClusterRole should contain permissions for all Kubernetes objects listed in custom permission mapping. + // More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ClusterRole"} CluserRoleName string `json:"clusterRoleName"` // Name of config map in the local namespace. diff --git a/bundle/manifests/cryostat-operator-oauth-client_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/cryostat-operator-oauth-client_rbac.authorization.k8s.io_v1_clusterrole.yaml index feea14b58..8b6cfe496 100644 --- a/bundle/manifests/cryostat-operator-oauth-client_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/bundle/manifests/cryostat-operator-oauth-client_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -4,20 +4,6 @@ metadata: creationTimestamp: null name: cryostat-operator-oauth-client rules: -- apiGroups: - - "" - resources: - - pods - verbs: - - create - - get -- apiGroups: - - "" - resources: - - replicationcontrollers - - endpoints - verbs: - - get - apiGroups: - operator.cryostat.io resources: @@ -27,27 +13,13 @@ rules: - delete - get - apiGroups: - - operator.cryostat.io - resources: - - flightrecorders - - recordings - verbs: - - create - - delete - - get - - patch -- apiGroups: - - apps + - "" resources: - - deployments + - pods + - pods/exec + - services + - secrets verbs: - create - get -- apiGroups: - - apps - resources: - - daemonsets - - replicasets - - statefulsets - verbs: - - get + - delete diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 1f42d14e9..68d2da877 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -120,11 +120,14 @@ spec: name: "" version: v1 specDescriptors: - - description: Authorization properties to preconfigure in Cryostat. + - description: Override default authorization properties for Cryostat on OpenShift. displayName: Authorization Properties path: authProperties - - description: Name of ClusterRole defining access rules for mapped Kubernetes - resources. + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped + OAuth token. This ClusterRole should contain permissions for all Kubernetes + objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' displayName: Cluser Role Name path: authProperties.clusterRoleName x-descriptors: diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 0800da7db..9bbefed44 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -44,11 +44,14 @@ spec: description: CryostatSpec defines the desired state of Cryostat properties: authProperties: - description: Authorization properties to preconfigure in Cryostat. + description: Override default authorization properties for Cryostat + on OpenShift. properties: clusterRoleName: - description: Name of ClusterRole defining access rules for mapped - Kubernetes resources. + description: 'Name of the ClusterRole to use when Cryostat requests + a role-scoped OAuth token. This ClusterRole should contain permissions + for all Kubernetes objects listed in custom permission mapping. + More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' type: string configMapName: description: Name of config map in the local namespace. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 63593359f..2971d1bda 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -45,11 +45,14 @@ spec: description: CryostatSpec defines the desired state of Cryostat properties: authProperties: - description: Authorization properties to preconfigure in Cryostat. + description: Override default authorization properties for Cryostat + on OpenShift. properties: clusterRoleName: - description: Name of ClusterRole defining access rules for mapped - Kubernetes resources. + description: 'Name of the ClusterRole to use when Cryostat requests + a role-scoped OAuth token. This ClusterRole should contain permissions + for all Kubernetes objects listed in custom permission mapping. + More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' type: string configMapName: description: Name of config map in the local namespace. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 46b1fa016..563f4a238 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -108,11 +108,14 @@ spec: name: "" version: v1 specDescriptors: - - description: Authorization properties to preconfigure in Cryostat. + - description: Override default authorization properties for Cryostat on OpenShift. displayName: Authorization Properties path: authProperties - - description: Name of ClusterRole defining access rules for mapped Kubernetes - resources. + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped + OAuth token. This ClusterRole should contain permissions for all Kubernetes + objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' displayName: Cluser Role Name path: authProperties.clusterRoleName x-descriptors: From 9ef15d65547ce73885de98331eaaaddc09f332bc Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 24 Aug 2022 13:16:32 -0400 Subject: [PATCH 26/32] fix(auth-props): only configure auth properties on Openshift --- .../resource_definitions.go | 120 +++++++++--------- .../controllers/cryostat_controller_test.go | 25 +++- internal/test/resources.go | 49 +++---- 3 files changed, 106 insertions(+), 88 deletions(-) diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index 34180d85f..bd90d51f9 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -351,8 +351,8 @@ func NewPodForCR(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTags *I volumes = append(volumes, eventTemplateVolume) } - // Add Auth properties as a volume if specified - if cr.Spec.AuthProperties != nil { + // Add Auth properties as a volume if specified (on Openshift) + if openshift && cr.Spec.AuthProperties != nil { authResourceVolume := corev1.Volume{ Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, VolumeSource: corev1.VolumeSource{ @@ -521,6 +521,7 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa clientlibPath := "/opt/cryostat.d/clientlib.d" probesPath := "/opt/cryostat.d/probes.d" authPropertiesPath := "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties" + envs := []corev1.EnvVar{ { Name: "CRYOSTAT_WEB_PORT", @@ -551,6 +552,46 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa Value: "false", }, } + + mounts := []corev1.VolumeMount{ + { + Name: cr.Name, + MountPath: configPath, + SubPath: "config", + }, + { + Name: cr.Name, + MountPath: archivePath, + SubPath: "flightrecordings", + }, + { + Name: cr.Name, + MountPath: templatesPath, + SubPath: "templates", + }, + { + Name: cr.Name, + MountPath: clientlibPath, + SubPath: "clientlib", + }, + { + Name: cr.Name, + MountPath: probesPath, + SubPath: "probes", + }, + { + Name: cr.Name, + MountPath: "truststore", + SubPath: "truststore", + }, + { + // Mount the CA cert and user certificates in the expected /truststore location + Name: "cert-secrets", + MountPath: "/truststore/operator", + ReadOnly: true, + }, + } + if specs.CoreURL != nil { coreEnvs := []corev1.EnvVar{ { @@ -620,10 +661,26 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa }, } envs = append(envs, jmxCacheEnvs...) + envsFrom := []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Name + "-jmx-auth", + }, + }, + }, + } if openshift { OAuthClusterRoleName := "cryostat-operator-oauth-client" if cr.Spec.AuthProperties != nil { + // Mount Auth properties if specified (on Openshift) + mounts = append(mounts, corev1.VolumeMount{ + Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, + MountPath: authPropertiesPath, + SubPath: "OpenShiftAuthManager.properties", + ReadOnly: true, + }) OAuthClusterRoleName = cr.Spec.AuthProperties.CluserRoleName } @@ -646,67 +703,8 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa Value: OAuthClusterRoleName, }, } - envs = append(envs, openshiftEnvs...) } - envsFrom := []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Name + "-jmx-auth", - }, - }, - }, - } - - mounts := []corev1.VolumeMount{ - { - Name: cr.Name, - MountPath: configPath, - SubPath: "config", - }, - { - Name: cr.Name, - MountPath: archivePath, - SubPath: "flightrecordings", - }, - { - Name: cr.Name, - MountPath: templatesPath, - SubPath: "templates", - }, - { - Name: cr.Name, - MountPath: clientlibPath, - SubPath: "clientlib", - }, - { - Name: cr.Name, - MountPath: probesPath, - SubPath: "probes", - }, - { - Name: cr.Name, - MountPath: "truststore", - SubPath: "truststore", - }, - { - // Mount the CA cert and user certificates in the expected /truststore location - Name: "cert-secrets", - MountPath: "/truststore/operator", - ReadOnly: true, - }, - } - - // Mount Auth properties if specified - if cr.Spec.AuthProperties != nil { - mounts = append(mounts, corev1.VolumeMount{ - Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, - MountPath: authPropertiesPath, - SubPath: "OpenShiftAuthManager.properties", - ReadOnly: true, - }) - } if !cr.Spec.Minimal { grafanaVars := []corev1.EnvVar{ diff --git a/internal/controllers/cryostat_controller_test.go b/internal/controllers/cryostat_controller_test.go index 72f0d0ef6..d3117931c 100644 --- a/internal/controllers/cryostat_controller_test.go +++ b/internal/controllers/cryostat_controller_test.go @@ -1436,8 +1436,8 @@ var _ = Describe("CryostatController", func() { JustBeforeEach(func() { t.reconcileCryostatFully() }) - It("Should add volumes and volumeMounts to deployment", func() { - t.checkDeploymentHasAuthProperties() + It("Should not add volumes and volumeMounts to deployment", func() { + t.checkDeploymentHasNoAuthProperties() }) }) }) @@ -2089,10 +2089,25 @@ func (t *cryostatTestInput) checkDeploymentHasAuthProperties() { volumeMounts := coreContainer.VolumeMounts expectedVolumeMounts := test.NewVolumeMountsWithAuthProperties(t.TLS) Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) + Expect(coreContainer.Env).To(ConsistOf(test.NewCoreEnvironmentVariables(t.minimal, t.TLS, t.externalTLS, t.controller.IsOpenShift, "", true))) +} - if t.controller.IsOpenShift { // Only check env vars if running on Openshift - Expect(coreContainer.Env).To(ConsistOf(test.NewCoreEnvironmentVariables(t.minimal, t.TLS, t.externalTLS, t.controller.IsOpenShift, "", true))) - } +func (t *cryostatTestInput) checkDeploymentHasNoAuthProperties() { + deployment := &appsv1.Deployment{} + err := t.Client.Get(context.Background(), types.NamespacedName{Name: "cryostat", Namespace: "default"}, deployment) + Expect(err).ToNot(HaveOccurred()) + + volumes := deployment.Spec.Template.Spec.Volumes + expectedVolumes := test.NewVolumes(t.minimal, t.TLS) + Expect(volumes).ToNot(ContainElements(test.NewAuthPropertiesVolume())) + Expect(volumes).To(ConsistOf(expectedVolumes)) + + coreContainer := deployment.Spec.Template.Spec.Containers[0] + + volumeMounts := coreContainer.VolumeMounts + expectedVolumeMounts := test.NewCoreVolumeMounts(t.TLS) + Expect(volumeMounts).ToNot(ContainElement(test.NewAuthPropertiesVolumeMount())) + Expect(volumeMounts).To(ConsistOf(expectedVolumeMounts)) } func checkCoreContainer(container *corev1.Container, minimal bool, tls bool, externalTLS bool, diff --git a/internal/test/resources.go b/internal/test/resources.go index 0412dee5f..ac498cf99 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1591,13 +1591,16 @@ func NewVolumeMountsWithTemplates(tls bool) []corev1.VolumeMount { } func NewVolumeMountsWithAuthProperties(tls bool) []corev1.VolumeMount { - return append(NewCoreVolumeMounts(tls), - corev1.VolumeMount{ - Name: "auth-properties-authConfigMapName", - ReadOnly: true, - MountPath: "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties", - SubPath: "OpenShiftAuthManager.properties", - }) + return append(NewCoreVolumeMounts(tls), NewAuthPropertiesVolumeMount()) +} + +func NewAuthPropertiesVolumeMount() corev1.VolumeMount { + return corev1.VolumeMount{ + Name: "auth-properties-authConfigMapName", + ReadOnly: true, + MountPath: "/app/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties", + SubPath: "OpenShiftAuthManager.properties", + } } func NewCoreLivenessProbe(tls bool) *corev1.Probe { @@ -1806,26 +1809,28 @@ func NewVolumesWithTemplates(tls bool) []corev1.Volume { } func NewVolumeWithAuthProperties(tls bool) []corev1.Volume { + return append(NewVolumes(false, tls), NewAuthPropertiesVolume()) +} + +func NewAuthPropertiesVolume() corev1.Volume { readOnlyMode := int32(0440) - return append(NewVolumes(false, tls), - corev1.Volume{ - Name: "auth-properties-authConfigMapName", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "authConfigMapName", - }, - Items: []corev1.KeyToPath{ - { - Key: "auth.properties", - Path: "OpenShiftAuthManager.properties", - Mode: &readOnlyMode, - }, + return corev1.Volume{ + Name: "auth-properties-authConfigMapName", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "authConfigMapName", + }, + Items: []corev1.KeyToPath{ + { + Key: "auth.properties", + Path: "OpenShiftAuthManager.properties", + Mode: &readOnlyMode, }, }, }, }, - ) + } } func newVolumes(minimal bool, tls bool, certProjections []corev1.VolumeProjection) []corev1.Volume { From 876a2b9aac80f6a15dc932b5967938b3aafb8440 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 24 Aug 2022 13:19:35 -0400 Subject: [PATCH 27/32] docs(config): update docs on custom auth properties --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 18b60e7c9..9f3c60428 100644 --- a/docs/config.md +++ b/docs/config.md @@ -288,7 +288,7 @@ data: CREDENTIALS=cryostats.operator.cryostat.io ``` -If custom mapping is specified, the user is also required to create a ClusterRole that defines access rules for mapped Kubernetes resources. +If custom mapping is specified, a ClusterRole must be defined and should contain permissions for all Kubernetes objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth The property `.spec.authProperties` can then be set to configure Cryostat to use this mapping instead of the default ones. ```yaml From f59045b984b8bf7877e57e9e6128fdc1a92d6fec Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 24 Aug 2022 17:59:08 -0400 Subject: [PATCH 28/32] fix(apis): add xdescriptor for auth filename, fix auth spec field typo, edit auth spec field displayname --- api/v1beta1/cryostat_types.go | 7 ++++--- .../cryostat-operator.clusterserviceversion.yaml | 9 +++++++-- .../bases/cryostat-operator.clusterserviceversion.yaml | 9 +++++++-- .../common/resource_definitions/resource_definitions.go | 2 +- internal/test/resources.go | 6 +++--- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/api/v1beta1/cryostat_types.go b/api/v1beta1/cryostat_types.go index 958fe80e6..cd98313f6 100644 --- a/api/v1beta1/cryostat_types.go +++ b/api/v1beta1/cryostat_types.go @@ -412,11 +412,12 @@ type AuthorizationProperties struct { // Name of the ClusterRole to use when Cryostat requests a role-scoped OAuth token. // This ClusterRole should contain permissions for all Kubernetes objects listed in custom permission mapping. // More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth - // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ClusterRole"} - CluserRoleName string `json:"clusterRoleName"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="ClusterRole Name",xDescriptors={"urn:alm:descriptor:io.kubernetes:ClusterRole"} + ClusterRoleName string `json:"clusterRoleName"` // Name of config map in the local namespace. - // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:ConfigMap"} + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="ConfigMap Name",xDescriptors={"urn:alm:descriptor:io.kubernetes:ConfigMap"} ConfigMapName string `json:"configMapName"` // Filename within config map containing the resource mapping. + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} Filename string `json:"filename"` } diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index 68d2da877..5814676d8 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -128,15 +128,20 @@ spec: - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped OAuth token. This ClusterRole should contain permissions for all Kubernetes objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: Cluser Role Name + displayName: ClusterRole Name path: authProperties.clusterRoleName x-descriptors: - urn:alm:descriptor:io.kubernetes:ClusterRole - description: Name of config map in the local namespace. - displayName: Config Map Name + displayName: ConfigMap Name path: authProperties.configMapName x-descriptors: - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Filename within config map containing the resource mapping. + displayName: Filename + path: authProperties.filename + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text - description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. displayName: Enable cert-manager Integration diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index 563f4a238..95487ac50 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -116,15 +116,20 @@ spec: - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped OAuth token. This ClusterRole should contain permissions for all Kubernetes objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: Cluser Role Name + displayName: ClusterRole Name path: authProperties.clusterRoleName x-descriptors: - urn:alm:descriptor:io.kubernetes:ClusterRole - description: Name of config map in the local namespace. - displayName: Config Map Name + displayName: ConfigMap Name path: authProperties.configMapName x-descriptors: - urn:alm:descriptor:io.kubernetes:ConfigMap + - description: Filename within config map containing the resource mapping. + displayName: Filename + path: authProperties.filename + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text - description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. displayName: Enable cert-manager Integration diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index bd90d51f9..fc43ed73d 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -681,7 +681,7 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa SubPath: "OpenShiftAuthManager.properties", ReadOnly: true, }) - OAuthClusterRoleName = cr.Spec.AuthProperties.CluserRoleName + OAuthClusterRoleName = cr.Spec.AuthProperties.ClusterRoleName } // Force OpenShift platform strategy diff --git a/internal/test/resources.go b/internal/test/resources.go index ac498cf99..fe7fc70a4 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -372,9 +372,9 @@ func NewCryostatWithResources() *operatorv1beta1.Cryostat { func NewCryostatWithAuthProperties() *operatorv1beta1.Cryostat { cr := NewCryostat() cr.Spec.AuthProperties = &operatorv1beta1.AuthorizationProperties{ - ConfigMapName: "authConfigMapName", - Filename: "auth.properties", - CluserRoleName: "oauth-cluster-role", + ConfigMapName: "authConfigMapName", + Filename: "auth.properties", + ClusterRoleName: "oauth-cluster-role", } return cr } From 0a803f74e27059f1fd98a02c57f0e75dc413079f Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 25 Aug 2022 13:40:36 -0400 Subject: [PATCH 29/32] fix(oauth): use default oauth-client-role as base --- .../resource_definitions.go | 31 ++++++++++--------- internal/test/resources.go | 15 +++++---- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index fc43ed73d..e5b9383a8 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -96,6 +96,7 @@ const ( datasourceContainerPort int32 = 8080 reportsContainerPort int32 = 10000 loopbackAddress string = "127.0.0.1" + operatorNamePrefix string = "cryostat-operator-" ) func NewPersistentVolumeClaimForCR(cr *operatorv1beta1.Cryostat) *corev1.PersistentVolumeClaim { @@ -672,18 +673,6 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa } if openshift { - OAuthClusterRoleName := "cryostat-operator-oauth-client" - if cr.Spec.AuthProperties != nil { - // Mount Auth properties if specified (on Openshift) - mounts = append(mounts, corev1.VolumeMount{ - Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, - MountPath: authPropertiesPath, - SubPath: "OpenShiftAuthManager.properties", - ReadOnly: true, - }) - OAuthClusterRoleName = cr.Spec.AuthProperties.ClusterRoleName - } - // Force OpenShift platform strategy openshiftEnvs := []corev1.EnvVar{ { @@ -699,11 +688,25 @@ func NewCoreContainer(cr *operatorv1beta1.Cryostat, specs *ServiceSpecs, imageTa Value: cr.Name, }, { - Name: "CRYOSTAT_OAUTH_ROLE", - Value: OAuthClusterRoleName, + Name: "CRYOSTAT_BASE_OAUTH_ROLE", + Value: operatorNamePrefix + "oauth-client", }, } envs = append(envs, openshiftEnvs...) + + if cr.Spec.AuthProperties != nil { + // Mount Auth properties if specified (on Openshift) + mounts = append(mounts, corev1.VolumeMount{ + Name: "auth-properties-" + cr.Spec.AuthProperties.ConfigMapName, + MountPath: authPropertiesPath, + SubPath: "OpenShiftAuthManager.properties", + ReadOnly: true, + }) + envs = append(envs, corev1.EnvVar{ + Name: "CRYOSTAT_CUSTOM_OAUTH_ROLE", + Value: cr.Spec.AuthProperties.ClusterRoleName, + }) + } } if !cr.Spec.Minimal { diff --git a/internal/test/resources.go b/internal/test/resources.go index fe7fc70a4..3d528812f 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -1320,10 +1320,6 @@ func NewCoreEnvironmentVariables(minimal bool, tls bool, externalTLS bool, opens }) } if openshift { - OAuthClusterRoleName := "cryostat-operator-oauth-client" - if authProps { - OAuthClusterRoleName = "oauth-cluster-role" - } envs = append(envs, corev1.EnvVar{ Name: "CRYOSTAT_PLATFORM", @@ -1338,9 +1334,16 @@ func NewCoreEnvironmentVariables(minimal bool, tls bool, externalTLS bool, opens Value: "cryostat", }, corev1.EnvVar{ - Name: "CRYOSTAT_OAUTH_ROLE", - Value: OAuthClusterRoleName, + Name: "CRYOSTAT_BASE_OAUTH_ROLE", + Value: "cryostat-operator-oauth-client", + }) + + if authProps { + envs = append(envs, corev1.EnvVar{ + Name: "CRYOSTAT_CUSTOM_OAUTH_ROLE", + Value: "oauth-cluster-role", }) + } } if reportsUrl != "" { envs = append(envs, From 6468bc9f83d46f9541a8b5683ab294f3b1591a45 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 25 Aug 2022 14:32:43 -0400 Subject: [PATCH 30/32] fix(rbac): update default oauth-client cluster role --- config/rbac/oauth_client.yaml | 45 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/config/rbac/oauth_client.yaml b/config/rbac/oauth_client.yaml index 8d42bf2e0..69164ee3e 100644 --- a/config/rbac/oauth_client.yaml +++ b/config/rbac/oauth_client.yaml @@ -20,30 +20,29 @@ rules: - pods - pods/exec - services - - secrets verbs: - create - get - delete -# - apiGroups: -# - "" -# resources: -# - replicationcontrollers -# - endpoints -# verbs: -# - get -# - apiGroups: -# - apps -# resources: -# - deployments -# verbs: -# - create -# - get -# - apiGroups: -# - apps -# resources: -# - daemonsets -# - replicasets -# - statefulsets -# verbs: -# - get +- apiGroups: + - "" + resources: + - replicationcontrollers + - endpoints + verbs: + - get +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - get +- apiGroups: + - apps + resources: + - daemonsets + - replicasets + - statefulsets + verbs: + - get From f5a91df7ff3b28dff6d2c4dbed6be13f1725ddba Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 25 Aug 2022 14:46:19 -0400 Subject: [PATCH 31/32] docs(config): mention escalation issue if using secret in permission mapping --- docs/config.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 9f3c60428..ebb576399 100644 --- a/docs/config.md +++ b/docs/config.md @@ -288,7 +288,10 @@ data: CREDENTIALS=cryostats.operator.cryostat.io ``` -If custom mapping is specified, a ClusterRole must be defined and should contain permissions for all Kubernetes objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth +If custom mapping is specified, a ClusterRole must be defined and should contain permissions for all Kubernetes objects listed in custom permission mapping. This ClusterRole will give additional rules on top of [default rules](placeholder). + + +**Note**: Using [`Secret`](https://kubernetes.io/docs/concepts/configuration/secret/) in mapping can fail with access denied under [security protection](https://kubernetes.io/docs/concepts/configuration/secret/#information-security-for-secrets) against escalations. Find more details about this issue [here](https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth). The property `.spec.authProperties` can then be set to configure Cryostat to use this mapping instead of the default ones. ```yaml From 270ce84d133fdd7eef6980e22ca1abff20ba9786 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 25 Aug 2022 20:12:40 -0400 Subject: [PATCH 32/32] fix(rbac): update base oauth-client role --- ...c.authorization.k8s.io_v1_clusterrole.yaml | 27 +++++++++++++++++-- config/rbac/oauth_client.yaml | 4 ++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/bundle/manifests/cryostat-operator-oauth-client_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/cryostat-operator-oauth-client_rbac.authorization.k8s.io_v1_clusterrole.yaml index 8b6cfe496..4cd821915 100644 --- a/bundle/manifests/cryostat-operator-oauth-client_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/bundle/manifests/cryostat-operator-oauth-client_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -10,6 +10,7 @@ rules: - cryostats verbs: - create + - patch - delete - get - apiGroups: @@ -18,8 +19,30 @@ rules: - pods - pods/exec - services - - secrets verbs: - create - - get + - patch - delete + - get +- apiGroups: + - "" + resources: + - replicationcontrollers + - endpoints + verbs: + - get +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - get +- apiGroups: + - apps + resources: + - daemonsets + - replicasets + - statefulsets + verbs: + - get diff --git a/config/rbac/oauth_client.yaml b/config/rbac/oauth_client.yaml index 69164ee3e..d8c6693c8 100644 --- a/config/rbac/oauth_client.yaml +++ b/config/rbac/oauth_client.yaml @@ -12,6 +12,7 @@ rules: - cryostats verbs: - create + - patch - delete - get - apiGroups: @@ -22,8 +23,9 @@ rules: - services verbs: - create - - get + - patch - delete + - get - apiGroups: - "" resources: