diff --git a/docs/modules/opensearch/examples/getting_started/getting_started.sh b/docs/modules/opensearch/examples/getting_started/getting_started.sh index 3bccc1f..a6ada9f 100755 --- a/docs/modules/opensearch/examples/getting_started/getting_started.sh +++ b/docs/modules/opensearch/examples/getting_started/getting_started.sh @@ -76,9 +76,9 @@ kubectl rollout status --watch statefulset/simple-opensearch-nodes-default --tim sleep 10 echo "Starting port-forwarding of port 9200" -# tag::port-forwarding[] +# tag::opensearch-port-forwarding[] kubectl port-forward services/simple-opensearch 9200 > /dev/null 2>&1 & -# end::port-forwarding[] +# end::opensearch-port-forwarding[] PORT_FORWARD_PID=$! # shellcheck disable=2064 # we want the PID evaluated now, not at the time the trap is trap "kill $PORT_FORWARD_PID" EXIT @@ -107,3 +107,25 @@ curl \ # Output: # {"_index":"sample_index","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"name": "Stackable"}} # end::rest-api[] + +echo +echo "Using OpenSearch Dashboards" +# tag::opensearch-dashboards[] +kubectl create secret generic opensearch-credentials \ + --from-literal kibanaserver=E4kENuEmkqH3jyHC + +helm install opensearch-dashboards opensearch-dashboards \ + --repo https://opensearch-project.github.io/helm-charts \ + --version 3.1.0 \ + --values opensearch-dashboards-values.yaml \ + --wait +# end::opensearch-dashboards[] + +echo "Starting port-forwarding of port 5601" +# tag::opensearch-dashboards-port-forwarding[] +kubectl port-forward services/opensearch-dashboards 5601 > /dev/null 2>&1 & +# end::opensearch-dashboards-port-forwarding[] +PORT_FORWARD_PID=$! +# shellcheck disable=2064 # we want the PID evaluated now, not at the time the trap is +trap "kill $PORT_FORWARD_PID" EXIT +sleep 600 diff --git a/docs/modules/opensearch/examples/getting_started/getting_started.sh.j2 b/docs/modules/opensearch/examples/getting_started/getting_started.sh.j2 index 8be395c..ec622c9 100755 --- a/docs/modules/opensearch/examples/getting_started/getting_started.sh.j2 +++ b/docs/modules/opensearch/examples/getting_started/getting_started.sh.j2 @@ -76,9 +76,9 @@ kubectl rollout status --watch statefulset/simple-opensearch-nodes-default --tim sleep 10 echo "Starting port-forwarding of port 9200" -# tag::port-forwarding[] +# tag::opensearch-port-forwarding[] kubectl port-forward services/simple-opensearch 9200 > /dev/null 2>&1 & -# end::port-forwarding[] +# end::opensearch-port-forwarding[] PORT_FORWARD_PID=$! # shellcheck disable=2064 # we want the PID evaluated now, not at the time the trap is trap "kill $PORT_FORWARD_PID" EXIT @@ -107,3 +107,25 @@ curl \ # Output: # {"_index":"sample_index","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"name": "Stackable"}} # end::rest-api[] + +echo +echo "Using OpenSearch Dashboards" +# tag::opensearch-dashboards[] +kubectl create secret generic opensearch-credentials \ + --from-literal kibanaserver=E4kENuEmkqH3jyHC + +helm install opensearch-dashboards opensearch-dashboards \ + --repo https://opensearch-project.github.io/helm-charts \ + --version 3.1.0 \ + --values opensearch-dashboards-values.yaml \ + --wait +# end::opensearch-dashboards[] + +echo "Starting port-forwarding of port 5601" +# tag::opensearch-dashboards-port-forwarding[] +kubectl port-forward services/opensearch-dashboards 5601 > /dev/null 2>&1 & +# end::opensearch-dashboards-port-forwarding[] +PORT_FORWARD_PID=$! +# shellcheck disable=2064 # we want the PID evaluated now, not at the time the trap is +trap "kill $PORT_FORWARD_PID" EXIT +sleep 600 diff --git a/docs/modules/opensearch/examples/getting_started/opensearch-dashboards-values.yaml b/docs/modules/opensearch/examples/getting_started/opensearch-dashboards-values.yaml new file mode 100644 index 0000000..9e30d3e --- /dev/null +++ b/docs/modules/opensearch/examples/getting_started/opensearch-dashboards-values.yaml @@ -0,0 +1,53 @@ +--- +opensearchHosts: https://simple-opensearch-nodes-default.default.svc.cluster.local:9200 +image: + repository: oci.stackable.tech/sdp/opensearch-dashboards + tag: 3.1.0-stackable0.0.0-dev +serviceAccount: + create: false + name: simple-opensearch-serviceaccount +config: + opensearch_dashboards.yml: + server: + ssl: + enabled: true + certificate: /stackable/opensearch-dashboards/config/tls/tls.crt + key: /stackable/opensearch-dashboards/config/tls/tls.key + opensearch: + username: kibanaserver + ssl: + verificationMode: full + certificateAuthorities: + - /stackable/opensearch-dashboards/config/tls/ca.crt + opensearch_security: + cookie: + secure: true +extraEnvs: + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: kibanaserver +extraVolumes: + - name: tls + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + secrets.stackable.tech/class: tls + secrets.stackable.tech/scope: service=opensearch-dashboards + spec: + storageClassName: secrets.stackable.tech + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "1" +extraVolumeMounts: + - mountPath: /stackable/opensearch-dashboards/config/tls + name: tls + - mountPath: /stackable/opensearch-dashboards/config/opensearch_dashboards.yml + name: config + subPath: opensearch_dashboards.yml +podSecurityContext: + fsGroup: 1000 diff --git a/docs/modules/opensearch/examples/getting_started/opensearch-dashboards-values.yaml.j2 b/docs/modules/opensearch/examples/getting_started/opensearch-dashboards-values.yaml.j2 new file mode 100644 index 0000000..6ba71f5 --- /dev/null +++ b/docs/modules/opensearch/examples/getting_started/opensearch-dashboards-values.yaml.j2 @@ -0,0 +1,53 @@ +--- +opensearchHosts: https://simple-opensearch-nodes-default.default.svc.cluster.local:9200 +image: + repository: oci.stackable.tech/sdp/opensearch-dashboards + tag: 3.1.0-stackable{{ versions.opensearch }} +serviceAccount: + create: false + name: simple-opensearch-serviceaccount +config: + opensearch_dashboards.yml: + server: + ssl: + enabled: true + certificate: /stackable/opensearch-dashboards/config/tls/tls.crt + key: /stackable/opensearch-dashboards/config/tls/tls.key + opensearch: + username: kibanaserver + ssl: + verificationMode: full + certificateAuthorities: + - /stackable/opensearch-dashboards/config/tls/ca.crt + opensearch_security: + cookie: + secure: true +extraEnvs: + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: kibanaserver +extraVolumes: + - name: tls + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + secrets.stackable.tech/class: tls + secrets.stackable.tech/scope: service=opensearch-dashboards + spec: + storageClassName: secrets.stackable.tech + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "1" +extraVolumeMounts: + - mountPath: /stackable/opensearch-dashboards/config/tls + name: tls + - mountPath: /stackable/opensearch-dashboards/config/opensearch_dashboards.yml + name: config + subPath: opensearch_dashboards.yml +podSecurityContext: + fsGroup: 1000 diff --git a/docs/modules/opensearch/images/getting_started/opensearch-dashboards.png b/docs/modules/opensearch/images/getting_started/opensearch-dashboards.png new file mode 100644 index 0000000..7b277bf Binary files /dev/null and b/docs/modules/opensearch/images/getting_started/opensearch-dashboards.png differ diff --git a/docs/modules/opensearch/pages/getting_started/first_steps.adoc b/docs/modules/opensearch/pages/getting_started/first_steps.adoc index a6080e6..7e4ec55 100644 --- a/docs/modules/opensearch/pages/getting_started/first_steps.adoc +++ b/docs/modules/opensearch/pages/getting_started/first_steps.adoc @@ -23,8 +23,11 @@ Such a hash can be e.g. generated with `htpasswd`: [source,bash] ---- -$ htpasswd -nbBC 10 admin AJVFsGJBbpT6mChnq +$ htpasswd -nbBC 10 admin AJVFsGJBbpT6mChn admin:$2y$10$xRtHZFJ9QhG9GcYhRpAGpufCZYsk//nxsuel5URh0GWEBgmiI4Q/e + +$ htpasswd -nbBC 10 kibanaserver E4kENuEmkqH3jyHC +kibanaserver:$2y$10$vPgQ/6ilKDM5utawBqxoR.7euhVQ0qeGl8mPTeKhmFT475WUDrfQS ---- == Creation of OpenSearch nodes @@ -63,7 +66,7 @@ To forward the HTTP port (`9200`) to localhost, run: [source,bash] ---- -include::example$getting_started/getting_started.sh[tag=port-forwarding] +include::example$getting_started/getting_started.sh[tag=opensearch-port-forwarding] ---- == Using the REST API @@ -78,6 +81,32 @@ include::example$getting_started/getting_started.sh[tag=rest-api] Great! Now you can create your own indexes, populate them with data and search for it. +== Using OpenSearch Dashboards + +OpenSearch Dashboards is currently not managed by the operator, but the Stackable Data Platform provides a supported OCI image. +First, create the Helm values file `opensearch-dashboards-values.yaml`: + +[source,yaml] +---- +include::example$getting_started/opensearch-dashboards-values.yaml[] +---- + +Then, create the Secret with the credentials for the `kibanaserver` user and deploy the OpenSearch Dashboards Helm chart: + +[source,bash] +---- +include::example$getting_started/getting_started.sh[tag=opensearch-dashboards] +---- + +Forward the OpenSearch Dashboards port 5601 to localhost, open `https://localhost:5601` in your browser and log in with username `admin` and password `AJVFsGJBbpT6mChn`: + +[source,bash] +---- +include::example$getting_started/getting_started.sh[tag=opensearch-dashboards-port-forwarding] +---- + +image::getting_started/opensearch-dashboards.png[Browser showing OpenSearch Dashboards after logging in] + == What's next Check the xref:usage-guide/index.adoc[] to find out more about configuring your OpenSearch instance or have a look at the OpenSearch documentation to https://docs.opensearch.org/docs/latest/getting-started/[ingest, search or visualize your data with OpenSearch Dashboards{external-link-icon}^]. diff --git a/docs/modules/opensearch/pages/usage-guide/opensearch-dashboards.adoc b/docs/modules/opensearch/pages/usage-guide/opensearch-dashboards.adoc index 632fe64..7031f89 100644 --- a/docs/modules/opensearch/pages/usage-guide/opensearch-dashboards.adoc +++ b/docs/modules/opensearch/pages/usage-guide/opensearch-dashboards.adoc @@ -10,14 +10,83 @@ A basic `values.yaml` file to deploy OpenSearch Dashboards with this chart might [source,yaml] ---- -opensearchHosts: https://opensearch..svc.cluster.local:9200 # <1> -image: - repository: oci.stackable.tech/sdp/opensearch-dashboards # <2> +opensearchHosts: https://opensearch-nodes-default..svc.cluster.local:9200 # <1> +image: # <2> + repository: oci.stackable.tech/sdp/opensearch-dashboards tag: 3.1.0-stackable0.0.0-dev -serviceAccount: # <3> +serviceAccount: create: false - name: opensearch-serviceaccount + name: opensearch-serviceaccount # <3> +config: + opensearch_dashboards.yml: + server: + ssl: + enabled: true # <4> + certificate: /stackable/opensearch-dashboards/config/tls/tls.crt # <5> + key: /stackable/opensearch-dashboards/config/tls/tls.key # <6> + opensearch: + username: kibanaserver # <7> + ssl: + verificationMode: full # <8> + certificateAuthorities: + - /stackable/opensearch-dashboards/config/tls/ca.crt # <9> + opensearch_security: + cookie: + secure: true # <10> +extraEnvs: + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: kibanaserver # <11> +extraVolumes: + - name: tls # <12> + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + secrets.stackable.tech/class: tls + secrets.stackable.tech/scope: service=opensearch-dashboards + spec: + storageClassName: secrets.stackable.tech + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "1" +extraVolumeMounts: + - mountPath: /stackable/opensearch-dashboards/config/tls + name: tls + - mountPath: /stackable/opensearch-dashboards/config/opensearch_dashboards.yml + name: config # <13> + subPath: opensearch_dashboards.yml +podSecurityContext: + fsGroup: 1000 # <14> ---- -<1> Address of the OpenSearch Service deployed by the operator +<1> Address of the OpenSearch Service deployed by the operator; + This address must be adapted according to your deployment. <2> Use the OCI image provided by the Stackable Data Platform <3> If running on OpenShift, use the ServiceAccount of OpenSearch because its permissions are already configured to work on OpenShift. + This ServiceAccount name must probably adapted according to your deployment. +<4> Enable TLS, so that OpenSearch Dashboards is served over HTTPS. +<5> The TLS server certificate +<6> The key for the TLS server certificate +<7> OpenSearch Dashboards uses the user `kibanaserver` to communicate with OpenSearch. +<8> OpenSearch Dashboards verifies the certificate of OpenSearch. This is disabled by default. +<9> The CA certificate which is used to verify the OpenSearch certificate +<10> Ensure that cookies are not sent via an insecure connection. +<11> The password for the `kibanaserver` user +<12> This example uses the secret operator to provide a TLS certificate. +<13> The Helm chart only adds a volume mount at `/usr/share/opensearch-dashboards/config`, but in the image provided by Stackable, OpenSearch Dashboards is located in `/stackable/opensearch-dashboards`. +<14> Mount the volumes with the `stackable` group so that the files are accessible by OpenSearch Dashboards. + +After the values are adjusted according to your deployment, especially `opensearchHosts` and `serviceAccount.name`, you can deploy the Helm chart as follows: + +[shell,yaml] +---- +helm install opensearch-dashboards opensearch-dashboards \ + --repo https://opensearch-project.github.io/helm-charts \ + --version 3.1.0 \ + --values opensearch-dashboards-values.yaml \ + --wait +---- diff --git a/docs/modules/opensearch/pages/usage-guide/opensearch-dashboards.adoc.j2 b/docs/modules/opensearch/pages/usage-guide/opensearch-dashboards.adoc.j2 index 16f8b7d..5f333ae 100644 --- a/docs/modules/opensearch/pages/usage-guide/opensearch-dashboards.adoc.j2 +++ b/docs/modules/opensearch/pages/usage-guide/opensearch-dashboards.adoc.j2 @@ -10,14 +10,83 @@ A basic `values.yaml` file to deploy OpenSearch Dashboards with this chart might [source,yaml] ---- -opensearchHosts: https://opensearch..svc.cluster.local:9200 # <1> -image: - repository: oci.stackable.tech/sdp/opensearch-dashboards # <2> +opensearchHosts: https://opensearch-nodes-default..svc.cluster.local:9200 # <1> +image: # <2> + repository: oci.stackable.tech/sdp/opensearch-dashboards tag: 3.1.0-stackable{{ versions.opensearch }} -serviceAccount: # <3> +serviceAccount: create: false - name: opensearch-serviceaccount + name: opensearch-serviceaccount # <3> +config: + opensearch_dashboards.yml: + server: + ssl: + enabled: true # <4> + certificate: /stackable/opensearch-dashboards/config/tls/tls.crt # <5> + key: /stackable/opensearch-dashboards/config/tls/tls.key # <6> + opensearch: + username: kibanaserver # <7> + ssl: + verificationMode: full # <8> + certificateAuthorities: + - /stackable/opensearch-dashboards/config/tls/ca.crt # <9> + opensearch_security: + cookie: + secure: true # <10> +extraEnvs: + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: kibanaserver # <11> +extraVolumes: + - name: tls # <12> + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + secrets.stackable.tech/class: tls + secrets.stackable.tech/scope: service=opensearch-dashboards + spec: + storageClassName: secrets.stackable.tech + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "1" +extraVolumeMounts: + - mountPath: /stackable/opensearch-dashboards/config/tls + name: tls + - mountPath: /stackable/opensearch-dashboards/config/opensearch_dashboards.yml + name: config # <13> + subPath: opensearch_dashboards.yml +podSecurityContext: + fsGroup: 1000 # <14> ---- -<1> Address of the OpenSearch Service deployed by the operator +<1> Address of the OpenSearch Service deployed by the operator; + This address must be adapted according to your deployment. <2> Use the OCI image provided by the Stackable Data Platform <3> If running on OpenShift, use the ServiceAccount of OpenSearch because its permissions are already configured to work on OpenShift. + This ServiceAccount name must probably adapted according to your deployment. +<4> Enable TLS, so that OpenSearch Dashboards is served over HTTPS. +<5> The TLS server certificate +<6> The key for the TLS server certificate +<7> OpenSearch Dashboards uses the user `kibanaserver` to communicate with OpenSearch. +<8> OpenSearch Dashboards verifies the certificate of OpenSearch. This is disabled by default. +<9> The CA certificate which is used to verify the OpenSearch certificate +<10> Ensure that cookies are not sent via an insecure connection. +<11> The password for the `kibanaserver` user +<12> This example uses the secret operator to provide a TLS certificate. +<13> The Helm chart only adds a volume mount at `/usr/share/opensearch-dashboards/config`, but in the image provided by Stackable, OpenSearch Dashboards is located in `/stackable/opensearch-dashboards`. +<14> Mount the volumes with the `stackable` group so that the files are accessible by OpenSearch Dashboards. + +After the values are adjusted according to your deployment, especially `opensearchHosts` and `serviceAccount.name`, you can deploy the Helm chart as follows: + +[shell,yaml] +---- +helm install opensearch-dashboards opensearch-dashboards \ + --repo https://opensearch-project.github.io/helm-charts \ + --version 3.1.0 \ + --values opensearch-dashboards-values.yaml \ + --wait +---- diff --git a/tests/templates/kuttl/opensearch-dashboards/20_opensearch-dashboards-values.yaml.j2 b/tests/templates/kuttl/opensearch-dashboards/20_opensearch-dashboards-values.yaml.j2 index b1bc73b..3ef67a3 100644 --- a/tests/templates/kuttl/opensearch-dashboards/20_opensearch-dashboards-values.yaml.j2 +++ b/tests/templates/kuttl/opensearch-dashboards/20_opensearch-dashboards-values.yaml.j2 @@ -8,28 +8,28 @@ serviceAccount: # Use the ServiceAccount of OpenSearch because its permissions are already configured to work on # OpenShift. name: opensearch-serviceaccount -extraEnvs: - - name: OPENSEARCH_PASSWORD - valueFrom: - secretKeyRef: - name: opensearch-credentials - key: kibanaserver config: opensearch_dashboards.yml: + server: + ssl: + enabled: true + certificate: /stackable/opensearch-dashboards/config/tls/tls.crt + key: /stackable/opensearch-dashboards/config/tls/tls.key opensearch: username: kibanaserver - requestHeadersWhitelist: - - authorization - - securitytenant ssl: verificationMode: full - certificateAuthorities: [/stackable/opensearch-dashboards/config/tls/ca.crt] + certificateAuthorities: + - /stackable/opensearch-dashboards/config/tls/ca.crt opensearch_security: - multitenancy: - enabled: true - tenants.preferred: [Private, Global] - readonly_mode.roles: [kibana_read_only] - cookie.secure: false + cookie: + secure: true +extraEnvs: + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: kibanaserver extraVolumes: - name: tls ephemeral: @@ -37,6 +37,7 @@ extraVolumes: metadata: annotations: secrets.stackable.tech/class: tls + secrets.stackable.tech/scope: service=opensearch-dashboards spec: storageClassName: secrets.stackable.tech accessModes: @@ -45,9 +46,11 @@ extraVolumes: requests: storage: "1" extraVolumeMounts: - - name: tls - mountPath: /stackable/opensearch-dashboards/config/tls - # The Helm chart only adds a volume mount at /usr/share/opensearch-dashboards + - mountPath: /stackable/opensearch-dashboards/config/tls + name: tls + # The Helm chart sets the volume "config" and adds a volume mount at + # /usr/share/opensearch-dashboards/config. But in the Stackable image, the configuration directory + # is located in /stackable/opensearch-dashboards/config. - mountPath: /stackable/opensearch-dashboards/config/opensearch_dashboards.yml name: config subPath: opensearch_dashboards.yml diff --git a/tests/templates/kuttl/opensearch-dashboards/30-test-opensearch-dashboards.yaml.j2 b/tests/templates/kuttl/opensearch-dashboards/30-test-opensearch-dashboards.yaml similarity index 90% rename from tests/templates/kuttl/opensearch-dashboards/30-test-opensearch-dashboards.yaml.j2 rename to tests/templates/kuttl/opensearch-dashboards/30-test-opensearch-dashboards.yaml index 0ced664..60adaf2 100644 --- a/tests/templates/kuttl/opensearch-dashboards/30-test-opensearch-dashboards.yaml.j2 +++ b/tests/templates/kuttl/opensearch-dashboards/30-test-opensearch-dashboards.yaml @@ -1,3 +1,4 @@ +--- apiVersion: batch/v1 kind: Job metadata: @@ -24,9 +25,13 @@ spec: secretKeyRef: name: opensearch-credentials key: admin + - name: REQUESTS_CA_BUNDLE + value: /stackable/tls/ca.crt volumeMounts: - name: script mountPath: /stackable/scripts + - name: truststore + mountPath: /stackable/tls securityContext: allowPrivilegeEscalation: false capabilities: @@ -44,11 +49,22 @@ spec: - name: script configMap: name: test-opensearch-dashboards + - name: truststore + configMap: + name: truststore serviceAccountName: test-service-account securityContext: fsGroup: 1000 restartPolicy: OnFailure --- +apiVersion: secrets.stackable.tech/v1alpha1 +kind: TrustStore +metadata: + name: truststore +spec: + secretClassName: tls + format: tls-pem +--- apiVersion: v1 kind: ConfigMap metadata: @@ -67,7 +83,7 @@ data: namespace = os.environ["NAMESPACE"] opensearch_user = os.environ["OPENSEARCH_USER"] opensearch_password = os.environ["OPENSEARCH_PASSWORD"] - opensearch_dashboards_service = "http://opensearch-dashboards:5601" + opensearch_dashboards_service = f"https://opensearch-dashboards.{namespace}.svc.cluster.local:5601" session = requests.Session() session.headers.update({"osd-xsrf": "true"})