Skip to content

Commit

Permalink
feat(auth): add configuration for htpasswd basic auth (#802)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewazores committed Apr 29, 2024
1 parent a26ff9c commit d455719
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 5 deletions.
23 changes: 23 additions & 0 deletions api/v1beta2/cryostat_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ type CryostatSpec struct {
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
Resources *ResourceConfigList `json:"resources,omitempty"`
// Additional configuration options for the authorization proxy.
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Options",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"}
AuthorizationOptions *AuthorizationOptions `json:"authorizationOptions,omitempty"`
// Override default authorization properties for Cryostat on OpenShift.
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"}
Expand Down Expand Up @@ -481,6 +485,25 @@ type TemplateConfigMap struct {
Filename string `json:"filename"`
}

// Authorization options provide additional configurations for the auth proxy.
type AuthorizationOptions struct {
// Reference to a secret and file name containing the Basic authentication htpasswd file
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"}
BasicAuth *SecretFile `json:"basicAuth,omitempty"`
}

type SecretFile struct {
// Name of the secret to reference.
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"}
SecretName *string `json:"secretName,omitempty"`
// Name of the file within the secret.
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"}
Filename *string `json:"filename,omitempty"`
}

// Authorization properties provide custom permission mapping between Cryostat resources to Kubernetes resources.
// If the mapping is updated, Cryostat must be manually restarted.
type AuthorizationProperties struct {
Expand Down
50 changes: 50 additions & 0 deletions api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 22 additions & 1 deletion bundle/manifests/cryostat-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ metadata:
capabilities: Seamless Upgrades
categories: Monitoring, Developer Tools
containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev
createdAt: "2024-04-26T21:39:27Z"
createdAt: "2024-04-26T21:51:07Z"
description: JVM monitoring and profiling tool
operatorframework.io/initialization-resource: |-
{
Expand Down Expand Up @@ -553,6 +553,27 @@ spec:
path: authProperties.filename
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Additional configuration options for the authorization proxy.
displayName: Authorization Options
path: authorizationOptions
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: Reference to a secret and file name containing the Basic authentication
htpasswd file
displayName: Basic Auth
path: authorizationOptions.basicAuth
x-descriptors:
- urn:alm:descriptor:io.kubernetes:Secret
- description: Name of the file within the secret.
displayName: Filename
path: authorizationOptions.basicAuth.filename
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Name of the secret to reference.
displayName: Secret Name
path: authorizationOptions.basicAuth.secretName
x-descriptors:
- urn:alm:descriptor:io.kubernetes:Secret
- description: List of Flight Recorder Event Templates to preconfigure in Cryostat.
displayName: Event Templates
path: eventTemplates
Expand Down
16 changes: 16 additions & 0 deletions bundle/manifests/operator.cryostat.io_cryostats.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5150,6 +5150,22 @@ spec:
- configMapName
- filename
type: object
authorizationOptions:
description: Additional configuration options for the authorization
proxy.
properties:
basicAuth:
description: Reference to a secret and file name containing the
Basic authentication htpasswd file
properties:
filename:
description: Name of the file within the secret.
type: string
secretName:
description: Name of the secret to reference.
type: string
type: object
type: object
enableCertManager:
description: Use cert-manager to secure in-cluster communication between
Cryostat components. Requires cert-manager to be installed.
Expand Down
16 changes: 16 additions & 0 deletions config/crd/bases/operator.cryostat.io_cryostats.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5140,6 +5140,22 @@ spec:
- configMapName
- filename
type: object
authorizationOptions:
description: Additional configuration options for the authorization
proxy.
properties:
basicAuth:
description: Reference to a secret and file name containing the
Basic authentication htpasswd file
properties:
filename:
description: Name of the file within the secret.
type: string
secretName:
description: Name of the secret to reference.
type: string
type: object
type: object
enableCertManager:
description: Use cert-manager to secure in-cluster communication between
Cryostat components. Requires cert-manager to be installed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,27 @@ spec:
path: authProperties.filename
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Additional configuration options for the authorization proxy.
displayName: Authorization Options
path: authorizationOptions
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- description: Reference to a secret and file name containing the Basic authentication
htpasswd file
displayName: Basic Auth
path: authorizationOptions.basicAuth
x-descriptors:
- urn:alm:descriptor:io.kubernetes:Secret
- description: Name of the file within the secret.
displayName: Filename
path: authorizationOptions.basicAuth.filename
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- description: Name of the secret to reference.
displayName: Secret Name
path: authorizationOptions.basicAuth.secretName
x-descriptors:
- urn:alm:descriptor:io.kubernetes:Secret
- description: List of Flight Recorder Event Templates to preconfigure in Cryostat.
displayName: Event Templates
path: eventTemplates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type TLSConfig struct {

const (
defaultAuthProxyCpuRequest string = "50m"
defaultAuthProxyMemoryRequest string = "100Mi"
defaultAuthProxyMemoryRequest string = "120Mi"
defaultCoreCpuRequest string = "500m"
defaultCoreMemoryRequest string = "256Mi"
defaultJfrDatasourceCpuRequest string = "200m"
Expand Down Expand Up @@ -339,6 +339,19 @@ func NewPodForCR(cr *model.CryostatInstance, specs *ServiceSpecs, imageTags *Ima
}
volumes = append(volumes, certVolume)

if isBasicAuthEnabled(cr) {
volumes = append(volumes,
corev1.Volume{
Name: "auth-proxy-htpasswd",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: *cr.Spec.AuthorizationOptions.BasicAuth.SecretName,
},
},
},
)
}

// Add any EventTemplates as volumes
for _, template := range cr.Spec.EventTemplates {
eventTemplateVolume := corev1.Volume{
Expand Down Expand Up @@ -618,9 +631,7 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp
},
}

basicAuthEnabled := false
args := []string{
fmt.Sprintf("--skip-provider-button=%t", !basicAuthEnabled),
fmt.Sprintf("--upstream=http://localhost:%d/", constants.CryostatHTTPContainerPort),
fmt.Sprintf("--upstream=http://localhost:%d/grafana/", constants.GrafanaContainerPort),
fmt.Sprintf("--upstream=http://localhost:%d/storage/", constants.StoragePort),
Expand All @@ -639,6 +650,22 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp
"--bypass-auth-for=^/health",
"--proxy-prefix=/oauth2",
}

volumeMounts := []corev1.VolumeMount{}
if isBasicAuthEnabled(cr) {
mountPath := fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s", *cr.Spec.AuthorizationOptions.BasicAuth.SecretName)
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: "auth-proxy-htpasswd",
MountPath: mountPath,
ReadOnly: true,
})
args = append(args, fmt.Sprintf("--htpasswd-file=%s/%s", mountPath, *cr.Spec.AuthorizationOptions.BasicAuth.Filename))
}

args = append(args,
fmt.Sprintf("--skip-provider-button=%t", !isBasicAuthEnabled(cr)),
)

// if tls != nil {
// "--https-address=:8443",
// "--tls-cert=/etc/tls/private/tls.crt",
Expand All @@ -651,7 +678,7 @@ func NewOpenShiftAuthProxyContainer(cr *model.CryostatInstance, specs *ServiceSp
Name: cr.Name + "-auth-proxy",
Image: imageTag,
ImagePullPolicy: getPullPolicy(imageTag),
// VolumeMounts: mounts,
VolumeMounts: volumeMounts,
Ports: []corev1.ContainerPort{
{
ContainerPort: constants.AuthProxyHttpContainerPort,
Expand Down Expand Up @@ -1498,7 +1525,10 @@ func newVolumeForCR(cr *model.CryostatInstance) []corev1.Volume {

func useEmptyDir(cr *model.CryostatInstance) bool {
return cr.Spec.StorageOptions != nil && cr.Spec.StorageOptions.EmptyDir != nil && cr.Spec.StorageOptions.EmptyDir.Enabled
}

func isBasicAuthEnabled(cr *model.CryostatInstance) bool {
return cr.Spec.AuthorizationOptions != nil && cr.Spec.AuthorizationOptions.BasicAuth != nil && cr.Spec.AuthorizationOptions.BasicAuth.SecretName != nil && cr.Spec.AuthorizationOptions.BasicAuth.Filename != nil
}

func checkResourceRequestWithLimit(requests, limits corev1.ResourceList) {
Expand Down

0 comments on commit d455719

Please sign in to comment.