diff --git a/README.md b/README.md index acd009cf7..e2f29b6d8 100644 --- a/README.md +++ b/README.md @@ -31,14 +31,6 @@ at the URL provided by: ``` kubectl get cryostat -o jsonpath='{$.items[0].status.applicationUrl}' ``` -The Grafana credentials can be obtained with: -```shell -CRYOSTAT_NAME=$(kubectl get cryostat -o jsonpath='{$.items[0].metadata.name}') -# Username -kubectl get secret ${CRYOSTAT_NAME}-grafana-basic -o jsonpath='{$.data.GF_SECURITY_ADMIN_USER}' | base64 -d -# Password -kubectl get secret ${CRYOSTAT_NAME}-grafana-basic -o jsonpath='{$.data.GF_SECURITY_ADMIN_PASSWORD}' | base64 -d -``` The JMX authentication credentials for Cryostat itself can be obtained with: ```shell CRYOSTAT_NAME=$(kubectl get cryostat -o jsonpath='{$.items[0].metadata.name}') diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index de2b74a35..301ca0b4f 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -49,20 +49,18 @@ func convertSpecTo(src *CryostatSpec, dst *operatorv1beta2.CryostatSpec) { dst.ServiceOptions = convertServiceOptionsTo(src.ServiceOptions) dst.NetworkOptions = convertNetworkOptionsTo(src.NetworkOptions) dst.ReportOptions = convertReportOptionsTo(src.ReportOptions) - dst.JmxCacheOptions = convertJmxCacheOptionsTo(src.JmxCacheOptions) + dst.TargetConnectionCacheOptions = convertJmxCacheOptionsTo(src.JmxCacheOptions) dst.Resources = convertResourceOptionsTo(src.Resources) - dst.AuthProperties = convertAuthPropertiesTo(src.AuthProperties) dst.SecurityOptions = convertSecurityOptionsTo(src.SecurityOptions) dst.SchedulingOptions = convertSchedulingOptionsTo(src.SchedulingOptions) dst.TargetDiscoveryOptions = convertTargetDiscoveryTo(src.TargetDiscoveryOptions) - dst.JmxCredentialsDatabaseOptions = convertDatabaseOptionsTo(src.JmxCredentialsDatabaseOptions) + dst.DatabaseOptions = convertDatabaseOptionsTo(src.JmxCredentialsDatabaseOptions) dst.OperandMetadata = convertOperandMetadataTo(src.OperandMetadata) } func convertStatusTo(src *CryostatStatus, dst *operatorv1beta2.CryostatStatus) { dst.ApplicationURL = src.ApplicationURL dst.Conditions = src.Conditions - dst.GrafanaSecret = src.GrafanaSecret } func convertCertSecretsTo(srcCerts []CertificateSecret) []operatorv1beta2.CertificateSecret { @@ -214,10 +212,10 @@ func convertSchedulingOptionsTo(srcOpts *SchedulingConfiguration) *operatorv1bet return dstOpts } -func convertJmxCacheOptionsTo(srcOpts *JmxCacheOptions) *operatorv1beta2.JmxCacheOptions { - var dstOpts *operatorv1beta2.JmxCacheOptions +func convertJmxCacheOptionsTo(srcOpts *JmxCacheOptions) *operatorv1beta2.TargetConnectionCacheOptions { + var dstOpts *operatorv1beta2.TargetConnectionCacheOptions if srcOpts != nil { - dstOpts = &operatorv1beta2.JmxCacheOptions{ + dstOpts = &operatorv1beta2.TargetConnectionCacheOptions{ TargetCacheSize: srcOpts.TargetCacheSize, TargetCacheTTL: srcOpts.TargetCacheTTL, } @@ -237,18 +235,6 @@ func convertResourceOptionsTo(srcOpts *ResourceConfigList) *operatorv1beta2.Reso return dstOpts } -func convertAuthPropertiesTo(srcProps *AuthorizationProperties) *operatorv1beta2.AuthorizationProperties { - var dstProps *operatorv1beta2.AuthorizationProperties - if srcProps != nil { - dstProps = &operatorv1beta2.AuthorizationProperties{ - ClusterRoleName: srcProps.ClusterRoleName, - ConfigMapName: srcProps.ConfigMapName, - Filename: srcProps.Filename, - } - } - return dstProps -} - func convertSecurityOptionsTo(srcOpts *SecurityOptions) *operatorv1beta2.SecurityOptions { var dstOpts *operatorv1beta2.SecurityOptions if srcOpts != nil { @@ -276,11 +262,11 @@ func convertTargetDiscoveryTo(srcOpts *TargetDiscoveryOptions) *operatorv1beta2. return dstOpts } -func convertDatabaseOptionsTo(srcOpts *JmxCredentialsDatabaseOptions) *operatorv1beta2.JmxCredentialsDatabaseOptions { - var dstOpts *operatorv1beta2.JmxCredentialsDatabaseOptions +func convertDatabaseOptionsTo(srcOpts *JmxCredentialsDatabaseOptions) *operatorv1beta2.DatabaseOptions { + var dstOpts *operatorv1beta2.DatabaseOptions if srcOpts != nil { - dstOpts = &operatorv1beta2.JmxCredentialsDatabaseOptions{ - DatabaseSecretName: srcOpts.DatabaseSecretName, + dstOpts = &operatorv1beta2.DatabaseOptions{ + SecretName: srcOpts.DatabaseSecretName, } } return dstOpts @@ -332,20 +318,18 @@ func convertSpecFrom(src *operatorv1beta2.CryostatSpec, dst *CryostatSpec) { dst.ServiceOptions = convertServiceOptionsFrom(src.ServiceOptions) dst.NetworkOptions = convertNetworkOptionsFrom(src.NetworkOptions) dst.ReportOptions = convertReportOptionsFrom(src.ReportOptions) - dst.JmxCacheOptions = convertJmxCacheOptionsFrom(src.JmxCacheOptions) + dst.JmxCacheOptions = convertJmxCacheOptionsFrom(src.TargetConnectionCacheOptions) dst.Resources = convertResourceOptionsFrom(src.Resources) - dst.AuthProperties = convertAuthPropertiesFrom(src.AuthProperties) dst.SecurityOptions = convertSecurityOptionsFrom(src.SecurityOptions) dst.SchedulingOptions = convertSchedulingOptionsFrom(src.SchedulingOptions) dst.TargetDiscoveryOptions = convertTargetDiscoveryFrom(src.TargetDiscoveryOptions) - dst.JmxCredentialsDatabaseOptions = convertDatabaseOptionsFrom(src.JmxCredentialsDatabaseOptions) + dst.JmxCredentialsDatabaseOptions = convertDatabaseOptionsFrom(src.DatabaseOptions) dst.OperandMetadata = convertOperandMetadataFrom(src.OperandMetadata) } func convertStatusFrom(src *operatorv1beta2.CryostatStatus, dst *CryostatStatus) { dst.ApplicationURL = src.ApplicationURL dst.Conditions = src.Conditions - dst.GrafanaSecret = src.GrafanaSecret } func convertCertSecretsFrom(srcCerts []operatorv1beta2.CertificateSecret) []CertificateSecret { @@ -497,7 +481,7 @@ func convertSchedulingOptionsFrom(srcOpts *operatorv1beta2.SchedulingConfigurati return dstOpts } -func convertJmxCacheOptionsFrom(srcOpts *operatorv1beta2.JmxCacheOptions) *JmxCacheOptions { +func convertJmxCacheOptionsFrom(srcOpts *operatorv1beta2.TargetConnectionCacheOptions) *JmxCacheOptions { var dstOpts *JmxCacheOptions if srcOpts != nil { dstOpts = &JmxCacheOptions{ @@ -520,18 +504,6 @@ func convertResourceOptionsFrom(srcOpts *operatorv1beta2.ResourceConfigList) *Re return dstOpts } -func convertAuthPropertiesFrom(srcProps *operatorv1beta2.AuthorizationProperties) *AuthorizationProperties { - var dstProps *AuthorizationProperties - if srcProps != nil { - dstProps = &AuthorizationProperties{ - ClusterRoleName: srcProps.ClusterRoleName, - ConfigMapName: srcProps.ConfigMapName, - Filename: srcProps.Filename, - } - } - return dstProps -} - func convertSecurityOptionsFrom(srcOpts *operatorv1beta2.SecurityOptions) *SecurityOptions { var dstOpts *SecurityOptions if srcOpts != nil { @@ -559,11 +531,11 @@ func convertTargetDiscoveryFrom(srcOpts *operatorv1beta2.TargetDiscoveryOptions) return dstOpts } -func convertDatabaseOptionsFrom(srcOpts *operatorv1beta2.JmxCredentialsDatabaseOptions) *JmxCredentialsDatabaseOptions { +func convertDatabaseOptionsFrom(srcOpts *operatorv1beta2.DatabaseOptions) *JmxCredentialsDatabaseOptions { var dstOpts *JmxCredentialsDatabaseOptions if srcOpts != nil { dstOpts = &JmxCredentialsDatabaseOptions{ - DatabaseSecretName: srcOpts.DatabaseSecretName, + DatabaseSecretName: srcOpts.SecretName, } } return dstOpts diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index f66ed2b0d..1655ef883 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -45,11 +45,11 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,order=3,displayName="Enable cert-manager Integration",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} EnableCertManager *bool `json:"enableCertManager"` - // Options to customize the storage for Flight Recordings and Templates. + // Options to customize the storage provisioned for the database and object storage. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec StorageOptions *StorageConfiguration `json:"storageOptions,omitempty"` - // Options to customize the services created for the Cryostat application and Grafana dashboard. + // Options to customize the services created for the Cryostat application. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec ServiceOptions *ServiceConfigList `json:"serviceOptions,omitempty"` @@ -62,10 +62,10 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec ReportOptions *ReportConfiguration `json:"reportOptions,omitempty"` - // Options to customize the JMX target connections cache for the Cryostat application. + // Options to customize the target connections cache for the Cryostat application. // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="JMX Connections Cache Options" - JmxCacheOptions *JmxCacheOptions `json:"jmxCacheOptions,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Target Connection Cache Options" + TargetConnectionCacheOptions *TargetConnectionCacheOptions `json:"targetConnectionCacheOptions,omitempty"` // Resource requirements for the Cryostat deployment. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -74,10 +74,6 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Options",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} AuthorizationOptions *AuthorizationOptions `json:"authorizationOptions,omitempty"` - // Override default authorization properties for Cryostat on OpenShift. - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Authorization Properties",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} - AuthProperties *AuthorizationProperties `json:"authProperties,omitempty"` // Options to configure the Security Contexts for the Cryostat application. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} @@ -90,10 +86,10 @@ type CryostatSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec TargetDiscoveryOptions *TargetDiscoveryOptions `json:"targetDiscoveryOptions,omitempty"` - // Options to configure the Cryostat application's credentials database. + // Options to configure the Cryostat application's database. // +optional - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Credentials Database Options" - JmxCredentialsDatabaseOptions *JmxCredentialsDatabaseOptions `json:"jmxCredentialsDatabaseOptions,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Database Options" + DatabaseOptions *DatabaseOptions `json:"databaseOptions,omitempty"` // Options to configure the Cryostat deployments and pods metadata // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Operand metadata" @@ -127,7 +123,7 @@ type ResourceConfigList struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} AuthProxyResources corev1.ResourceRequirements `json:"authProxyResources,omitempty"` - // Resource requirements for the Cryostat application. If specifying a memory limit, at least 768MiB is recommended. + // Resource requirements for the Cryostat application. If specifying a memory limit, at least 384MiB is recommended. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} CoreResources corev1.ResourceRequirements `json:"coreResources,omitempty"` @@ -139,6 +135,14 @@ type ResourceConfigList struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} GrafanaResources corev1.ResourceRequirements `json:"grafanaResources,omitempty"` + // Resource requirements for the database container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + DatabaseResources corev1.ResourceRequirements `json:"databaseResources,omitempty"` + // Resource requirements for the object storage container. + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + ObjectStorageResources corev1.ResourceRequirements `json:"objectStorageResources,omitempty"` } // CryostatStatus defines the observed state of Cryostat. @@ -152,10 +156,6 @@ type CryostatStatus struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Cryostat Conditions",xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"} Conditions []metav1.Condition `json:"conditions,omitempty"` - // Name of the Secret containing the generated Grafana credentials. - // +optional - // +operator-sdk:csv:customresourcedefinitions:type=status,order=2,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} - GrafanaSecret string `json:"grafanaSecret,omitempty"` // Address of the deployed Cryostat web application. // +operator-sdk:csv:customresourcedefinitions:type=status,order=1,xDescriptors={"urn:alm:descriptor:org.w3:link"} ApplicationURL string `json:"applicationUrl"` @@ -405,15 +405,15 @@ type EmptyDirConfig struct { SizeLimit string `json:"sizeLimit,omitempty"` } -// JmxCacheConfig provides customization for the JMX target connections +// TargetConnectionCacheOptions provides customization for the target connections // cache for the Cryostat application. -type JmxCacheOptions struct { - // The maximum number of JMX connections to cache. Use `-1` for an unlimited cache size (TTL expiration only). Defaults to `-1`. +type TargetConnectionCacheOptions struct { + // The maximum number of target connections to cache. Use `-1` for an unlimited cache size (TTL expiration only). Defaults to `-1`. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} // +kubebuilder:validation:Minimum=-1 TargetCacheSize int32 `json:"targetCacheSize,omitempty"` - // The time to live (in seconds) for cached JMX connections. Defaults to `10`. + // The time to live (in seconds) for cached target connections. Defaults to `10`. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"} // +kubebuilder:validation:Minimum=1 @@ -432,7 +432,6 @@ type JmxCacheOptions struct { // to deploy the Cryostat application. // +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1},{Ingress,v1},{PersistentVolumeClaim,v1},{Secret,v1},{Service,v1},{Route,v1},{ConsoleLink,v1}} // +kubebuilder:printcolumn:name="Application URL",type=string,JSONPath=`.status.applicationUrl` -// +kubebuilder:printcolumn:name="Grafana Secret",type=string,JSONPath=`.status.grafanaSecret` type Cryostat struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -611,10 +610,12 @@ type TargetDiscoveryOptions struct { DiscoveryPortNumbers []int32 `json:"discoveryPortNumbers,omitempty"` } -// JmxCredentialsDatabaseOptions provides configuration options to the Cryostat application's credentials database. -type JmxCredentialsDatabaseOptions struct { - // Name of the secret containing the password to encrypt credentials database. +// DatabaseOptions provides configuration options to the Cryostat application's database. +type DatabaseOptions struct { + // Name of the secret containing database keys. This secret must contain a CONNECTION_KEY secret which is the + // database connection password, and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive data + // stored within the database, such as the target credentials keyring. // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"} - DatabaseSecretName *string `json:"databaseSecretName,omitempty"` + SecretName *string `json:"secretName,omitempty"` } diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 929146417..0fa1bd72c 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -247,9 +247,9 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { *out = new(ReportConfiguration) (*in).DeepCopyInto(*out) } - if in.JmxCacheOptions != nil { - in, out := &in.JmxCacheOptions, &out.JmxCacheOptions - *out = new(JmxCacheOptions) + if in.TargetConnectionCacheOptions != nil { + in, out := &in.TargetConnectionCacheOptions, &out.TargetConnectionCacheOptions + *out = new(TargetConnectionCacheOptions) **out = **in } if in.Resources != nil { @@ -262,11 +262,6 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { *out = new(AuthorizationOptions) (*in).DeepCopyInto(*out) } - if in.AuthProperties != nil { - in, out := &in.AuthProperties, &out.AuthProperties - *out = new(AuthorizationProperties) - **out = **in - } if in.SecurityOptions != nil { in, out := &in.SecurityOptions, &out.SecurityOptions *out = new(SecurityOptions) @@ -282,9 +277,9 @@ func (in *CryostatSpec) DeepCopyInto(out *CryostatSpec) { *out = new(TargetDiscoveryOptions) (*in).DeepCopyInto(*out) } - if in.JmxCredentialsDatabaseOptions != nil { - in, out := &in.JmxCredentialsDatabaseOptions, &out.JmxCredentialsDatabaseOptions - *out = new(JmxCredentialsDatabaseOptions) + if in.DatabaseOptions != nil { + in, out := &in.DatabaseOptions, &out.DatabaseOptions + *out = new(DatabaseOptions) (*in).DeepCopyInto(*out) } if in.OperandMetadata != nil { @@ -332,72 +327,57 @@ func (in *CryostatStatus) DeepCopy() *CryostatStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EmptyDirConfig) DeepCopyInto(out *EmptyDirConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmptyDirConfig. -func (in *EmptyDirConfig) DeepCopy() *EmptyDirConfig { - if in == nil { - return nil - } - out := new(EmptyDirConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GrafanaServiceConfig) DeepCopyInto(out *GrafanaServiceConfig) { +func (in *DatabaseOptions) DeepCopyInto(out *DatabaseOptions) { *out = *in - if in.HTTPPort != nil { - in, out := &in.HTTPPort, &out.HTTPPort - *out = new(int32) + if in.SecretName != nil { + in, out := &in.SecretName, &out.SecretName + *out = new(string) **out = **in } - in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaServiceConfig. -func (in *GrafanaServiceConfig) DeepCopy() *GrafanaServiceConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseOptions. +func (in *DatabaseOptions) DeepCopy() *DatabaseOptions { if in == nil { return nil } - out := new(GrafanaServiceConfig) + out := new(DatabaseOptions) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JmxCacheOptions) DeepCopyInto(out *JmxCacheOptions) { +func (in *EmptyDirConfig) DeepCopyInto(out *EmptyDirConfig) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JmxCacheOptions. -func (in *JmxCacheOptions) DeepCopy() *JmxCacheOptions { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmptyDirConfig. +func (in *EmptyDirConfig) DeepCopy() *EmptyDirConfig { if in == nil { return nil } - out := new(JmxCacheOptions) + out := new(EmptyDirConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JmxCredentialsDatabaseOptions) DeepCopyInto(out *JmxCredentialsDatabaseOptions) { +func (in *GrafanaServiceConfig) DeepCopyInto(out *GrafanaServiceConfig) { *out = *in - if in.DatabaseSecretName != nil { - in, out := &in.DatabaseSecretName, &out.DatabaseSecretName - *out = new(string) + if in.HTTPPort != nil { + in, out := &in.HTTPPort, &out.HTTPPort + *out = new(int32) **out = **in } + in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JmxCredentialsDatabaseOptions. -func (in *JmxCredentialsDatabaseOptions) DeepCopy() *JmxCredentialsDatabaseOptions { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaServiceConfig. +func (in *GrafanaServiceConfig) DeepCopy() *GrafanaServiceConfig { if in == nil { return nil } - out := new(JmxCredentialsDatabaseOptions) + out := new(GrafanaServiceConfig) in.DeepCopyInto(out) return out } @@ -624,6 +604,8 @@ func (in *ResourceConfigList) DeepCopyInto(out *ResourceConfigList) { in.CoreResources.DeepCopyInto(&out.CoreResources) in.DataSourceResources.DeepCopyInto(&out.DataSourceResources) in.GrafanaResources.DeepCopyInto(&out.GrafanaResources) + in.DatabaseResources.DeepCopyInto(&out.DatabaseResources) + in.ObjectStorageResources.DeepCopyInto(&out.ObjectStorageResources) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceConfigList. @@ -863,6 +845,21 @@ func (in *StorageConfiguration) DeepCopy() *StorageConfiguration { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TargetConnectionCacheOptions) DeepCopyInto(out *TargetConnectionCacheOptions) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetConnectionCacheOptions. +func (in *TargetConnectionCacheOptions) DeepCopy() *TargetConnectionCacheOptions { + if in == nil { + return nil + } + out := new(TargetConnectionCacheOptions) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TargetDiscoveryOptions) DeepCopyInto(out *TargetDiscoveryOptions) { *out = *in diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index a7d07fe70..c05bf7536 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -53,7 +53,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:3.0.0-dev - createdAt: "2024-05-03T20:13:14Z" + createdAt: "2024-05-06T20:05:20Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { @@ -531,28 +531,6 @@ spec: path: enableCertManager x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Override default authorization properties for Cryostat on OpenShift. - displayName: Authorization Properties - path: authProperties - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped - OAuth token. This ClusterRole should contain permissions for all Kubernetes - objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: ClusterRole Name - path: authProperties.clusterRoleName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ClusterRole - - description: Name of config map in the local namespace. - displayName: ConfigMap Name - path: authProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Filename within config map containing the resource mapping. - displayName: Filename - path: authProperties.filename - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - description: Additional configuration options for the authorization proxy. displayName: Authorization Options path: authorizationOptions @@ -595,6 +573,17 @@ spec: path: authorizationOptions.openShiftSSO.disable x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Options to configure the Cryostat application's database. + displayName: Database Options + path: databaseOptions + - description: Name of the secret containing database keys. This secret must + contain a CONNECTION_KEY secret which is the database connection password, + and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive + data stored within the database, such as the target credentials keyring. + displayName: Secret Name + path: databaseOptions.secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. displayName: Event Templates path: eventTemplates @@ -603,31 +592,6 @@ spec: path: eventTemplates[0].configMapName x-descriptors: - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Options to customize the JMX target connections cache for the - Cryostat application. - displayName: JMX Connections Cache Options - path: jmxCacheOptions - - description: The maximum number of JMX connections to cache. Use `-1` for - an unlimited cache size (TTL expiration only). Defaults to `-1`. - displayName: Target Cache Size - path: jmxCacheOptions.targetCacheSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: The time to live (in seconds) for cached JMX connections. Defaults - to `10`. - displayName: Target Cache TTL - path: jmxCacheOptions.targetCacheTTL - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to configure the Cryostat application's credentials database. - displayName: Credentials Database Options - path: jmxCredentialsDatabaseOptions - - description: Name of the secret containing the password to encrypt credentials - database. - displayName: Database Secret Name - path: jmxCredentialsDatabaseOptions.databaseSecretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options @@ -749,7 +713,7 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Cryostat application. If specifying - a memory limit, at least 768MiB is recommended. + a memory limit, at least 384MiB is recommended. displayName: Core Resources path: resources.coreResources x-descriptors: @@ -759,11 +723,21 @@ spec: path: resources.dataSourceResources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the database container. + displayName: Database Resources + path: resources.databaseResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Grafana container. displayName: Grafana Resources path: resources.grafanaResources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the object storage container. + displayName: Object Storage Resources + path: resources.objectStorageResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Options to configure scheduling for the Cryostat deployment displayName: Scheduling Options path: schedulingOptions @@ -822,11 +796,11 @@ spec: - description: Security Context to apply to the storage container. displayName: Storage Security Context path: securityOptions.storageSecurityContext - - description: Options to customize the services created for the Cryostat application - and Grafana dashboard. + - description: Options to customize the services created for the Cryostat application. displayName: Service Options path: serviceOptions - - description: Options to customize the storage for Flight Recordings and Templates. + - description: Options to customize the storage provisioned for the database + and object storage. displayName: Storage Options path: storageOptions - description: Configuration for an EmptyDir to be created by the operator instead @@ -861,6 +835,22 @@ spec: has created the PVC, changes to this field have no effect. displayName: Spec path: storageOptions.pvc.spec + - description: Options to customize the target connections cache for the Cryostat + application. + displayName: Target Connection Cache Options + path: targetConnectionCacheOptions + - description: The maximum number of target connections to cache. Use `-1` for + an unlimited cache size (TTL expiration only). Defaults to `-1`. + displayName: Target Cache Size + path: targetConnectionCacheOptions.targetCacheSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: The time to live (in seconds) for cached target connections. + Defaults to `10`. + displayName: Target Cache TTL + path: targetConnectionCacheOptions.targetCacheTTL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number - description: Options to configure the Cryostat application's target discovery mechanisms. displayName: Target Discovery Options @@ -915,11 +905,6 @@ spec: path: applicationUrl x-descriptors: - urn:alm:descriptor:org.w3:link - - description: Name of the Secret containing the generated Grafana credentials. - displayName: Grafana Secret - path: grafanaSecret - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - description: List of namespaces that Cryostat has been configured and authorized to access and profile. displayName: Target Namespaces diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index 460244d0c..2104aa932 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -5101,9 +5101,6 @@ spec: - jsonPath: .status.applicationUrl name: Application URL type: string - - jsonPath: .status.grafanaSecret - name: Grafana Secret - type: string name: v1beta2 schema: openAPIV3Schema: @@ -5128,28 +5125,6 @@ spec: spec: description: CryostatSpec defines the desired state of Cryostat. properties: - authProperties: - description: Override default authorization properties for Cryostat - on OpenShift. - properties: - clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - type: string - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - clusterRoleName - - configMapName - - filename - type: object authorizationOptions: description: Additional configuration options for the authorization proxy. @@ -5224,6 +5199,17 @@ spec: type: boolean type: object type: object + databaseOptions: + description: Options to configure the Cryostat application's database. + properties: + secretName: + description: Name of the secret containing database keys. This + secret must contain a CONNECTION_KEY secret which is the database + connection password, and an ENCRYPTION_KEY secret which is the + key used to encrypt sensitive data stored within the database, + such as the target credentials keyring. + type: string + type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. @@ -5246,33 +5232,6 @@ spec: - filename type: object type: array - jmxCacheOptions: - description: Options to customize the JMX target connections cache - for the Cryostat application. - properties: - targetCacheSize: - description: The maximum number of JMX connections to cache. Use - `-1` for an unlimited cache size (TTL expiration only). Defaults - to `-1`. - format: int32 - minimum: -1 - type: integer - targetCacheTTL: - description: The time to live (in seconds) for cached JMX connections. - Defaults to `10`. - format: int32 - minimum: 1 - type: integer - type: object - jmxCredentialsDatabaseOptions: - description: Options to configure the Cryostat application's credentials - database. - properties: - databaseSecretName: - description: Name of the secret containing the password to encrypt - credentials database. - type: string - type: object networkOptions: description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. @@ -7379,7 +7338,7 @@ spec: type: object coreResources: description: Resource requirements for the Cryostat application. - If specifying a memory limit, at least 768MiB is recommended. + If specifying a memory limit, at least 384MiB is recommended. properties: claims: description: "Claims lists the names of resources, defined @@ -7476,6 +7435,55 @@ spec: Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + databaseResources: + description: Resource requirements for the database container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object grafanaResources: description: Resource requirements for the Grafana container. properties: @@ -7525,6 +7533,55 @@ spec: Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + objectStorageResources: + description: Resource requirements for the object storage container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object type: object schedulingOptions: description: Options to configure scheduling for the Cryostat deployment @@ -9621,7 +9678,7 @@ spec: type: object serviceOptions: description: Options to customize the services created for the Cryostat - application and Grafana dashboard. + application. properties: coreConfig: description: Specification for the service responsible for the @@ -9708,8 +9765,8 @@ spec: type: object type: object storageOptions: - description: Options to customize the storage for Flight Recordings - and Templates. + description: Options to customize the storage provisioned for the + database and object storage. properties: emptyDir: description: Configuration for an EmptyDir to be created by the @@ -9968,6 +10025,24 @@ spec: type: object type: object type: object + targetConnectionCacheOptions: + description: Options to customize the target connections cache for + the Cryostat application. + properties: + targetCacheSize: + description: The maximum number of target connections to cache. + Use `-1` for an unlimited cache size (TTL expiration only). + Defaults to `-1`. + format: int32 + minimum: -1 + type: integer + targetCacheTTL: + description: The time to live (in seconds) for cached target connections. + Defaults to `10`. + format: int32 + minimum: 1 + type: integer + type: object targetDiscoveryOptions: description: Options to configure the Cryostat application's target discovery mechanisms. @@ -10098,9 +10173,6 @@ spec: - type type: object type: array - grafanaSecret: - description: Name of the Secret containing the generated Grafana credentials. - type: string targetNamespaces: description: List of namespaces that Cryostat has been configured and authorized to access and profile. diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 4bb2140fc..fd1d66c0c 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -5091,9 +5091,6 @@ spec: - jsonPath: .status.applicationUrl name: Application URL type: string - - jsonPath: .status.grafanaSecret - name: Grafana Secret - type: string name: v1beta2 schema: openAPIV3Schema: @@ -5118,28 +5115,6 @@ spec: spec: description: CryostatSpec defines the desired state of Cryostat. properties: - authProperties: - description: Override default authorization properties for Cryostat - on OpenShift. - properties: - clusterRoleName: - description: 'Name of the ClusterRole to use when Cryostat requests - a role-scoped OAuth token. This ClusterRole should contain permissions - for all Kubernetes objects listed in custom permission mapping. - More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - type: string - configMapName: - description: Name of config map in the local namespace. - type: string - filename: - description: Filename within config map containing the resource - mapping. - type: string - required: - - clusterRoleName - - configMapName - - filename - type: object authorizationOptions: description: Additional configuration options for the authorization proxy. @@ -5214,6 +5189,17 @@ spec: type: boolean type: object type: object + databaseOptions: + description: Options to configure the Cryostat application's database. + properties: + secretName: + description: Name of the secret containing database keys. This + secret must contain a CONNECTION_KEY secret which is the database + connection password, and an ENCRYPTION_KEY secret which is the + key used to encrypt sensitive data stored within the database, + such as the target credentials keyring. + type: string + type: object enableCertManager: description: Use cert-manager to secure in-cluster communication between Cryostat components. Requires cert-manager to be installed. @@ -5236,33 +5222,6 @@ spec: - filename type: object type: array - jmxCacheOptions: - description: Options to customize the JMX target connections cache - for the Cryostat application. - properties: - targetCacheSize: - description: The maximum number of JMX connections to cache. Use - `-1` for an unlimited cache size (TTL expiration only). Defaults - to `-1`. - format: int32 - minimum: -1 - type: integer - targetCacheTTL: - description: The time to live (in seconds) for cached JMX connections. - Defaults to `10`. - format: int32 - minimum: 1 - type: integer - type: object - jmxCredentialsDatabaseOptions: - description: Options to configure the Cryostat application's credentials - database. - properties: - databaseSecretName: - description: Name of the secret containing the password to encrypt - credentials database. - type: string - type: object networkOptions: description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. @@ -7369,7 +7328,7 @@ spec: type: object coreResources: description: Resource requirements for the Cryostat application. - If specifying a memory limit, at least 768MiB is recommended. + If specifying a memory limit, at least 384MiB is recommended. properties: claims: description: "Claims lists the names of resources, defined @@ -7466,6 +7425,55 @@ spec: Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + databaseResources: + description: Resource requirements for the database container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object grafanaResources: description: Resource requirements for the Grafana container. properties: @@ -7515,6 +7523,55 @@ spec: Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + objectStorageResources: + description: Resource requirements for the object storage container. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object type: object schedulingOptions: description: Options to configure scheduling for the Cryostat deployment @@ -9611,7 +9668,7 @@ spec: type: object serviceOptions: description: Options to customize the services created for the Cryostat - application and Grafana dashboard. + application. properties: coreConfig: description: Specification for the service responsible for the @@ -9698,8 +9755,8 @@ spec: type: object type: object storageOptions: - description: Options to customize the storage for Flight Recordings - and Templates. + description: Options to customize the storage provisioned for the + database and object storage. properties: emptyDir: description: Configuration for an EmptyDir to be created by the @@ -9958,6 +10015,24 @@ spec: type: object type: object type: object + targetConnectionCacheOptions: + description: Options to customize the target connections cache for + the Cryostat application. + properties: + targetCacheSize: + description: The maximum number of target connections to cache. + Use `-1` for an unlimited cache size (TTL expiration only). + Defaults to `-1`. + format: int32 + minimum: -1 + type: integer + targetCacheTTL: + description: The time to live (in seconds) for cached target connections. + Defaults to `10`. + format: int32 + minimum: 1 + type: integer + type: object targetDiscoveryOptions: description: Options to configure the Cryostat application's target discovery mechanisms. @@ -10088,9 +10163,6 @@ spec: - type type: object type: array - grafanaSecret: - description: Name of the Secret containing the generated Grafana credentials. - type: string targetNamespaces: description: List of namespaces that Cryostat has been configured and authorized to access and profile. diff --git a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml index c85c5c395..62e4d6a3c 100644 --- a/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/cryostat-operator.clusterserviceversion.yaml @@ -76,28 +76,6 @@ spec: path: enableCertManager x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Override default authorization properties for Cryostat on OpenShift. - displayName: Authorization Properties - path: authProperties - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'Name of the ClusterRole to use when Cryostat requests a role-scoped - OAuth token. This ClusterRole should contain permissions for all Kubernetes - objects listed in custom permission mapping. More details: https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth' - displayName: ClusterRole Name - path: authProperties.clusterRoleName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ClusterRole - - description: Name of config map in the local namespace. - displayName: ConfigMap Name - path: authProperties.configMapName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Filename within config map containing the resource mapping. - displayName: Filename - path: authProperties.filename - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - description: Additional configuration options for the authorization proxy. displayName: Authorization Options path: authorizationOptions @@ -140,6 +118,17 @@ spec: path: authorizationOptions.openShiftSSO.disable x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Options to configure the Cryostat application's database. + displayName: Database Options + path: databaseOptions + - description: Name of the secret containing database keys. This secret must + contain a CONNECTION_KEY secret which is the database connection password, + and an ENCRYPTION_KEY secret which is the key used to encrypt sensitive + data stored within the database, such as the target credentials keyring. + displayName: Secret Name + path: databaseOptions.secretName + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Secret - description: List of Flight Recorder Event Templates to preconfigure in Cryostat. displayName: Event Templates path: eventTemplates @@ -148,31 +137,6 @@ spec: path: eventTemplates[0].configMapName x-descriptors: - urn:alm:descriptor:io.kubernetes:ConfigMap - - description: Options to customize the JMX target connections cache for the - Cryostat application. - displayName: JMX Connections Cache Options - path: jmxCacheOptions - - description: The maximum number of JMX connections to cache. Use `-1` for - an unlimited cache size (TTL expiration only). Defaults to `-1`. - displayName: Target Cache Size - path: jmxCacheOptions.targetCacheSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: The time to live (in seconds) for cached JMX connections. Defaults - to `10`. - displayName: Target Cache TTL - path: jmxCacheOptions.targetCacheTTL - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:number - - description: Options to configure the Cryostat application's credentials database. - displayName: Credentials Database Options - path: jmxCredentialsDatabaseOptions - - description: Name of the secret containing the password to encrypt credentials - database. - displayName: Database Secret Name - path: jmxCredentialsDatabaseOptions.databaseSecretName - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - description: Options to control how the operator exposes the application outside of the cluster, such as using an Ingress or Route. displayName: Network Options @@ -294,7 +258,7 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Cryostat application. If specifying - a memory limit, at least 768MiB is recommended. + a memory limit, at least 384MiB is recommended. displayName: Core Resources path: resources.coreResources x-descriptors: @@ -304,11 +268,21 @@ spec: path: resources.dataSourceResources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the database container. + displayName: Database Resources + path: resources.databaseResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Resource requirements for the Grafana container. displayName: Grafana Resources path: resources.grafanaResources x-descriptors: - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Resource requirements for the object storage container. + displayName: Object Storage Resources + path: resources.objectStorageResources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - description: Options to configure scheduling for the Cryostat deployment displayName: Scheduling Options path: schedulingOptions @@ -367,11 +341,11 @@ spec: - description: Security Context to apply to the storage container. displayName: Storage Security Context path: securityOptions.storageSecurityContext - - description: Options to customize the services created for the Cryostat application - and Grafana dashboard. + - description: Options to customize the services created for the Cryostat application. displayName: Service Options path: serviceOptions - - description: Options to customize the storage for Flight Recordings and Templates. + - description: Options to customize the storage provisioned for the database + and object storage. displayName: Storage Options path: storageOptions - description: Configuration for an EmptyDir to be created by the operator instead @@ -406,6 +380,22 @@ spec: has created the PVC, changes to this field have no effect. displayName: Spec path: storageOptions.pvc.spec + - description: Options to customize the target connections cache for the Cryostat + application. + displayName: Target Connection Cache Options + path: targetConnectionCacheOptions + - description: The maximum number of target connections to cache. Use `-1` for + an unlimited cache size (TTL expiration only). Defaults to `-1`. + displayName: Target Cache Size + path: targetConnectionCacheOptions.targetCacheSize + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number + - description: The time to live (in seconds) for cached target connections. + Defaults to `10`. + displayName: Target Cache TTL + path: targetConnectionCacheOptions.targetCacheTTL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:number - description: Options to configure the Cryostat application's target discovery mechanisms. displayName: Target Discovery Options @@ -454,11 +444,6 @@ spec: path: applicationUrl x-descriptors: - urn:alm:descriptor:org.w3:link - - description: Name of the Secret containing the generated Grafana credentials. - displayName: Grafana Secret - path: grafanaSecret - x-descriptors: - - urn:alm:descriptor:io.kubernetes:Secret - description: List of namespaces that Cryostat has been configured and authorized to access and profile. displayName: Target Namespaces diff --git a/docs/config.md b/docs/config.md index 1633b3f95..e57155516 100644 --- a/docs/config.md +++ b/docs/config.md @@ -62,7 +62,7 @@ spec: Multiple TLS secrets may be specified in the `trustedCertSecrets` array. The `secretName` property is mandatory, and must refer to the name of a Secret within the same namespace as the `Cryostat` object. The `certificateKey` must point to the X.509 certificate file to be trusted. If `certificateKey` is omitted, the default key name of `tls.crt` will be used. ### Storage Options -Cryostat uses storage volumes to hold Flight Recording files and user-configured Recording Templates. In the interest of persisting these files across redeployments, Cryostat uses a Persistent Volume Claim by default. Unless overidden, the operator will create a Persistent Volume Claim with the default Storage Class and 500MiB of storage capacity. +Cryostat uses storage volumes to persist data in its database and object storage. In the interest of persisting these files across redeployments, Cryostat uses a Persistent Volume Claim by default. Unless overidden, the operator will create a Persistent Volume Claim with the default Storage Class and 500MiB of storage capacity. Through the `spec.storageOptions` property, users can choose to provide either a custom Persistent Volume Claim `pvc.spec` or an `emptyDir` configuration. Either of these configurations will override any defaults when the operator creates the storage volume. If an `emptyDir` configuration is enabled, Cryostat will use an EmptyDir volume instead of a Persistent Volume Claim. Additional labels and annotations for the Persistent Volume Claim may also be specified. ```yaml @@ -286,9 +286,9 @@ spec: targetCacheTTL: 10 ``` -### JMX Credentials Database +### Application Database -The Cryostat application must be provided with a password to encrypt saved JMX credentials in database. The user can specify a secret containing the password entry with key `CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD`. The Cryostat application will use this password to encrypt saved JMX credentials in database. +Cryostat stores various pieces of information in a database. This can also include target application connection credentials, such as target applications' JMX credentials, which are stored in an encrypted database table. By default, the Operator will generate both a random database connection key and a random table encryption key and configure Cryostat and the database to use these. You may also specify these keys yourself by creating a Secret containing the keys `CONNECTION_KEY` and `ENCRYPTION_KEY`. For example: ```yaml @@ -298,10 +298,11 @@ metadata: name: credentials-database-secret type: Opaque stringData: - CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD: a-very-good-password + CONNECTION_KEY: a-very-good-password + ENCRYPTION_KEY: a-second-good-password ``` -Then, the property `.spec.jmxCredentialsDatabaseOptions.databaseSecretName` must be set to use this secret for password. +Then, the property `.spec.databaseOptions.secretName` must be set to use this Secret for the two keys. ```yaml apiVersion: operator.cryostat.io/v1beta1 @@ -313,48 +314,41 @@ spec: databaseSecretName: credentials-database-secret ``` -**Note**: If the secret is not provided, a default one is generated for this purpose. However, switching between using provided and generated secret is not allowed to avoid password mismatch that causes the Cryostat application's failure to access the credentials database. +**Note**: If the secret is not provided, one is generated for this purpose containing two randomly generated keys. However, switching between using provided and generated secret is not allowed to avoid password mismatch that causes the Cryostat application's failure to access the database or failure to decrypt the credentials keyring. -### Authorization Properties +### Authorization Options -When running on OpenShift, the user is required to have sufficient permissions for certain Kubernetes resources that are mapped into Cryostat-managed resources for authorization. - -The mappings can be specified using a ConfigMap that is compatible with [`OpenShiftAuthManager.properties`](https://github.com/cryostatio/cryostat/blob/6db048682b2b0048c1f6ea9215de626b5a5be284/src/main/resources/io/cryostat/net/openshift/OpenShiftAuthManager.properties). For example: -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: auth-properties -data: - auth.properties: | - TARGET=pods,deployments.apps - RECORDING=pods,pods/exec - CERTIFICATE=deployments.apps,pods,cryostats.operator.cryostat.io - CREDENTIALS=cryostats.operator.cryostat.io -``` - -If custom mapping is specified, a ClusterRole must be defined and should contain permissions for all Kubernetes objects listed in custom permission mapping. This ClusterRole will give additional rules on top of [default rules](https://github.com/cryostatio/cryostat-operator/blob/1b5d1ab97fca925e14b6c2baf2585f5e04426440/config/rbac/oauth_client.yaml). +On OpenShift, the authentication/authorization proxy deployed in front of the Cryostat application requires all users to pass a `create pods/exec` access review in the Cryostat installation namespace +by default. This means that access to the Cryostat application is granted to exactly the set of OpenShift cluster user accounts and service accounts which have this Role. This can be configured +using `spec.authorizationOptions.openShiftSSO.accessReview` as depicted below, but note that the `namespace` field should always be included and in most cases should match the Cryostat installation namespace. +The auth proxy may also be configured to allow Basic authentication by creating a Secret containing an `htpasswd` user file. An `htpasswd` file granting access to a user named `user` with the +password `pass` can be generated like this: `htpasswd -cbB htpasswd.conf user pass`. The password should use `bcrypt` hashing, specified by the `-B` flag. +Any user accounts defined in this file will also be granted access to the Cryostat application, and when this configuration is enabled you will see an additional Basic login option when visiting +the Cryostat application UI. If deployed on a non-OpenShift Kubernetes then this is the only supported authentication mechanism. -**Note**: Using [`Secret`](https://kubernetes.io/docs/concepts/configuration/secret/) in mapping can fail with access denied under [security protection](https://kubernetes.io/docs/concepts/configuration/secret/#information-security-for-secrets) against escalations. Find more details about this issue [here](https://docs.openshift.com/container-platform/4.11/authentication/tokens-scoping.html#scoping-tokens-role-scope_configuring-internal-oauth). +If not deployed on OpenShift, or if OpenShift SSO integration is disabled, then no authentication is performed by default - the Cryostat application UI is openly accessible. You should configure +`htpasswd` Basic authentication or install some other access control mechanism. -The property `spec.authProperties` can then be set to configure Cryostat to use this mapping instead of the default ones. ```yaml -apiVersion: operator.cryostat.io/v1beta1 +apiVersion: operator.cryostat.io/v1beta2 kind: Cryostat metadata: name: cryostat-sample spec: - authProperties: - configMapName: auth-properties - filename: auth.properties - clusterRoleName: oauth-cluster-role + authorizationOptions: + openShiftSSO: # only effective when running on OpenShift + disable: false # set this to `true` to disable OpenShift SSO integration + accessReview: # override this to change the required Role for users and service accounts to access the application + verb: create + resource: pods + subresource: exec + namespace: cryostat-install-namespace + basicAuth: + secretName: my-secret # a Secret with this name must exist in the Cryostat installation namespace + filename: htpasswd.conf # the name of the htpasswd user file within the Secret ``` -Each `configMapName` must refer to the name of a Config Map in the same namespace as Cryostat. The corresponding `filename` must be a key within that Config Map containing resource mappings. The `clusterRoleName` must be a valid name of an existing Cluster Role. - -**Note:** If the mapping is updated, Cryostat must be manually restarted. - ### Security Context @@ -486,6 +480,8 @@ spec: If you wish to use only Cryostat's [Discovery Plugin API](https://github.com/cryostatio/cryostat/blob/801779d5ddf7fa30f7b230f649220a852b06f27d/docs/DISCOVERY_PLUGINS.md), set the property `spec.targetDiscoveryOptions.builtInDiscoveryDisabled` to `true` to disable Cryostat's built-in discovery mechanisms. +You may also change the list of port names and port numbers that Cryostat uses to discover compatible target Endpoints. By default it looks for ports with the name `jfr-jmx` or with the number `9091`. + ```yaml apiVersion: operator.cryostat.io/v1beta1 kind: Cryostat @@ -493,5 +489,9 @@ metadata: name: cryostat-sample spec: targetDiscoveryOptions: - builtInDiscoveryDisabled: true + builtInDiscoveryDisabled: false + discoveryPortNames: + - my-jmx-port # look for ports named my-jmx-port or jdk-observe + - jdk-observe + disableBuiltInPortNumbers: true # ignore default port number 9091 ``` diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index cd3e8036e..a4980bda6 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -71,16 +71,20 @@ type TLSConfig struct { } const ( - defaultAuthProxyCpuRequest string = "50m" - defaultAuthProxyMemoryRequest string = "120Mi" + defaultAuthProxyCpuRequest string = "25m" + defaultAuthProxyMemoryRequest string = "64Mi" defaultCoreCpuRequest string = "500m" - defaultCoreMemoryRequest string = "256Mi" + defaultCoreMemoryRequest string = "384Mi" defaultJfrDatasourceCpuRequest string = "200m" - defaultJfrDatasourceMemoryRequest string = "384Mi" - defaultGrafanaCpuRequest string = "100m" - defaultGrafanaMemoryRequest string = "120Mi" - defaultReportCpuRequest string = "200m" - defaultReportMemoryRequest string = "384Mi" + defaultJfrDatasourceMemoryRequest string = "200Mi" + defaultGrafanaCpuRequest string = "25m" + defaultGrafanaMemoryRequest string = "80Mi" + defaultDatabaseCpuRequest string = "25m" + defaultDatabaseMemoryRequest string = "64Mi" + defaultStorageCpuRequest string = "50m" + defaultStorageMemoryRequest string = "256Mi" + defaultReportCpuRequest string = "500m" + defaultReportMemoryRequest string = "512Mi" OAuth2ConfigFileName string = "alpha_config.json" OAuth2ConfigFilePath string = "/etc/oauth2_proxy/alpha_config" ) @@ -894,10 +898,7 @@ func NewCoreContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequir func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag string, tls *TLSConfig, openshift bool) corev1.Container { configPath := "/opt/cryostat.d/conf.d" - archivePath := "/opt/cryostat.d/recordings.d" templatesPath := "/opt/cryostat.d/templates.d" - clientlibPath := "/opt/cryostat.d/clientlib.d" - probesPath := "/opt/cryostat.d/probes.d" envs := []corev1.EnvVar{ { @@ -968,26 +969,10 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Name: "CRYOSTAT_CONFIG_PATH", Value: configPath, }, - { - Name: "CRYOSTAT_ARCHIVE_PATH", - Value: archivePath, - }, { Name: "CRYOSTAT_TEMPLATE_PATH", Value: templatesPath, }, - { - Name: "CRYOSTAT_CLIENTLIB_PATH", - Value: clientlibPath, - }, - { - Name: "CRYOSTAT_PROBE_TEMPLATE_PATH", - Value: probesPath, - }, - { - Name: "CRYOSTAT_ENABLE_JDP_BROADCAST", - Value: "false", - }, } mounts := []corev1.VolumeMount{ @@ -996,26 +981,11 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag MountPath: configPath, SubPath: "config", }, - { - Name: cr.Name, - MountPath: archivePath, - SubPath: "flightrecordings", - }, { Name: cr.Name, MountPath: templatesPath, SubPath: "templates", }, - { - Name: cr.Name, - MountPath: clientlibPath, - SubPath: "clientlib", - }, - { - Name: cr.Name, - MountPath: probesPath, - SubPath: "probes", - }, { Name: cr.Name, MountPath: "truststore", @@ -1031,8 +1001,8 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag optional := false secretName := cr.Name + "-db" - if cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil { - secretName = *cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName + if cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil { + secretName = *cr.Spec.DatabaseOptions.SecretName } envs = append(envs, corev1.EnvVar{ Name: "QUARKUS_DATASOURCE_PASSWORD", @@ -1041,7 +1011,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag LocalObjectReference: corev1.LocalObjectReference{ Name: secretName, }, - Key: "CONNECTION_KEY", + Key: constants.DatabaseSecretConnectionKey, Optional: &optional, }, }, @@ -1071,19 +1041,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Value: "$(QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY)", }) - if specs.CoreURL != nil { - coreEnvs := []corev1.EnvVar{ - { - Name: "CRYOSTAT_EXT_WEB_PORT", - Value: getPort(specs.CoreURL), - }, - { - Name: "CRYOSTAT_WEB_HOST", - Value: specs.CoreURL.Hostname(), - }, - } - envs = append(envs, coreEnvs...) - } if specs.ReportsURL != nil { reportsEnvs := []corev1.EnvVar{ { @@ -1107,16 +1064,16 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag targetCacheSize := "-1" targetCacheTTL := "10" - if cr.Spec.JmxCacheOptions != nil { - if cr.Spec.JmxCacheOptions.TargetCacheSize != 0 { - targetCacheSize = strconv.Itoa(int(cr.Spec.JmxCacheOptions.TargetCacheSize)) + if cr.Spec.TargetConnectionCacheOptions != nil { + if cr.Spec.TargetConnectionCacheOptions.TargetCacheSize != 0 { + targetCacheSize = strconv.Itoa(int(cr.Spec.TargetConnectionCacheOptions.TargetCacheSize)) } - if cr.Spec.JmxCacheOptions.TargetCacheTTL != 0 { - targetCacheTTL = strconv.Itoa(int(cr.Spec.JmxCacheOptions.TargetCacheTTL)) + if cr.Spec.TargetConnectionCacheOptions.TargetCacheTTL != 0 { + targetCacheTTL = strconv.Itoa(int(cr.Spec.TargetConnectionCacheOptions.TargetCacheTTL)) } } - jmxCacheEnvs := []corev1.EnvVar{ + connectionCacheEnvs := []corev1.EnvVar{ { Name: "CRYOSTAT_CONNECTIONS_MAX_OPEN", Value: targetCacheSize, @@ -1126,7 +1083,7 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Value: targetCacheTTL, }, } - envs = append(envs, jmxCacheEnvs...) + envs = append(envs, connectionCacheEnvs...) envsFrom := []corev1.EnvFromSource{ { SecretRef: &corev1.SecretEnvSource{ @@ -1181,33 +1138,21 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag Value: datasourceURL, }, } - if specs.GrafanaURL != nil { + if specs.AuthProxyURL != nil { grafanaVars = append(grafanaVars, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: specs.GrafanaURL.String(), + Value: fmt.Sprintf("%s/grafana/", specs.AuthProxyURL.String()), }, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_URL", Value: getInternalDashboardURL(tls), - }) + }, + ) } envs = append(envs, grafanaVars...) - if tls == nil { - // If TLS isn't set up, tell Cryostat to not use it - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_DISABLE_SSL", - Value: "true", - }) - // Set CRYOSTAT_SSL_PROXIED if Ingress/Route use HTTPS - if specs.CoreURL != nil && specs.CoreURL.Scheme == "https" { - envs = append(envs, corev1.EnvVar{ - Name: "CRYOSTAT_SSL_PROXIED", - Value: "true", - }) - } - } else { + if tls != nil { // Configure keystore location and password in expected environment variables envs = append(envs, corev1.EnvVar{ Name: "KEYSTORE_PATH", @@ -1302,6 +1247,18 @@ func NewGrafanaContainerResource(cr *model.CryostatInstance) *corev1.ResourceReq func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSConfig) corev1.Container { envs := []corev1.EnvVar{ + { + Name: "GF_AUTH_ANONYMOUS_ENABLED", + Value: "true", + }, + { + Name: "GF_SERVER_DOMAIN", + Value: "localhost", + }, + { + Name: "GF_SERVER_SERVE_FROM_SUB_PATH", + Value: "true", + }, { Name: "JFR_DATASOURCE_URL", Value: datasourceURL, @@ -1317,6 +1274,10 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo Name: "GF_SERVER_PROTOCOL", Value: "https", }, + { + Name: "GF_SERVER_ROOT_URL", + Value: fmt.Sprintf("%s://localhost:%d/grafana/", "https", constants.AuthProxyHttpContainerPort), + }, { Name: "GF_SERVER_CERT_KEY", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s/%s", tls.GrafanaSecret, corev1.TLSPrivateKeyKey), @@ -1338,6 +1299,11 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo // Use HTTPS for liveness probe livenessProbeScheme = corev1.URISchemeHTTPS + } else { + envs = append(envs, corev1.EnvVar{ + Name: "GF_SERVER_ROOT_URL", + Value: fmt.Sprintf("%s://localhost:%d/grafana/", "http", constants.AuthProxyHttpContainerPort), + }) } var containerSc *corev1.SecurityContext @@ -1364,15 +1330,6 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo }, }, Env: envs, - EnvFrom: []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Name + "-grafana-basic", - }, - }, - }, - }, LivenessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ @@ -1387,19 +1344,21 @@ func NewGrafanaContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo } } -/* - * storage.image.repository - Repository for the database container - * storage.image.pullPolicy - Pull Policy for the database container - * storage.image.tag - Image tag for the database container - * storage.resources - Resource requests/limits for the database container - * storage.securityContext - Security Context for the database container - */ +func NewStorageContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{} + if cr.Spec.Resources != nil { + resources = cr.Spec.Resources.ObjectStorageResources.DeepCopy() + } + populateResourceRequest(resources, defaultStorageCpuRequest, defaultStorageMemoryRequest) + return resources +} + func NewStorageContainer(cr *model.CryostatInstance, imageTag string, tls *TLSConfig) corev1.Container { var containerSc *corev1.SecurityContext envs := []corev1.EnvVar{ { Name: "CRYOSTAT_BUCKETS", - Value: "archivedrecordings,archivedreports,eventtemplates", + Value: "archivedrecordings,archivedreports,eventtemplates,probes", }, { Name: "CRYOSTAT_ACCESS_KEY", @@ -1479,23 +1438,19 @@ func NewStorageContainer(cr *model.CryostatInstance, imageTag string, tls *TLSCo ProbeHandler: probeHandler, FailureThreshold: 13, }, + Resources: *NewStorageContainerResource(cr), } } -/* -* { - Name: cr.Name, - MountPath: "/var/lib/pgsql/data", - SubPath: "postgres", - }, -*/ -/* - * db.image.repository - Repository for the database container - * db.image.pullPolicy - Pull Policy for the database container - * db.image.tag - Image tag for the database container - * db.resources - Resource requests/limits for the database container - * db.securityContext - Security Context for the database container - */ +func NewDatabaseContainerResource(cr *model.CryostatInstance) *corev1.ResourceRequirements { + resources := &corev1.ResourceRequirements{} + if cr.Spec.Resources != nil { + resources = cr.Spec.Resources.DatabaseResources.DeepCopy() + } + populateResourceRequest(resources, defaultDatabaseCpuRequest, defaultDatabaseMemoryRequest) + return resources +} + func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSConfig) corev1.Container { var containerSc *corev1.SecurityContext if cr.Spec.SecurityOptions != nil && cr.Spec.SecurityOptions.DatabaseSecurityContext != nil { @@ -1530,7 +1485,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC LocalObjectReference: corev1.LocalObjectReference{ Name: secretName, }, - Key: "CONNECTION_KEY", + Key: constants.DatabaseSecretConnectionKey, Optional: &optional, }, }, @@ -1543,7 +1498,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC LocalObjectReference: corev1.LocalObjectReference{ Name: secretName, }, - Key: "ENCRYPTION_KEY", + Key: constants.DatabaseSecretEncryptionKey, Optional: &optional, }, }, @@ -1553,7 +1508,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC { Name: cr.Name, MountPath: "/data", - SubPath: "seaweed", + SubPath: "postgres", }, } @@ -1576,6 +1531,7 @@ func newDatabaseContainer(cr *model.CryostatInstance, imageTag string, tls *TLSC }, }, }, + Resources: *NewDatabaseContainerResource(cr), } } diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index d417b62ff..18f1a71f2 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -39,4 +39,9 @@ const ( // ALL capability to drop for restricted pod security. See: // https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted CapabilityAll corev1.Capability = "ALL" + + // DatabaseSecretConnectionKey indexes the database connection password within the Cryostat database Secret + DatabaseSecretConnectionKey = "CONNECTION_KEY" + // DatabaseSecretEncryptionKey indexes the database encryption key within the Cryostat database Secret + DatabaseSecretEncryptionKey = "ENCRYPTION_KEY" ) diff --git a/internal/controllers/ingresses.go b/internal/controllers/ingresses.go index 307307875..d73c2ebeb 100644 --- a/internal/controllers/ingresses.go +++ b/internal/controllers/ingresses.go @@ -48,6 +48,7 @@ func (r *Reconciler) reconcileCoreIngress(ctx context.Context, cr *model.Cryosta if err != nil { return err } + specs.AuthProxyURL = url specs.CoreURL = url return nil } diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 484615959..dea4149b8 100644 --- a/internal/controllers/reconciler_test.go +++ b/internal/controllers/reconciler_test.go @@ -66,7 +66,7 @@ type cryostatTestInput struct { func (c *controllerTest) commonBeforeEach() *cryostatTestInput { t := &cryostatTestInput{ TestReconcilerConfig: test.TestReconcilerConfig{ - GeneratedPasswords: []string{"auth_cookie_secret", "grafana", "credentials_database", "encryption_key", "object_storage", "jmx", "keystore"}, + GeneratedPasswords: []string{"auth_cookie_secret", "credentials_database", "encryption_key", "object_storage", "jmx", "keystore"}, }, TestResources: &test.TestResources{ Name: "cryostat", @@ -145,7 +145,6 @@ func resourceChecks() []resourceCheck { {func(t *cryostatTestInput) { t.expectPVC(t.NewDefaultPVC()) }, "persistent volume claim"}, - {(*cryostatTestInput).expectGrafanaSecret, "Grafana secret"}, {(*cryostatTestInput).expectCredentialsDatabaseSecret, "credentials database secret"}, {(*cryostatTestInput).expectStorageSecret, "object storage secret"}, {(*cryostatTestInput).expectJMXSecret, "JMX secret"}, @@ -166,9 +165,6 @@ func expectSuccessful(t **cryostatTestInput) { It("should set ApplicationURL in CR Status", func() { (*t).expectStatusApplicationURL() }) - It("should set GrafanaSecret in CR Status", func() { - (*t).expectStatusGrafanaSecretName((*t).NewGrafanaSecret().Name) - }) It("should set TLSSetupComplete condition", func() { (*t).checkConditionPresent(operatorv1beta2.ConditionTypeTLSSetupComplete, metav1.ConditionTrue, "AllCertificatesReady") @@ -477,30 +473,6 @@ func (c *controllerTest) commonTests() { }) }) }) - Context("with an existing Grafana Secret", func() { - var cr *model.CryostatInstance - var oldSecret *corev1.Secret - BeforeEach(func() { - cr = t.NewCryostat() - oldSecret = t.OtherGrafanaSecret() - t.objs = append(t.objs, cr.Object, oldSecret) - }) - JustBeforeEach(func() { - t.reconcileCryostatFully() - }) - It("should update the username but not password", func() { - secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: oldSecret.Name, Namespace: t.Namespace}, secret) - Expect(err).ToNot(HaveOccurred()) - - Expect(metav1.IsControlledBy(secret, cr.Object)).To(BeTrue()) - - // Username should be replaced, but not password - expected := t.NewGrafanaSecret() - Expect(secret.StringData["GF_SECURITY_ADMIN_USER"]).To(Equal(expected.StringData["GF_SECURITY_ADMIN_USER"])) - Expect(secret.StringData["GF_SECURITY_ADMIN_PASSWORD"]).To(Equal(oldSecret.StringData["GF_SECURITY_ADMIN_PASSWORD"])) - }) - }) Context("with an existing JMX Secret", func() { var cr *model.CryostatInstance var oldSecret *corev1.Secret @@ -2448,17 +2420,6 @@ func (t *cryostatTestInput) expectEmptyDir(expectedEmptyDir *corev1.EmptyDirVolu Expect(emptyDir.SizeLimit).To(Equal(expectedEmptyDir.SizeLimit)) } -func (t *cryostatTestInput) expectGrafanaSecret() { - secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-grafana-basic", Namespace: t.Namespace}, secret) - Expect(err).ToNot(HaveOccurred()) - - // Compare to desired spec - expectedSecret := t.NewGrafanaSecret() - t.checkMetadata(secret, expectedSecret) - Expect(secret.StringData).To(Equal(expectedSecret.StringData)) -} - func (t *cryostatTestInput) expectCredentialsDatabaseSecret() { secret := &corev1.Secret{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-db", Namespace: t.Namespace}, secret) @@ -2501,11 +2462,6 @@ func (t *cryostatTestInput) expectStatusApplicationURL() { Expect(instance.Status.ApplicationURL).To(Equal(fmt.Sprintf("https://%s.example.com", t.Name))) } -func (t *cryostatTestInput) expectStatusGrafanaSecretName(secretName string) { - instance := t.getCryostatInstance() - Expect(instance.Status.GrafanaSecret).To(Equal(secretName)) -} - func (t *cryostatTestInput) expectDeploymentHasCertSecrets() { deployment := &appsv1.Deployment{} err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name, Namespace: t.Namespace}, deployment) @@ -2710,10 +2666,9 @@ func (t *cryostatTestInput) checkMainPodTemplate(deployment *appsv1.Deployment, builtInPortConfigDisabled := cr.Spec.TargetDiscoveryOptions != nil && cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNames && cr.Spec.TargetDiscoveryOptions.DisableBuiltInPortNumbers - dbSecretProvided := cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil + dbSecretProvided := cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil t.checkCoreContainer(&coreContainer, ingress, reportsUrl, - cr.Spec.AuthProperties != nil, emptyDir, hasPortConfig, builtInDiscoveryDisabled, @@ -2859,7 +2814,7 @@ func (t *cryostatTestInput) checkDeploymentHasTemplates() { } func (t *cryostatTestInput) checkCoreContainer(container *corev1.Container, ingress bool, - reportsUrl string, authProps bool, + reportsUrl string, emptyDir bool, hasPortConfig bool, builtInDiscoveryDisabled bool, builtInPortConfigDisabled bool, dbSecretProvided bool, @@ -2872,7 +2827,7 @@ func (t *cryostatTestInput) checkCoreContainer(container *corev1.Container, ingr Expect(container.Image).To(Equal(*t.EnvCoreImageTag)) } Expect(container.Ports).To(ConsistOf(t.NewCorePorts())) - Expect(container.Env).To(ConsistOf(t.NewCoreEnvironmentVariables(reportsUrl, authProps, ingress, emptyDir, hasPortConfig, builtInDiscoveryDisabled, builtInPortConfigDisabled, dbSecretProvided))) + Expect(container.Env).To(ConsistOf(t.NewCoreEnvironmentVariables(reportsUrl, ingress, emptyDir, hasPortConfig, builtInDiscoveryDisabled, builtInPortConfigDisabled, dbSecretProvided))) Expect(container.EnvFrom).To(ConsistOf(t.NewCoreEnvFromSource())) Expect(container.VolumeMounts).To(ConsistOf(t.NewCoreVolumeMounts())) Expect(container.LivenessProbe).To(Equal(t.NewCoreLivenessProbe())) @@ -2891,7 +2846,6 @@ func (t *cryostatTestInput) checkGrafanaContainer(container *corev1.Container, r } Expect(container.Ports).To(ConsistOf(t.NewGrafanaPorts())) Expect(container.Env).To(ConsistOf(t.NewGrafanaEnvironmentVariables())) - Expect(container.EnvFrom).To(ConsistOf(t.NewGrafanaEnvFromSource())) Expect(container.VolumeMounts).To(ConsistOf(t.NewGrafanaVolumeMounts())) Expect(container.LivenessProbe).To(Equal(t.NewGrafanaLivenessProbe())) Expect(container.SecurityContext).To(Equal(securityContext)) diff --git a/internal/controllers/routes.go b/internal/controllers/routes.go index ef0b3920d..ac0d47a51 100644 --- a/internal/controllers/routes.go +++ b/internal/controllers/routes.go @@ -48,6 +48,7 @@ func (r *Reconciler) reconcileCoreRoute(ctx context.Context, svc *corev1.Service if err != nil { return err } + specs.AuthProxyURL = url specs.CoreURL = url return nil } diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index 6118ce55c..119a02d01 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -18,6 +18,7 @@ import ( "context" "fmt" + "github.com/cryostatio/cryostat-operator/internal/controllers/constants" "github.com/cryostatio/cryostat-operator/internal/controllers/model" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -29,9 +30,6 @@ func (r *Reconciler) reconcileSecrets(ctx context.Context, cr *model.CryostatIns if err := r.reconcileAuthProxyCookieSecret(ctx, cr); err != nil { return err } - if err := r.reconcileGrafanaSecret(ctx, cr); err != nil { - return err - } if err := r.reconcileDatabaseConnectionSecret(ctx, cr); err != nil { return err } @@ -62,35 +60,6 @@ func (r *Reconciler) reconcileAuthProxyCookieSecret(ctx context.Context, cr *mod }) } -func (r *Reconciler) reconcileGrafanaSecret(ctx context.Context, cr *model.CryostatInstance) error { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + "-grafana-basic", - Namespace: cr.InstallNamespace, - }, - } - - err := r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { - if secret.StringData == nil { - secret.StringData = map[string]string{} - } - secret.StringData["GF_SECURITY_ADMIN_USER"] = "admin" - - // Password is generated, so don't regenerate it when updating - if secret.CreationTimestamp.IsZero() { - secret.StringData["GF_SECURITY_ADMIN_PASSWORD"] = r.GenPasswd(20) - } - return nil - }) - if err != nil { - return err - } - - // Set the Grafana secret in the CR status - cr.Status.GrafanaSecret = secret.Name - return r.Client.Status().Update(ctx, cr.Object) -} - // jmxSecretNameSuffix is the suffix to be appended to the name of a // Cryostat CR to name its JMX credentials secret const jmxSecretNameSuffix = "-jmx-auth" @@ -127,12 +96,6 @@ func (r *Reconciler) reconcileJMXSecret(ctx context.Context, cr *model.CryostatI // Cryostat CR to name its credentials database secret const databaseSecretNameSuffix = "-db" -// databaseSecretConnectionPassKey indexes the database connection password within the Cryostat database Secret -const databaseSecretConnectionPassKey = "CONNECTION_KEY" - -// databaseSecretEncryptionKey indexes the database encryption key within the Cryostat database Secret -const databaseSecretEncryptionKey = "ENCRYPTION_KEY" - func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr *model.CryostatInstance) error { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -141,7 +104,7 @@ func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr * }, } - secretProvided := cr.Spec.JmxCredentialsDatabaseOptions != nil && cr.Spec.JmxCredentialsDatabaseOptions.DatabaseSecretName != nil + secretProvided := cr.Spec.DatabaseOptions != nil && cr.Spec.DatabaseOptions.SecretName != nil if secretProvided { return nil // Do not delete default secret to allow reverting to use default if needed } @@ -153,8 +116,8 @@ func (r *Reconciler) reconcileDatabaseConnectionSecret(ctx context.Context, cr * // Password is generated, so don't regenerate it when updating if secret.CreationTimestamp.IsZero() { - secret.StringData[databaseSecretConnectionPassKey] = r.GenPasswd(32) - secret.StringData[databaseSecretEncryptionKey] = r.GenPasswd(32) + secret.StringData[constants.DatabaseSecretConnectionKey] = r.GenPasswd(32) + secret.StringData[constants.DatabaseSecretEncryptionKey] = r.GenPasswd(32) } return nil }) diff --git a/internal/test/resources.go b/internal/test/resources.go index 619ca7621..f68af5544 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -541,7 +541,7 @@ func newPVCSpec(storageClass string, storageRequest string, func (r *TestResources) NewCryostatWithJmxCacheOptionsSpec() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.JmxCacheOptions = &operatorv1beta2.JmxCacheOptions{ + cr.Spec.TargetConnectionCacheOptions = &operatorv1beta2.TargetConnectionCacheOptions{ TargetCacheSize: 10, TargetCacheTTL: 20, } @@ -626,8 +626,8 @@ var providedDatabaseSecretName string = "credentials-database-secret" func (r *TestResources) NewCryostatWithDatabaseSecretProvided() *model.CryostatInstance { cr := r.NewCryostat() - cr.Spec.JmxCredentialsDatabaseOptions = &operatorv1beta2.JmxCredentialsDatabaseOptions{ - DatabaseSecretName: &providedDatabaseSecretName, + cr.Spec.DatabaseOptions = &operatorv1beta2.DatabaseOptions{ + SecretName: &providedDatabaseSecretName, } return cr } @@ -900,32 +900,6 @@ func (r *TestResources) NewCACertSecret(ns string) *corev1.Secret { } } -func (r *TestResources) NewGrafanaSecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-grafana-basic", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "GF_SECURITY_ADMIN_USER": "admin", - "GF_SECURITY_ADMIN_PASSWORD": "grafana", - }, - } -} - -func (r *TestResources) OtherGrafanaSecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-grafana-basic", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "GF_SECURITY_ADMIN_USER": "user", - "GF_SECURITY_ADMIN_PASSWORD": "goodpassword", - }, - } -} - func (r *TestResources) NewDatabaseSecret() *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -1289,7 +1263,7 @@ func (r *TestResources) NewStoragePorts() []corev1.ContainerPort { } } -func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps bool, ingress bool, +func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, ingress bool, emptyDir bool, hasPortConfig bool, builtInDiscoveryDisabled bool, builtInPortConfigDisabled bool, dbSecretProvided bool) []corev1.EnvVar { envs := []corev1.EnvVar{ { @@ -1360,26 +1334,10 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps Name: "CRYOSTAT_CONFIG_PATH", Value: "/opt/cryostat.d/conf.d", }, - { - Name: "CRYOSTAT_ARCHIVE_PATH", - Value: "/opt/cryostat.d/recordings.d", - }, { Name: "CRYOSTAT_TEMPLATE_PATH", Value: "/opt/cryostat.d/templates.d", }, - { - Name: "CRYOSTAT_CLIENTLIB_PATH", - Value: "/opt/cryostat.d/clientlib.d", - }, - { - Name: "CRYOSTAT_PROBE_TEMPLATE_PATH", - Value: "/opt/cryostat.d/probes.d", - }, - { - Name: "CRYOSTAT_ENABLE_JDP_BROADCAST", - Value: "false", - }, { Name: "CRYOSTAT_CONNECTIONS_MAX_OPEN", Value: "-1", @@ -1442,20 +1400,7 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps }, ) - if !r.TLS { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_DISABLE_SSL", - Value: "true", - }) - if r.ExternalTLS { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_SSL_PROXIED", - Value: "true", - }) - } - } else { + if r.TLS { envs = append(envs, corev1.EnvVar{ Name: "KEYSTORE_PATH", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-tls/keystore.p12", r.Name), @@ -1485,36 +1430,18 @@ func (r *TestResources) NewCoreEnvironmentVariables(reportsUrl string, authProps } func (r *TestResources) newNetworkEnvironmentVariables() []corev1.EnvVar { - envs := []corev1.EnvVar{ - { - Name: "CRYOSTAT_WEB_HOST", - Value: r.Name + ".example.com", - }, - } - if r.ExternalTLS { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_EXT_WEB_PORT", - Value: "443", - }) - } else { - envs = append(envs, - corev1.EnvVar{ - Name: "CRYOSTAT_EXT_WEB_PORT", - Value: "80", - }) - } + envs := []corev1.EnvVar{} if r.ExternalTLS { envs = append(envs, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: fmt.Sprintf("https://%s-grafana.example.com", r.Name), + Value: fmt.Sprintf("https://%s.example.com/grafana/", r.Name), }) } else { envs = append(envs, corev1.EnvVar{ Name: "GRAFANA_DASHBOARD_EXT_URL", - Value: fmt.Sprintf("http://%s-grafana.example.com", r.Name), + Value: fmt.Sprintf("http://%s.example.com/grafana/", r.Name), }) } if r.TLS { @@ -1539,6 +1466,21 @@ func (r *TestResources) NewGrafanaEnvironmentVariables() []corev1.EnvVar { Name: "JFR_DATASOURCE_URL", Value: "http://127.0.0.1:8989", }, + { + Name: "GF_AUTH_ANONYMOUS_ENABLED", + Value: "true", + ValueFrom: nil, + }, + { + Name: "GF_SERVER_DOMAIN", + Value: "localhost", + ValueFrom: nil, + }, + { + Name: "GF_SERVER_SERVE_FROM_SUB_PATH", + Value: "true", + ValueFrom: nil, + }, } if r.TLS { envs = append(envs, corev1.EnvVar{ @@ -1550,6 +1492,14 @@ func (r *TestResources) NewGrafanaEnvironmentVariables() []corev1.EnvVar { }, corev1.EnvVar{ Name: "GF_SERVER_CERT_FILE", Value: fmt.Sprintf("/var/run/secrets/operator.cryostat.io/%s-grafana-tls/tls.crt", r.Name), + }, corev1.EnvVar{ + Name: "GF_SERVER_ROOT_URL", + Value: "https://localhost:4180/grafana/", + }) + } else { + envs = append(envs, corev1.EnvVar{ + Name: "GF_SERVER_ROOT_URL", + Value: "http://localhost:4180/grafana/", }) } return envs @@ -1644,18 +1594,6 @@ func (r *TestResources) NewCoreEnvFromSource() []corev1.EnvFromSource { return envsFrom } -func (r *TestResources) NewGrafanaEnvFromSource() []corev1.EnvFromSource { - return []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: r.Name + "-grafana-basic", - }, - }, - }, - } -} - func (r *TestResources) NewJmxCacheOptionsEnv() []corev1.EnvVar { return []corev1.EnvVar{ { @@ -1722,30 +1660,12 @@ func (r *TestResources) NewCoreVolumeMounts() []corev1.VolumeMount { MountPath: "/opt/cryostat.d/conf.d", SubPath: "config", }, - { - Name: r.Name, - ReadOnly: false, - MountPath: "/opt/cryostat.d/recordings.d", - SubPath: "flightrecordings", - }, { Name: r.Name, ReadOnly: false, MountPath: "/opt/cryostat.d/templates.d", SubPath: "templates", }, - { - Name: r.Name, - ReadOnly: false, - MountPath: "/opt/cryostat.d/clientlib.d", - SubPath: "clientlib", - }, - { - Name: r.Name, - ReadOnly: false, - MountPath: "/opt/cryostat.d/probes.d", - SubPath: "probes", - }, { Name: r.Name, ReadOnly: false, @@ -2859,7 +2779,7 @@ func newCoreContainerDefaultResource() *corev1.ResourceRequirements { return &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("256Mi"), + corev1.ResourceMemory: resource.MustParse("384Mi"), }, } } @@ -2887,7 +2807,7 @@ func newDatasourceContainerDefaultResource() *corev1.ResourceRequirements { return &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("200m"), - corev1.ResourceMemory: resource.MustParse("384Mi"), + corev1.ResourceMemory: resource.MustParse("200Mi"), }, } } @@ -2914,8 +2834,8 @@ func (r *TestResources) NewDatasourceContainerResource(cr *model.CryostatInstanc func newGrafanaContainerDefaultResource() *corev1.ResourceRequirements { return &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("100m"), - corev1.ResourceMemory: resource.MustParse("120Mi"), + corev1.ResourceCPU: resource.MustParse("25m"), + corev1.ResourceMemory: resource.MustParse("80Mi"), }, } } @@ -2942,8 +2862,8 @@ func (r *TestResources) NewGrafanaContainerResource(cr *model.CryostatInstance) func newReportContainerDefaultResource() *corev1.ResourceRequirements { return &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("200m"), - corev1.ResourceMemory: resource.MustParse("384Mi"), + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("512Mi"), }, } }