diff --git a/README.md b/README.md index e2f29b6d8..936e5fc5d 100644 --- a/README.md +++ b/README.md @@ -31,14 +31,11 @@ at the URL provided by: ``` kubectl get cryostat -o jsonpath='{$.items[0].status.applicationUrl}' ``` -The JMX authentication credentials for Cryostat itself can be obtained with: -```shell -CRYOSTAT_NAME=$(kubectl get cryostat -o jsonpath='{$.items[0].metadata.name}') -# Username -kubectl get secret ${CRYOSTAT_NAME}-jmx-auth -o jsonpath='{$.data.CRYOSTAT_RJMX_USER}' | base64 -d -# Password -kubectl get secret ${CRYOSTAT_NAME}-jmx-auth -o jsonpath='{$.data.CRYOSTAT_RJMX_PASS}' | base64 -d -``` + +To use Cryostat to monitor or profile Cryostat itself - since it is also an available JVM target - +you may use the Cryostat web UI to define a Custom Target with the connection URL `localhost:0`. +This is a special value which tells Cryostat's JVM that it should connect to itself directly, without +the need to expose a JMX port over the network. # Building ## Requirements diff --git a/api/v1beta1/cryostat_conversion.go b/api/v1beta1/cryostat_conversion.go index 0d8bc4424..4a6b898d2 100644 --- a/api/v1beta1/cryostat_conversion.go +++ b/api/v1beta1/cryostat_conversion.go @@ -120,7 +120,6 @@ func convertServiceOptionsTo(srcOpts *ServiceConfigList) *operatorv1beta2.Servic if srcOpts.CoreConfig != nil { dstOpts.CoreConfig = &operatorv1beta2.CoreServiceConfig{ HTTPPort: srcOpts.CoreConfig.HTTPPort, - JMXPort: srcOpts.CoreConfig.JMXPort, ServiceConfig: convertServiceConfigTo(srcOpts.CoreConfig.ServiceConfig), } } @@ -382,7 +381,6 @@ func convertServiceOptionsFrom(srcOpts *operatorv1beta2.ServiceConfigList) *Serv if srcOpts.CoreConfig != nil { dstOpts.CoreConfig = &CoreServiceConfig{ HTTPPort: srcOpts.CoreConfig.HTTPPort, - JMXPort: srcOpts.CoreConfig.JMXPort, ServiceConfig: convertServiceConfigFrom(srcOpts.CoreConfig.ServiceConfig), } } diff --git a/api/v1beta1/cryostat_conversion_test.go b/api/v1beta1/cryostat_conversion_test.go index ccc9ad597..a0058defd 100644 --- a/api/v1beta1/cryostat_conversion_test.go +++ b/api/v1beta1/cryostat_conversion_test.go @@ -84,6 +84,8 @@ func tableEntriesTo() []TableEntry { (*test.TestResources).NewCryostatWithIngress), Entry("minimal mode", (*test.TestResources).NewCryostatWithMinimalModeV1Beta1, (*test.TestResources).NewCryostat), + Entry("core JMX port", (*test.TestResources).NewCryostatWithCoreSvcJMXPortV1Beta1, + (*test.TestResources).NewCryostatWithCoreSvc), ) } diff --git a/api/v1beta2/cryostat_types.go b/api/v1beta2/cryostat_types.go index c93a30c24..89df67d0c 100644 --- a/api/v1beta2/cryostat_types.go +++ b/api/v1beta2/cryostat_types.go @@ -292,11 +292,7 @@ type CoreServiceConfig struct { // HTTP port number for the Cryostat application service. // Defaults to 8181. // +optional - HTTPPort *int32 `json:"httpPort,omitempty"` - // Remote JMX port number for the Cryostat application service. - // Defaults to 9091. - // +optional - JMXPort *int32 `json:"jmxPort,omitempty"` + HTTPPort *int32 `json:"httpPort,omitempty"` ServiceConfig `json:",inline"` } diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 973fbf820..57b4fc8a7 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -125,11 +125,6 @@ func (in *CoreServiceConfig) DeepCopyInto(out *CoreServiceConfig) { *out = new(int32) **out = **in } - if in.JMXPort != nil { - in, out := &in.JMXPort, &out.JMXPort - *out = new(int32) - **out = **in - } in.ServiceConfig.DeepCopyInto(&out.ServiceConfig) } diff --git a/bundle/manifests/operator.cryostat.io_cryostats.yaml b/bundle/manifests/operator.cryostat.io_cryostats.yaml index b095d06d1..e20a74c99 100644 --- a/bundle/manifests/operator.cryostat.io_cryostats.yaml +++ b/bundle/manifests/operator.cryostat.io_cryostats.yaml @@ -9385,11 +9385,6 @@ spec: service. Defaults to 8181. format: int32 type: integer - jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. - format: int32 - type: integer labels: additionalProperties: type: string diff --git a/config/crd/bases/operator.cryostat.io_cryostats.yaml b/config/crd/bases/operator.cryostat.io_cryostats.yaml index 3102d2e92..17a51300b 100644 --- a/config/crd/bases/operator.cryostat.io_cryostats.yaml +++ b/config/crd/bases/operator.cryostat.io_cryostats.yaml @@ -9375,11 +9375,6 @@ spec: service. Defaults to 8181. format: int32 type: integer - jmxPort: - description: Remote JMX port number for the Cryostat application - service. Defaults to 9091. - format: int32 - type: integer labels: additionalProperties: type: string diff --git a/config/samples/sample-app-agent.yaml b/config/samples/sample-app-agent.yaml index d3cf7ca7c..4ca177ae7 100644 --- a/config/samples/sample-app-agent.yaml +++ b/config/samples/sample-app-agent.yaml @@ -24,8 +24,10 @@ spec: fieldRef: apiVersion: v1 fieldPath: metadata.namespace + - name: CRYOSTAT_AGENT_API_WRITES_ENABLED + value: "true" - name: CRYOSTAT_AGENT_BASEURI - value: https://cryostat-sample.$(NAMESPACE).svc:8181 + value: https://cryostat-sample.$(NAMESPACE).svc:4180 - name: POD_IP valueFrom: fieldRef: @@ -64,7 +66,7 @@ spec: memory: 96Mi limits: cpu: 500m - memory: 128Mi + memory: 192Mi securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/docs/config.md b/docs/config.md index e57155516..1d694774e 100644 --- a/docs/config.md +++ b/docs/config.md @@ -99,7 +99,7 @@ spec: ``` ### Service Options -The Cryostat operator creates three services: one for the core Cryostat application, one for Grafana, and one for the cryostat-reports sidecars. These services are created by default as Cluster IP services. The core service exposes two ports: `8181` for HTTP and `9091` for JMX. The Grafana service exposes port `3000` for HTTP traffic. The Reports service exposts port `10000` for HTTP traffic. The service type, port numbers, labels and annotations can all be customized using the `spec.serviceOptions` property. +The Cryostat operator creates two services: one for the core Cryostat application and (optionally) one for the cryostat-reports sidecars. These services are created by default as Cluster IP services. The core service exposes one ports `4180` for HTTP(S). The Reports service exposts port `10000` for HTTP(S) traffic. The service type, port numbers, labels and annotations can all be customized using the `spec.serviceOptions` property. ```yaml apiVersion: operator.cryostat.io/v1beta1 kind: Cryostat @@ -114,7 +114,6 @@ spec: my-custom-annotation: some-value serviceType: NodePort httpPort: 8080 - jmxPort: 9095 grafanaConfig: labels: my-custom-label: some-value diff --git a/internal/controllers/common/resource_definitions/resource_definitions.go b/internal/controllers/common/resource_definitions/resource_definitions.go index e80cfb00e..43fdb346d 100644 --- a/internal/controllers/common/resource_definitions/resource_definitions.go +++ b/internal/controllers/common/resource_definitions/resource_definitions.go @@ -1081,15 +1081,6 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag }, } envs = append(envs, connectionCacheEnvs...) - envsFrom := []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: cr.Name + "-jmx-auth", - }, - }, - }, - } k8sDiscoveryEnabled := true k8sDiscoveryPortNames := "jfr-jmx" @@ -1190,12 +1181,8 @@ func NewCoreContainer(cr *model.CryostatInstance, specs *ServiceSpecs, imageTag { ContainerPort: constants.CryostatHTTPContainerPort, }, - { - ContainerPort: constants.CryostatJMXContainerPort, - }, }, Env: envs, - EnvFrom: envsFrom, Resources: *NewCoreContainerResource(cr), LivenessProbe: &corev1.Probe{ ProbeHandler: probeHandler, diff --git a/internal/controllers/constants/constants.go b/internal/controllers/constants/constants.go index f609d40b8..86351dfc1 100644 --- a/internal/controllers/constants/constants.go +++ b/internal/controllers/constants/constants.go @@ -22,7 +22,6 @@ import ( const ( AuthProxyHttpContainerPort int32 = 4180 CryostatHTTPContainerPort int32 = 8181 - CryostatJMXContainerPort int32 = 9091 GrafanaContainerPort int32 = 3000 DatasourceContainerPort int32 = 8989 ReportsContainerPort int32 = 10000 diff --git a/internal/controllers/reconciler_test.go b/internal/controllers/reconciler_test.go index 526f327ce..9b2415d08 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", "connection_key", "encryption_key", "object_storage", "jmx", "keystore"}, + GeneratedPasswords: []string{"auth_cookie_secret", "connection_key", "encryption_key", "object_storage", "keystore"}, }, TestResources: &test.TestResources{ Name: "cryostat", @@ -147,7 +147,6 @@ func resourceChecks() []resourceCheck { }, "persistent volume claim"}, {(*cryostatTestInput).expectDatabaseSecret, "database secret"}, {(*cryostatTestInput).expectStorageSecret, "object storage secret"}, - {(*cryostatTestInput).expectJMXSecret, "JMX secret"}, {(*cryostatTestInput).expectCoreService, "core service"}, {(*cryostatTestInput).expectMainDeployment, "main deployment"}, {(*cryostatTestInput).expectLockConfigMap, "lock config map"}, @@ -478,30 +477,6 @@ func (c *controllerTest) commonTests() { }) }) }) - Context("with an existing JMX Secret", func() { - var cr *model.CryostatInstance - var oldSecret *corev1.Secret - BeforeEach(func() { - cr = t.NewCryostat() - oldSecret = t.OtherJMXSecret() - 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.NewJMXSecret() - Expect(secret.StringData["CRYOSTAT_RJMX_USER"]).To(Equal(expected.StringData["CRYOSTAT_RJMX_USER"])) - Expect(secret.StringData["CRYOSTAT_RJMX_PASS"]).To(Equal(oldSecret.StringData["CRYOSTAT_RJMX_PASS"])) - }) - }) Context("with an existing Database Secret", func() { var cr *model.CryostatInstance var oldSecret *corev1.Secret @@ -2390,17 +2365,6 @@ func (t *cryostatTestInput) expectStorageSecret() { Expect(secret.StringData).To(Equal(expectedSecret.StringData)) } -func (t *cryostatTestInput) expectJMXSecret() { - secret := &corev1.Secret{} - err := t.Client.Get(context.Background(), types.NamespacedName{Name: t.Name + "-jmx-auth", Namespace: t.Namespace}, secret) - Expect(err).ToNot(HaveOccurred()) - - // Compare to desired spec - expectedSecret := t.NewJMXSecret() - t.checkMetadata(secret, expectedSecret) - Expect(secret.StringData).To(Equal(expectedSecret.StringData)) -} - func (t *cryostatTestInput) expectCoreService() { t.checkService(t.Name, t.NewCryostatService()) } diff --git a/internal/controllers/secrets.go b/internal/controllers/secrets.go index 9ded00104..b2519c0b0 100644 --- a/internal/controllers/secrets.go +++ b/internal/controllers/secrets.go @@ -33,10 +33,7 @@ func (r *Reconciler) reconcileSecrets(ctx context.Context, cr *model.CryostatIns if err := r.reconcileDatabaseConnectionSecret(ctx, cr); err != nil { return err } - if err := r.reconcileStorageSecret(ctx, cr); err != nil { - return err - } - return r.reconcileJMXSecret(ctx, cr) + return r.reconcileStorageSecret(ctx, cr) } func (r *Reconciler) reconcileAuthProxyCookieSecret(ctx context.Context, cr *model.CryostatInstance) error { @@ -60,38 +57,6 @@ func (r *Reconciler) reconcileAuthProxyCookieSecret(ctx context.Context, cr *mod }) } -// jmxSecretNameSuffix is the suffix to be appended to the name of a -// Cryostat CR to name its JMX credentials secret -const jmxSecretNameSuffix = "-jmx-auth" - -// jmxSecretUserKey indexes the username within the Cryostat JMX auth secret -const jmxSecretUserKey = "CRYOSTAT_RJMX_USER" - -// jmxSecretPassKey indexes the password within the Cryostat JMX auth secret -const jmxSecretPassKey = "CRYOSTAT_RJMX_PASS" - -func (r *Reconciler) reconcileJMXSecret(ctx context.Context, cr *model.CryostatInstance) error { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.Name + jmxSecretNameSuffix, - Namespace: cr.InstallNamespace, - }, - } - - return r.createOrUpdateSecret(ctx, secret, cr.Object, func() error { - if secret.StringData == nil { - secret.StringData = map[string]string{} - } - secret.StringData[jmxSecretUserKey] = "cryostat" - - // Password is generated, so don't regenerate it when updating - if secret.CreationTimestamp.IsZero() { - secret.StringData[jmxSecretPassKey] = r.GenPasswd(20) - } - return nil - }) -} - // databaseSecretNameSuffix is the suffix to be appended to the name of a // Cryostat CR to name its database secret const databaseSecretNameSuffix = "-db" diff --git a/internal/controllers/services.go b/internal/controllers/services.go index e8ce4c61e..db099e1fd 100644 --- a/internal/controllers/services.go +++ b/internal/controllers/services.go @@ -53,11 +53,6 @@ func (r *Reconciler) reconcileCoreService(ctx context.Context, cr *model.Cryosta Port: *config.HTTPPort, TargetPort: intstr.IntOrString{IntVal: constants.AuthProxyHttpContainerPort}, }, - { - Name: "jfr-jmx", - Port: *config.JMXPort, - TargetPort: intstr.IntOrString{IntVal: constants.CryostatJMXContainerPort}, - }, } return nil }) @@ -133,10 +128,6 @@ func configureCoreService(cr *model.CryostatInstance) *operatorv1beta2.CoreServi httpPort := constants.AuthProxyHttpContainerPort config.HTTPPort = &httpPort } - if config.JMXPort == nil { - jmxPort := constants.CryostatJMXContainerPort - config.JMXPort = &jmxPort - } return config } diff --git a/internal/test/conversion.go b/internal/test/conversion.go index 86f61472d..ee42357e7 100644 --- a/internal/test/conversion.go +++ b/internal/test/conversion.go @@ -168,12 +168,10 @@ func (r *TestResources) NewCryostatWithEmptyDirSpecV1Beta1() *operatorv1beta1.Cr func (r *TestResources) NewCryostatWithCoreSvcV1Beta1() *operatorv1beta1.Cryostat { svcType := corev1.ServiceTypeNodePort httpPort := int32(8080) - jmxPort := int32(9095) cr := r.NewCryostatV1Beta1() cr.Spec.ServiceOptions = &operatorv1beta1.ServiceConfigList{ CoreConfig: &operatorv1beta1.CoreServiceConfig{ HTTPPort: &httpPort, - JMXPort: &jmxPort, ServiceConfig: operatorv1beta1.ServiceConfig{ ServiceType: &svcType, Annotations: map[string]string{ @@ -189,6 +187,13 @@ func (r *TestResources) NewCryostatWithCoreSvcV1Beta1() *operatorv1beta1.Cryosta return cr } +func (r *TestResources) NewCryostatWithCoreSvcJMXPortV1Beta1() *operatorv1beta1.Cryostat { + jmxPort := int32(9095) + cr := r.NewCryostatWithCoreSvcV1Beta1() + cr.Spec.ServiceOptions.CoreConfig.JMXPort = &jmxPort + return cr +} + func (r *TestResources) NewCryostatWithGrafanaSvcV1Beta1() *operatorv1beta1.Cryostat { svcType := corev1.ServiceTypeNodePort httpPort := int32(8080) diff --git a/internal/test/resources.go b/internal/test/resources.go index 9c4b86c73..91722ddd5 100644 --- a/internal/test/resources.go +++ b/internal/test/resources.go @@ -230,12 +230,10 @@ func (r *TestResources) NewCryostatWithEmptyDirSpec() *model.CryostatInstance { func (r *TestResources) NewCryostatWithCoreSvc() *model.CryostatInstance { svcType := corev1.ServiceTypeNodePort httpPort := int32(8080) - jmxPort := int32(9095) cr := r.NewCryostat() cr.Spec.ServiceOptions = &operatorv1beta2.ServiceConfigList{ CoreConfig: &operatorv1beta2.CoreServiceConfig{ HTTPPort: &httpPort, - JMXPort: &jmxPort, ServiceConfig: operatorv1beta2.ServiceConfig{ ServiceType: &svcType, Annotations: map[string]string{ @@ -665,11 +663,6 @@ func (r *TestResources) NewCryostatService() *corev1.Service { Port: 4180, TargetPort: intstr.FromInt(4180), }, - { - Name: "jfr-jmx", - Port: 9091, - TargetPort: intstr.FromInt(9091), - }, }, }, } @@ -790,7 +783,6 @@ func (r *TestResources) NewCustomizedCoreService() *corev1.Service { svc := r.NewCryostatService() svc.Spec.Type = corev1.ServiceTypeNodePort svc.Spec.Ports[0].Port = 8080 - svc.Spec.Ports[1].Port = 9095 svc.Annotations = map[string]string{ "my/custom": "annotation", } @@ -899,19 +891,6 @@ func (r *TestResources) OtherDatabaseSecret() *corev1.Secret { } } -func (r *TestResources) NewJMXSecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-jmx-auth", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "CRYOSTAT_RJMX_USER": "cryostat", - "CRYOSTAT_RJMX_PASS": "jmx", - }, - } -} - func (r *TestResources) NewKeystoreSecret() *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -924,19 +903,6 @@ func (r *TestResources) NewKeystoreSecret() *corev1.Secret { } } -func (r *TestResources) OtherJMXSecret() *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: r.Name + "-jmx-auth", - Namespace: r.Namespace, - }, - StringData: map[string]string{ - "CRYOSTAT_RJMX_USER": "not-cryostat", - "CRYOSTAT_RJMX_PASS": "other-pass", - }, - } -} - func (r *TestResources) NewTestCertSecret(name string) *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -1153,9 +1119,6 @@ func (r *TestResources) NewCorePorts() []corev1.ContainerPort { { ContainerPort: 8181, }, - { - ContainerPort: 9091, - }, } } @@ -1603,15 +1566,7 @@ func (r *TestResources) NewAuthProxyEnvFromSource() []corev1.EnvFromSource { } func (r *TestResources) NewCoreEnvFromSource() []corev1.EnvFromSource { - envsFrom := []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: r.Name + "-jmx-auth", - }, - }, - }, - } + envsFrom := []corev1.EnvFromSource{} return envsFrom } diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index a06b6e7a1..16d74d763 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -23,7 +23,6 @@ import ( operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -186,24 +185,6 @@ func CryostatRecordingTest(bundle *apimanifests.Bundle, namespace string, openSh } r.Log += fmt.Sprintf("created a custom target: %+v\n", target) - jmxSecretName := CryostatRecordingTestName + "-jmx-auth" - secret, err := r.Client.CoreV1().Secrets(namespace).Get(context.Background(), jmxSecretName, metav1.GetOptions{}) - if err != nil { - return r.fail(fmt.Sprintf("failed to get jmx credentials: %s", err.Error())) - } - - credential := &Credential{ - UserName: string(secret.Data["CRYOSTAT_RJMX_USER"]), - Password: string(secret.Data["CRYOSTAT_RJMX_PASS"]), - MatchExpression: fmt.Sprintf("target.alias==\"%s\"", target.Alias), - } - - err = apiClient.CredentialClient.Create(context.Background(), credential) - if err != nil { - return r.fail(fmt.Sprintf("failed to create stored credential: %s", err.Error())) - } - r.Log += fmt.Sprintf("created stored credential with match expression: %s\n", credential.MatchExpression) - // Wait for Cryostat to update the discovery tree time.Sleep(2 * time.Second)